summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwlemb <wlemb>2000-08-25 07:37:06 +0000
committerwlemb <wlemb>2000-08-25 07:37:06 +0000
commit9bf5b5d572f3af295a7a720878a0103b192e4873 (patch)
tree08d9dc3ed0d28bdbddcf15f1e53dde32ec633f06
parent68495d6cf5352cc8b1e8af49b1c50af703c46c81 (diff)
downloadgroff-9bf5b5d572f3af295a7a720878a0103b192e4873.tar.gz
Initial revision
-rwxr-xr-xfont/devhtml2/DESC.proto12
-rwxr-xr-xfont/devhtml2/Makefile.sub33
-rwxr-xr-xfont/devhtml2/R.proto308
-rwxr-xr-xsrc/devices/grohtml2/Makefile.in9
-rwxr-xr-xsrc/devices/grohtml2/Makefile.sub9
-rwxr-xr-xsrc/devices/grohtml2/post-html.cc93
-rwxr-xr-xsrc/preproc/html2/Makefile.sub7
-rwxr-xr-xsrc/preproc/html2/image.cc452
-rwxr-xr-xsrc/preproc/html2/pre-html.cc774
-rwxr-xr-xsrc/preproc/html2/pre-html.h37
-rwxr-xr-xsrc/preproc/html2/pushbackbuffer.cc312
-rwxr-xr-xsrc/preproc/html2/pushbackbuffer.h53
12 files changed, 2099 insertions, 0 deletions
diff --git a/font/devhtml2/DESC.proto b/font/devhtml2/DESC.proto
new file mode 100755
index 00000000..ba27fba0
--- /dev/null
+++ b/font/devhtml2/DESC.proto
@@ -0,0 +1,12 @@
+res 240
+hor 24
+vert 40
+unitwidth 10
+sizes 10 0
+fonts 5 R I B BI S
+tcommand
+html
+postpro post-grohtml
+prepro pre-grohtml
+use_charnames_in_special
+pass_filenames
diff --git a/font/devhtml2/Makefile.sub b/font/devhtml2/Makefile.sub
new file mode 100755
index 00000000..f973e9d2
--- /dev/null
+++ b/font/devhtml2/Makefile.sub
@@ -0,0 +1,33 @@
+DEV=html2
+PROTOFONTS=R I B BI
+FONTS=$(PROTOFONTS) S
+DEVFILES=$(FONTS) DESC
+CLEANADD=$(FONTS) DESC
+
+RES=240
+CPI=10
+LPI=6
+
+$(FONTS): R.proto
+ @echo Making $@
+ @-rm -f $@
+ @(charwidth=`expr $(RES) / $(CPI)` ; \
+ sed -e "s/^name [A-Z]*$$/name $@/" \
+ -e "s/^\\([^ ]*\\) [0-9]+ /\\1 $$charwidth /" \
+ -e "s/^spacewidth [0-9]+$$/spacewidth $$charwidth/" \
+ -e "s/^internalname .*$$/internalname $@/" \
+ -e "/^internalname/s/BI/3/" \
+ -e "/^internalname/s/B/2/" \
+ -e "/^internalname/s/I/1/" \
+ -e "/^internalname .*[^ 0-9]/d" \
+ $(srcdir)/R.proto >$@)
+
+DESC: DESC.proto
+ @echo Making $@
+ @-rm -f $@
+ @sed -e "s/^res .*$$/res $(RES)/" \
+ -e "s/^hor .*$$/hor `expr $(RES) / $(CPI)`/" \
+ -e "s/^vert .*$$/vert `expr $(RES) / $(LPI)`/" \
+ -e "s/^fonts .*$$/fonts `set $(FONTS); echo $$#` $(FONTS)/" \
+ $(srcdir)/DESC.proto >$@
+
diff --git a/font/devhtml2/R.proto b/font/devhtml2/R.proto
new file mode 100755
index 00000000..cb0e0799
--- /dev/null
+++ b/font/devhtml2/R.proto
@@ -0,0 +1,308 @@
+name R
+internalname 0
+spacewidth 24
+charset
+! 24 0 0x0021
+" 24 0 0x0022 &quot;
+dq "
+# 24 0 0x0023
+sh "
+$ 24 0 0x0024
+Do "
+% 24 0 0x0025
+& 24 0 0x0026 &amp;
+aq 24 0 0x0027
+( 24 0 0x0028
+) 24 0 0x0029
+* 24 0 0x002A
++ 24 0 0x002B
+pl "
+, 24 0 0x002C
+\- 24 0 00002D
+hy "
+- "
+. 24 0 0x002E
+/ 24 0 0x002F
+sl "
+0 24 0 0x0030
+1 24 0 0x0031
+2 24 0 0x0032
+3 24 0 0x0033
+4 24 0 0x0034
+5 24 0 0x0035
+6 24 0 0x0036
+7 24 0 0x0037
+8 24 0 0x0038
+9 24 0 0x0039
+: 24 0 0x003A
+; 24 0 0x003B
+< 24 0 0x003C &lt;
+= 24 0 0x003D
+eq "
+> 24 0 0x003E &gt;
+? 24 0 0x003F
+@ 24 0 0x0040
+at "
+A 24 0 0x0041
+B 24 0 0x0042
+C 24 0 0x0043
+D 24 0 0x0044
+E 24 0 0x0045
+F 24 0 0x0046
+G 24 0 0x0047
+H 24 0 0x0048
+I 24 0 0x0049
+J 24 0 0x004A
+K 24 0 0x004B
+L 24 0 0x004C
+M 24 0 0x004D
+N 24 0 0x004E
+O 24 0 0x004F
+P 24 0 0x0050
+Q 24 0 0x0051
+R 24 0 0x0052
+S 24 0 0x0053
+T 24 0 0x0054
+U 24 0 0x0055
+V 24 0 0x0056
+W 24 0 0x0057
+X 24 0 0x0058
+Y 24 0 0x0059
+Z 24 0 0x005A
+[ 24 0 0x005B
+lB "
+\ 24 0 0x005C
+rs "
+] 24 0 0x005D
+rB "
+a^ 24 0 0x005E
+^ "
+ha "
+_ 24 0 0x005F
+ru "
+ul "
+\` 24 0 0x0060
+ga "
+a 24 0 0x0061
+b 24 0 0x0062
+c 24 0 0x0063
+d 24 0 0x0064
+e 24 0 0x0065
+f 24 0 0x0066
+g 24 0 0x0067
+h 24 0 0x0068
+i 24 0 0x0069
+j 24 0 0x006A
+k 24 0 0x006B
+l 24 0 0x006C
+m 24 0 0x006D
+n 24 0 0x006E
+o 24 0 0x006F
+p 24 0 0x0070
+q 24 0 0x0071
+r 24 0 0x0072
+s 24 0 0x0073
+t 24 0 0x0074
+u 24 0 0x0075
+v 24 0 0x0076
+w 24 0 0x0077
+x 24 0 0x0078
+y 24 0 0x0079
+z 24 0 0x007A
+lC 24 0 0x007B
+{ "
+ba 24 0 0x007C
+or "
+| "
+rC 24 0 0x007D
+} "
+a~ 24 0 0x007E
+~ "
+ti "
+r! 24 0 0x00A1 &iexcl;
+char161 "
+ct 24 0 0x00A2 &cent;
+char162 "
+Po 24 0 0x00A3 &pound;
+char163 "
+Cs 24 0 0x00A4 &curren;
+char164 "
+Ye 24 0 0x00A5 &yen;
+char165 "
+bb 24 0 0x00A6 &brvbar;
+char166 "
+sc 24 0 0x00A7 &sect;
+char167 "
+ad 24 0 0x00A8 &uml;
+char168 "
+co 24 0 0x00A9 &copy;
+char169 "
+Of 24 0 0x00AA &ordf;
+char170 "
+Fo 24 0 0x00AB &laquo;
+char171 "
+no 24 0 0x00AC &not;
+char172 "
+rg 24 0 0x00AE &reg;
+char174 "
+a- 24 0 0x00AF &macr;
+char175 "
+de 24 0 0x00B0 &deg;
+char176 "
++- 24 0 0x00B1 &plusmn;
+char177 "
+S2 24 0 0x00B2 &sup2;
+char178 "
+S3 24 0 0x00B3 &sup3;
+char179 "
+aa 24 0 0x00B4 &acute;
+char180 "
+char181 24 0 0x00B5 &micro;
+ps 24 0 0x00B6 &para;
+char182 "
+pc 24 0 0x00B7 &middot;
+char183 "
+ac 24 0 0x00B8 &cedil;
+char184 "
+S1 24 0 0x00B9 &sup1;
+char185 "
+Om 24 0 0x00BA &ordm;
+char186 "
+Fc 24 0 0x00BB &raquo;
+char187 "
+14 24 0 0x00BC &frac14;
+char188 "
+12 24 0 0x00BD &frac12;
+char189 "
+34 24 0 0x00BE &frac34;
+char190 "
+r? 24 0 0x00BF &iquest;
+char191 "
+`A 24 0 0x00C0 &Agrave;
+char192 "
+'A 24 0 0x00C1 &Aacute;
+char193 "
+^A 24 0 0x00C2 &Acirc;
+char194 "
+~A 24 0 0x00C3 &Atilde;
+char195 "
+:A 24 0 0x00C4 &Auml;
+char196 "
+oA 24 0 0x00C5 &Aring;
+char197 "
+AE 24 0 0x00C6 &AElig;
+char198 "
+,C 24 0 0x00C7 &Ccedil;
+char199 "
+`E 24 0 0x00C8 &Egrave;
+char200 "
+'E 24 0 0x00C9 &Eacute;
+char201 "
+^E 24 0 0x00CA &Ecirc;
+char202 "
+:E 24 0 0x00CB &Euml;
+char203 "
+`I 24 0 0x00CC &Igrave;
+char204 "
+'I 24 0 0x00CD &Iacute;
+char205 "
+^I 24 0 0x00CE &Icirc;
+char206 "
+:I 24 0 0x00CF &Iuml;
+char207 "
+-D 24 0 0x00D0 &ETH;
+char208 "
+~N 24 0 0x00D1 &Ntilde;
+char209 "
+`O 24 0 0x00D2 &Ograve;
+char210 "
+'O 24 0 0x00D3 &Oacute;
+char211 "
+^O 24 0 0x00D4 &Ocirc;
+char212 "
+~O 24 0 0x00D5 &Otilde;
+char213 "
+:O 24 0 0x00D6 &Ouml;
+char214 "
+mu 24 0 0x00D7 &times;
+char215 "
+/O 24 0 0x00D8 &Oslash;
+char216 "
+`U 24 0 0x00D9 &Ugrave;
+char217 "
+'U 24 0 0x00DA &Uacute;
+char218 "
+^U 24 0 0x00DB &Ucirc;
+char219 "
+:U 24 0 0x00DC &Uuml;
+char220 "
+'Y 24 0 0x00DD &Yacute;
+char221 "
+TP 24 0 0x00DE &THORN;
+char222 "
+ss 24 0 0x00DF &szlig;
+char223 "
+`a 24 0 0x00E0 &agrave;
+char224 "
+'a 24 0 0x00E1 &aacute;
+char225 "
+^a 24 0 0x00E2 &acirc;
+char226 "
+~a 24 0 0x00E3 &atilde;
+char227 "
+:a 24 0 0x00E4 &auml;
+char228 "
+oa 24 0 0x00E5 &aring;
+char229 "
+ae 24 0 0x00E6 &aelig;
+char230 "
+,c 24 0 0x00E7 &ccedil;
+char231 "
+`e 24 0 0x00E8 &egrave;
+char232 "
+'e 24 0 0x00E9 &eacute;
+char233 "
+^e 24 0 0x00EA &ecirc;
+char234 "
+:e 24 0 0x00EB &euml;
+char235 "
+`i 24 0 0x00EC &igrave;
+char236 "
+'i 24 0 0x00ED &iacute;
+char237 "
+^i 24 0 0x00EE &icirc;
+char238 "
+:i 24 0 0x00EF &iuml;
+char239 "
+Sd 24 0 0x00F0 &eth;
+char240 "
+~n 24 0 0x00F1 &ntilde;
+char241 "
+`o 24 0 0x00F2 &ograve;
+char242 "
+'o 24 0 0x00F3 &oacute;
+char243 "
+^o 24 0 0x00F4 &ocirc;
+char244 "
+~o 24 0 0x00F5 &otilde;
+char245 "
+:o 24 0 0x00F6 &ouml;
+char246 "
+di 24 0 0x00F7 &divide;
+char247 "
+/o 24 0 0x00F8 &oslash;
+char248 "
+`u 24 0 0x00F9 &ugrave;
+char249 "
+'u 24 0 0x00FA &uacute;
+char250 "
+^u 24 0 0x00FB &ucirc;
+char251 "
+:u 24 0 0x00FC &uuml;
+char252 "
+'y 24 0 0x00FD &yacute;
+char253 "
+Tp 24 0 0x00FE &thorn;
+char254 "
+:y 24 0 0x00FF &yuml;
+char255 "
diff --git a/src/devices/grohtml2/Makefile.in b/src/devices/grohtml2/Makefile.in
new file mode 100755
index 00000000..bca59ad7
--- /dev/null
+++ b/src/devices/grohtml2/Makefile.in
@@ -0,0 +1,9 @@
+PROG=post-grohtml
+MAN1=
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
+MLIB=$(LIBM)
+OBJS=\
+ post-html.o
+CCSRCS=\
+ $(srcdir)/post-html.cc
+
diff --git a/src/devices/grohtml2/Makefile.sub b/src/devices/grohtml2/Makefile.sub
new file mode 100755
index 00000000..f43a276d
--- /dev/null
+++ b/src/devices/grohtml2/Makefile.sub
@@ -0,0 +1,9 @@
+PROG=post-grohtml
+MAN1=
+# MAN1=grohtml.n
+XLIBS=$(LIBDRIVER) $(LIBGROFF)
+MLIB=$(LIBM)
+OBJS=\
+ post-html.o
+CCSRCS=\
+ $(srcdir)/post-html.cc
diff --git a/src/devices/grohtml2/post-html.cc b/src/devices/grohtml2/post-html.cc
new file mode 100755
index 00000000..1693f106
--- /dev/null
+++ b/src/devices/grohtml2/post-html.cc
@@ -0,0 +1,93 @@
+// -*- C++ -*-
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ *
+ * Gaius Mulley (gaius@glam.ac.uk) wrote post-html.cc
+ * but it owes a huge amount of ideas and raw code from
+ * James Clark (jjc@jclark.com) grops/ps.cc.
+ */
+
+/*
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "driver.h"
+#include "stringclass.h"
+#include "cset.h"
+
+#include <time.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+
+#if !defined(TRUE)
+# define TRUE (1==1)
+#endif
+#if !defined(FALSE)
+# define FALSE (1==0)
+#endif
+
+printer *make_printer()
+{
+ // return new html_printer;
+ return( 0 );
+}
+
+static void usage();
+
+int main(int argc, char **argv)
+{
+ program_name = argv[0];
+ static char stderr_buf[BUFSIZ];
+ setbuf(stderr, stderr_buf);
+ int c;
+ while ((c = getopt(argc, argv, "F:atTvdgmx?I:r:")) != EOF)
+ switch(c) {
+ case 'v':
+ {
+ extern const char *Version_string;
+ fprintf(stderr, "post-grohtml version %s\n", Version_string);
+ fflush(stderr);
+ break;
+ }
+ case 'F':
+ font::command_line_font_dir(optarg);
+ break;
+ case '?':
+ usage();
+ break;
+ default:
+ assert(0);
+ }
+ if (optind >= argc) {
+ do_file("-");
+ } else {
+ for (int i = optind; i < argc; i++)
+ do_file(argv[i]);
+ }
+ delete pr;
+ return 0;
+}
+
+static void usage()
+{
+ fprintf(stderr, "usage: %s [-avdgmt?] [-r resolution] [-F dir] [-I imagetype] [files ...]\n",
+ program_name);
+ exit(1);
+}
diff --git a/src/preproc/html2/Makefile.sub b/src/preproc/html2/Makefile.sub
new file mode 100755
index 00000000..9d5045a9
--- /dev/null
+++ b/src/preproc/html2/Makefile.sub
@@ -0,0 +1,7 @@
+PROG=pre-grohtml
+# MAN1=pre-grohtml.n
+MAN1=
+XLIBS=$(LIBGROFF)
+OBJS=pre-html.o pushbackbuffer.o
+CCSRCS=$(srcdir)/pre-html.cc $(srcdir)/pushbackbuffer.cc
+NAMEPREFIX=$(g)
diff --git a/src/preproc/html2/image.cc b/src/preproc/html2/image.cc
new file mode 100755
index 00000000..23708b64
--- /dev/null
+++ b/src/preproc/html2/image.cc
@@ -0,0 +1,452 @@
+// -*- C++ -*-
+/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Gaius Mulley (gaius@glam.ac.uk) but owes much
+ of the code from James Clark (jjc@jclark.com).
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "lib.h"
+#include "errarg.h"
+#include "error.h"
+#include "stringclass.h"
+#include "posix.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef _POSIX_VERSION
+#include <sys/wait.h>
+#define PID_T pid_t
+#else /* not _POSIX_VERSION */
+#define PID_T int
+#endif /* not _POSIX_VERSION */
+
+extern char *strerror();
+
+static char *file_contents;
+static int stdoutfd =1; // output file descriptor - normally 1 but might move
+ // -1 means closed
+
+#define DEBUGGING
+
+/*
+ * eventually it would be nice to have the choice of image devices.
+ * This could be implemented once we have a -Tpng or -Tpdf device driver.
+ * For now we use what is available.. postscript, ghostscript + png utils.
+ */
+
+#define IMAGEDEVICE "-Tps"
+
+
+static int do_file(const char *filename);
+
+/*
+ * sys_fatal - writes a fatal error message. Taken from src/roff/groff/pipeline.c
+ */
+
+static void sys_fatal(const char *s)
+{
+ fprintf(stderr, "%s: %s: %s", program_name, s, strerror(errno));
+}
+
+ sprintf(buffer,
+ "echo showpage | gs -q -dSAFER -sDEVICE=%s -r%d -g%dx%d -sOutputFile=- %s - 2> /dev/null > %s.png \n",
+ image_device,
+ image_res,
+ (end_region_hpos-start_region_hpos)*image_res/font::res+IMAGE_BOARDER_PIXELS,
+ (end_region_vpos-start_region_vpos)*image_res/font::res+IMAGE_BOARDER_PIXELS,
+ ps_src, image_name);
+
+
+/*
+ * the class and methods for retaining ascii text
+ */
+
+struct char_block {
+ enum { SIZE = 256 };
+ char buffer[SIZE];
+ int used;
+ char_block *next;
+
+ char_block();
+};
+
+char_block::char_block()
+: used(0), next(0)
+{
+}
+
+class char_buffer {
+public:
+ char_buffer();
+ ~char_buffer();
+ int read_file(FILE *fp);
+ int do_html(int argc, char *argv[]);
+ int do_image(int argc, char *argv[]);
+ int write_file(int is_html);
+private:
+ char_block *head;
+ char_block *tail;
+};
+
+char_buffer::char_buffer()
+: head(0), tail(0)
+{
+}
+
+char_buffer::~char_buffer()
+{
+ while (head != 0) {
+ char_block *temp = head;
+ head = head->next;
+ delete temp;
+ }
+}
+
+int char_buffer::read_file (FILE *fp)
+{
+ int i=0;
+ unsigned int old_used;
+ int n;
+
+ while (! feof(fp)) {
+ if (tail == 0) {
+ tail = new char_block;
+ head = tail;
+ } else {
+ if (tail->used == char_block::SIZE) {
+ tail->next = new char_block;
+ tail = tail->next;
+ }
+ }
+ // at this point we have a tail which is ready for the the next SIZE bytes of the file
+
+ n = fread(tail->buffer, sizeof(char), char_block::SIZE-tail->used, fp);
+ if (n <= 0) {
+ // error
+ return( 0 );
+ } else {
+ tail->used += n*sizeof(char);
+ }
+ }
+ return( 1 );
+}
+
+/*
+ * writeNbytes - writes n bytes to stdout.
+ */
+
+static void writeNbytes (char *s, int l)
+{
+ int n=0;
+ int r;
+
+ while (n<l) {
+ r = write(stdoutfd, s, l-n);
+ if (r<0) {
+ sys_fatal("write");
+ }
+ n += r;
+ s += r;
+ }
+}
+
+/*
+ * writeString - writes a string to stdout.
+ */
+
+static void writeString (char *s)
+{
+ writeNbytes(s, strlen(s));
+}
+
+/*
+ * write_file - writes the buffer to stdout (troff).
+ * It prepends the number register set to 1 if stdout is
+ * connected to troff -Thtml and 0 if connected to troff -Tps
+ */
+
+int char_buffer::write_file (int is_html)
+{
+ char_block *t=head;
+ int r;
+
+ fprintf(stderr, "output to pipeline\n");
+ if (is_html) {
+ writeString(".nr htmlflip 1\n");
+ } else {
+ writeString(".nr htmlflip 0\n");
+ fprintf(stderr, ".nr htmlflip 0\n");
+ }
+ if (t != 0) {
+ do {
+ writeNbytes(t->buffer, t->used);
+ fprintf(stderr, "hunk..\n");
+ t = t->next;
+ } while ((t != head) && (t != 0));
+ }
+ if (close(stdoutfd) < 0)
+ sys_fatal("close");
+
+ // now we grab fd=1 so that the next pipe cannot use fd=1
+ if (stdoutfd == 1) {
+ if (dup(2) != stdoutfd) {
+ sys_fatal("dup failed to use fd=1");
+ }
+ }
+
+ return( 1 );
+}
+
+/*
+ * replaceFd - replace a file descriptor, was, with, willbe.
+ */
+
+static void replaceFd (int was, int willbe)
+{
+ int dupres;
+
+ if (was != willbe) {
+ if (close(was)<0) {
+ sys_fatal("close");
+ }
+ dupres = dup(willbe);
+ if (dupres != was) {
+ sys_fatal("dup");
+ fprintf(stderr, "trying to replace fd=%d with %d dup used %d\n", was, willbe, dupres);
+ if (willbe == 1) {
+ fprintf(stderr, "likely that stdout should be opened before %d\n", was);
+ }
+ exit(1);
+ }
+ if (close(willbe) < 0) {
+ sys_fatal("close");
+ }
+ }
+}
+
+/*
+ * waitForChild - waits for child, pid, to exit.
+ */
+
+static void waitForChild (PID_T pid)
+{
+ PID_T waitpd;
+ int status;
+
+ waitpd = wait(&status);
+ if (waitpd != pid)
+ sys_fatal("wait");
+}
+
+/*
+ * do_html - sets the troff number htmlflip and
+ * writes out the buffer to troff -Thtml
+ */
+
+int char_buffer::do_html(int argc, char *argv[])
+{
+ int pdes[2];
+ PID_T pid;
+
+ if (pipe(pdes) < 0)
+ sys_fatal("pipe");
+
+ argv++; // skip pre-grohtml argv[0]
+ pid = fork();
+ if (pid < 0)
+ sys_fatal("fork");
+
+ if (pid == 0) {
+ // child
+ replaceFd(0, pdes[0]);
+ // close end we are not using
+ if (close(pdes[1])<0)
+ sys_fatal("close");
+
+ execvp(argv[0], argv);
+ error("couldn't exec %1: %2", argv[0], strerror(errno), (char *)0);
+ fflush(stderr); /* just in case error() doesn't */
+ exit(1);
+ } else {
+ // parent
+
+ replaceFd(1, pdes[1]);
+ // close end we are not using
+ if (close(pdes[0])<0)
+ sys_fatal("close");
+
+ write_file(1);
+ waitForChild(pid);
+ }
+ return( 0 );
+}
+
+/*
+ * alterToDeviceImage - manipulates the argv to include IMAGEDEVICE rather than -Thtml2
+ */
+
+static void alterToDeviceImage (int argc, char *argv[])
+{
+ int i=0;
+
+ while (i < argc) {
+ if (strcmp(argv[i], "-Thtml2") == 0) {
+ argv[i] = IMAGEDEVICE;
+ }
+ i++;
+ }
+ argv[1] = "groff"; /* rather than troff */
+}
+
+/*
+ * do_image - sets the troff number htmlflip and
+ * writes out the buffer to troff -Tps
+ */
+
+int char_buffer::do_image(int argc, char *argv[])
+{
+ PID_T pid;
+ int pdes[2];
+
+ if (pipe(pdes) < 0)
+ sys_fatal("pipe");
+
+ alterToDeviceImage(argc, argv);
+ argv++; // skip pre-grohtml argv[0]
+
+ pid = fork();
+ if (pid == 0) {
+ // child
+
+#if defined(DEBUGGING)
+ int psFd = creat("/tmp/prehtml-ps", S_IWUSR|S_IRUSR);
+ int regionFd = creat("/tmp/prehtml-region", S_IWUSR|S_IRUSR);
+#else
+ int psFd = mkstemp(xtmptemplate("-ps-"));
+ int regionFd = mkstemp(xtmptemplate("-regions-"));
+#endif
+
+ fprintf(stderr, "about to exec %s\n", argv[0]);
+ replaceFd(1, psFd);
+ replaceFd(0, pdes[0]);
+ replaceFd(2, regionFd);
+
+ // close end we are not using
+ if (close(pdes[1])<0)
+ sys_fatal("close");
+
+ execvp(argv[0], argv);
+ error("couldn't exec %1: %2", argv[0], strerror(errno), (char *)0);
+ fflush(stderr); /* just in case error() doesn't */
+ exit(1);
+ } else {
+ // parent
+
+ replaceFd(1, pdes[1]);
+ write_file(0);
+ waitForChild(pid);
+ }
+ return( 0 );
+}
+
+static char_buffer inputFile;
+
+
+/*
+ * usage - emit usage arguments and exit.
+ */
+
+void usage()
+{
+ fprintf(stderr, "usage: %s troffname [ troff flags ] [ files ]\n", program_name);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ program_name = argv[0];
+ int i; // skip over troff name
+ int found=0;
+ int ok=1;
+
+ for (i = 2; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (argv[i][1] == 'v') {
+ extern const char *Version_string;
+ fprintf(stderr, "GNU pre-grohtml version %s\n", Version_string);
+ fflush(stderr);
+ }
+ } else {
+ ok = do_file(argv[i]);
+ if (! ok) {
+ return( 0 );
+ }
+ found = 1;
+ }
+ }
+
+ if (! found) {
+ do_file("-");
+ }
+ ok = inputFile.do_html(argc, argv);
+ if (ok == 0) {
+ ok = inputFile.do_image(argc, argv);
+ if (ok == 0) {
+ // generateImages();
+ }
+ }
+ return ok;
+}
+
+static int do_file(const char *filename)
+{
+ FILE *fp;
+
+ current_filename = filename;
+ if (strcmp(filename, "-") == 0) {
+ fp = stdin;
+ } else {
+ fp = fopen(filename, "r");
+ if (fp == 0) {
+ error("can't open `%1': %2", filename, strerror(errno));
+ return 0;
+ }
+ }
+
+ if (inputFile.read_file(fp)) {
+ }
+
+ if (fp != stdin)
+ fclose(fp);
+ current_filename = 0;
+ return 1;
+}
diff --git a/src/preproc/html2/pre-html.cc b/src/preproc/html2/pre-html.cc
new file mode 100755
index 00000000..8824f3ac
--- /dev/null
+++ b/src/preproc/html2/pre-html.cc
@@ -0,0 +1,774 @@
+// -*- C++ -*-
+/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Gaius Mulley (gaius@glam.ac.uk).
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define PREHTMLC
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "lib.h"
+#include "errarg.h"
+#include "error.h"
+#include "stringclass.h"
+#include "posix.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef _POSIX_VERSION
+#include <sys/wait.h>
+#define PID_T pid_t
+#else /* not _POSIX_VERSION */
+#define PID_T int
+#endif /* not _POSIX_VERSION */
+
+extern char *strerror();
+
+#include "pre-html.h"
+#include "pushbackbuffer.h"
+
+#define POSTSCRIPTRES 72000 // maybe there is a better way to find this? --fixme--
+#define DEFAULT_IMAGE_RES 80
+#define IMAGE_BOARDER_PIXELS 10
+
+// #define TRANSPARENT "-background \"#FFF\" -transparent \"#FFF\""
+#define TRANSPARENT ""
+
+#define DEBUGGING
+
+#if !defined(TRUE)
+# define TRUE (1==1)
+#endif
+#if !defined(FALSE)
+# define FALSE (1==0)
+#endif
+
+void stop() {}
+
+
+static int stdoutfd =1; // output file descriptor - normally 1 but might move
+ // -1 means closed
+static char *psFileName =0; // name of postscript file
+static char *regionFileName=0; // name of file containing all image regions
+static char *image_device = "pnmraw";
+static int image_res = DEFAULT_IMAGE_RES;
+
+
+/*
+ * Images are generated via postscript, gs and the pnm utilities.
+ */
+
+#define IMAGEDEVICE "-Tps"
+
+
+static int do_file(const char *filename);
+
+/*
+ * sys_fatal - writes a fatal error message. Taken from src/roff/groff/pipeline.c
+ */
+
+void sys_fatal (const char *s)
+{
+ fprintf(stderr, "%s: %s: %s", program_name, s, strerror(errno));
+}
+
+/*
+ * the class and methods for retaining ascii text
+ */
+
+struct char_block {
+ enum { SIZE = 256 };
+ char buffer[SIZE];
+ int used;
+ char_block *next;
+
+ char_block();
+};
+
+char_block::char_block()
+: used(0), next(0)
+{
+}
+
+class char_buffer {
+public:
+ char_buffer();
+ ~char_buffer();
+ int read_file(FILE *fp);
+ int do_html(int argc, char *argv[]);
+ int do_image(int argc, char *argv[]);
+ void write_file_html(void);
+ void write_file_troff(void);
+ void write_upto_newline (char_block **t, int *i);
+ int can_see(char_block **t, int *i, char *string);
+private:
+ char_block *head;
+ char_block *tail;
+};
+
+char_buffer::char_buffer()
+: head(0), tail(0)
+{
+}
+
+char_buffer::~char_buffer()
+{
+ while (head != 0) {
+ char_block *temp = head;
+ head = head->next;
+ delete temp;
+ }
+}
+
+int char_buffer::read_file (FILE *fp)
+{
+ int i=0;
+ unsigned int old_used;
+ int n;
+
+ while (! feof(fp)) {
+ if (tail == 0) {
+ tail = new char_block;
+ head = tail;
+ } else {
+ if (tail->used == char_block::SIZE) {
+ tail->next = new char_block;
+ tail = tail->next;
+ }
+ }
+ // at this point we have a tail which is ready for the next SIZE bytes of the file
+
+ n = fread(tail->buffer, sizeof(char), char_block::SIZE-tail->used, fp);
+ if (n <= 0) {
+ // error
+ return( 0 );
+ } else {
+ tail->used += n*sizeof(char);
+ }
+ }
+ return( 1 );
+}
+
+/*
+ * writeNbytes - writes n bytes to stdout.
+ */
+
+static void writeNbytes (char *s, int l)
+{
+ int n=0;
+ int r;
+
+ while (n<l) {
+ r = write(stdoutfd, s, l-n);
+ if (r<0) {
+ sys_fatal("write");
+ }
+ n += r;
+ s += r;
+ }
+}
+
+/*
+ * writeString - writes a string to stdout.
+ */
+
+static void writeString (char *s)
+{
+ writeNbytes(s, strlen(s));
+}
+
+/*
+ * write_upto_newline - writes the contents of the buffer until a newline is seen.
+ */
+
+void char_buffer::write_upto_newline (char_block **t, int *i)
+{
+ int j=*i;
+
+ if (*t) {
+ while ((j < (*t)->used) && ((*t)->buffer[j] != '\n')) {
+ j++;
+ }
+ if ((j < (*t)->used) && ((*t)->buffer[j] == '\n')) {
+ j++;
+ }
+ writeNbytes((*t)->buffer+(*i), j-(*i));
+ if (j == (*t)->used) {
+ *i = 0;
+ *t = (*t)->next;
+ write_upto_newline(t, i);
+ } else {
+ // newline was seen
+ *i = j;
+ }
+ }
+}
+
+/*
+ * can_see - returns TRUE if we can see string in t->buffer[i] onwards
+ */
+
+int char_buffer::can_see(char_block **t, int *i, char *string)
+{
+ int j = 0;
+ int l = strlen(string);
+ int k = *i;
+ char_block *s = *t;
+
+ while (s) {
+ while ((k<s->used) && (j<l) && (s->buffer[k] == string[j])) {
+ j++;
+ k++;
+ }
+ if (j == l) {
+ *i = k;
+ *t = s;
+ return( TRUE );
+ } else if ((k<s->used) && (s->buffer[k] != string[j])) {
+ return( FALSE );
+ }
+ s = s->next;
+ k = 0;
+ }
+ return( FALSE );
+}
+
+/*
+ * write_file_troff - writes the buffer to stdout (troff).
+ * It prepends the number register set to 0.
+ */
+
+void char_buffer::write_file_troff (void)
+{
+ char_block *t=head;
+ int r;
+
+ writeString(".nr html2enable 1\n");
+ writeString(".nr htmlflip 0\n");
+ if (t != 0) {
+ do {
+ writeNbytes(t->buffer, t->used);
+ t = t->next;
+ } while ((t != head) && (t != 0));
+ }
+ if (close(stdoutfd) < 0)
+ sys_fatal("close");
+
+ // now we grab fd=1 so that the next pipe cannot use fd=1
+ if (stdoutfd == 1) {
+ if (dup(2) != stdoutfd) {
+ sys_fatal("dup failed to use fd=1");
+ }
+ }
+}
+
+/*
+ * the image class remembers the position of all images in the postscript file
+ * and assigns names for each image.
+ */
+
+struct imageItem {
+ imageItem *next;
+ int X1;
+ int Y1;
+ int X2;
+ int Y2;
+ char *imageName;
+ int resolution;
+ int pageNo;
+
+ imageItem (int x1, int y1, int x2, int y2, int page, int res, char *name);
+ ~imageItem ();
+};
+
+/*
+ * imageItem - constructor
+ */
+
+imageItem::imageItem (int x1, int y1, int x2, int y2, int page, int res, char *name)
+{
+ X1 = x1;
+ Y1 = y1;
+ X2 = x2;
+ Y2 = y2;
+ pageNo = page;
+ resolution = res;
+ imageName = name;
+ next = 0;
+}
+
+/*
+ * imageItem - deconstructor
+ */
+
+imageItem::~imageItem ()
+{
+}
+
+/*
+ * imageList - class containing a list of imageItems.
+ */
+
+class imageList {
+private:
+ imageItem *head;
+ imageItem *tail;
+ int count;
+public:
+ imageList();
+ ~imageList();
+ void add(int x1, int y1, int x2, int y2, int page, int res);
+ char *get(int i);
+};
+
+/*
+ * imageList - constructor.
+ */
+
+imageList::imageList ()
+ : head(0), tail(0), count(0)
+{
+}
+
+/*
+ * imageList - deconstructor.
+ */
+
+imageList::~imageList ()
+{
+ while (head != 0) {
+ imageItem *i = head;
+ head = head->next;
+ delete i;
+ }
+}
+
+/*
+ * createImage - generates a png file from the information held in, i, and
+ * the postscript file.
+ */
+
+static void createImage (imageItem *i)
+{
+ if (i->X1 != -1) {
+ char buffer[4096];
+
+ sprintf(buffer,
+ "echo showpage | gs -q -dFirstPage=%d -dLastPage=%d -dSAFER -sDEVICE=%s -r%d -sOutputFile=- %s - 2> /dev/null | pnmcut %d %d %d %d | pnmtopng %s > %s.png \n",
+ i->pageNo, i->pageNo,
+ image_device,
+ image_res,
+ psFileName,
+ i->X1*image_res/POSTSCRIPTRES,
+ i->Y1*image_res/POSTSCRIPTRES-IMAGE_BOARDER_PIXELS,
+ (i->X2-i->X1)*image_res/POSTSCRIPTRES+IMAGE_BOARDER_PIXELS,
+ (i->Y2-i->Y1)*image_res/POSTSCRIPTRES+IMAGE_BOARDER_PIXELS,
+ TRANSPARENT,
+ i->imageName);
+ fprintf(stderr, buffer);
+ system(buffer);
+ }
+}
+
+/*
+ * add - an image description to the imageList.
+ */
+
+void imageList::add (int x1, int y1, int x2, int y2, int page, int res)
+{
+ char *name = (char *)malloc(50);
+
+ if (name == 0)
+ sys_fatal("malloc");
+
+ if (x1 == -1) {
+ name[0] = (char)0;
+ } else {
+ count++;
+ sprintf(name, "grohtml-%d", count);
+ }
+ imageItem *i = new imageItem(x1, y1, x2, y2, page, res, name);
+
+ if (head == 0) {
+ head = i;
+ tail = i;
+ } else {
+ tail->next = i;
+ tail = i;
+ }
+ createImage(i);
+}
+
+/*
+ * get - returns the name for image number, i.
+ */
+
+char *imageList::get(int i)
+{
+ imageItem *t=head;
+
+ while (i>0) {
+ if (i == 1) {
+ if (t->X1 == -1) {
+ return( NULL );
+ } else {
+ return( t->imageName );
+ }
+ }
+ t = t->next;
+ i--;
+ }
+}
+
+static imageList listOfImages; // list of images defined by the region file.
+
+/*
+ * write_file_html - writes the buffer to stdout (troff).
+ * It prepends the number register set to 1 and writes
+ * out the file replacing template image names with
+ * actual image names.
+ */
+
+void char_buffer::write_file_html (void)
+{
+ char_block *t =head;
+ int imageNo=0;
+ char *name;
+ int i=0;
+
+ writeString(".nr html2enable 1\n");
+ writeString(".nr htmlflip 1\n");
+ if (t != 0) {
+ stop();
+ do {
+ if (can_see(&t, &i, ".if '\\*(.T'html2' .IMAGE <pre-html-image>\n")) {
+ imageNo++;
+ name = listOfImages.get(imageNo);
+ if (name != 0) {
+ writeString(".if '\\*(.T'html2' .IMAGE \"");
+ writeString(name);
+ writeString(".png\"\n");
+ }
+ } else {
+ write_upto_newline(&t, &i);
+ }
+ } while (t != 0);
+ }
+ if (close(stdoutfd) < 0)
+ sys_fatal("close");
+
+ // now we grab fd=1 so that the next pipe cannot use fd=1
+ if (stdoutfd == 1) {
+ if (dup(2) != stdoutfd) {
+ sys_fatal("dup failed to use fd=1");
+ }
+ }
+}
+
+/*
+ * generateImages - parses the region file and generates images
+ * from the postscript file. The region file
+ * contains the x1,y1 x2,y2 extents of each
+ * image.
+ */
+
+static void generateImages (char *regionFileName)
+{
+ pushBackBuffer *f=new pushBackBuffer(regionFileName);
+ char ch;
+
+ if (f->putPB('\n') == '\n') {
+ }
+ while (f->putPB(f->getPB()) != eof) {
+ if (f->isString("\ngrohtml-info:page")) {
+ int page= f->readInt();
+ int x1 = f->readInt();
+ int y1 = f->readInt();
+ int x2 = f->readInt();
+ int y2 = f->readInt();
+ int res = POSTSCRIPTRES; // --fixme-- prefer (f->readInt()) providing that troff can discover the value
+ listOfImages.add(x1, y1, x2, y2, page, res);
+ }
+ ch = f->getPB();
+ }
+}
+
+/*
+ * replaceFd - replace a file descriptor, was, with, willbe.
+ */
+
+static void replaceFd (int was, int willbe)
+{
+ int dupres;
+
+ if (was != willbe) {
+ if (close(was)<0) {
+ sys_fatal("close");
+ }
+ dupres = dup(willbe);
+ if (dupres != was) {
+ sys_fatal("dup");
+ fprintf(stderr, "trying to replace fd=%d with %d dup used %d\n", was, willbe, dupres);
+ if (willbe == 1) {
+ fprintf(stderr, "likely that stdout should be opened before %d\n", was);
+ }
+ exit(1);
+ }
+ if (close(willbe) < 0) {
+ sys_fatal("close");
+ }
+ }
+}
+
+/*
+ * waitForChild - waits for child, pid, to exit.
+ */
+
+static void waitForChild (PID_T pid)
+{
+ PID_T waitpd;
+ int status;
+
+ waitpd = wait(&status);
+ if (waitpd != pid)
+ sys_fatal("wait");
+}
+
+/*
+ * alterDeviceTo - if toImage is set then the arg list is altered to include
+ * IMAGEDEVICE and we invoke groff rather than troff.
+ * else
+ * set -Thtml2 and troff
+ */
+
+static void alterDeviceTo (int argc, char *argv[], int toImage)
+{
+ int i=0;
+
+ if (toImage) {
+ while (i < argc) {
+ if (strcmp(argv[i], "-Thtml2") == 0) {
+ argv[i] = IMAGEDEVICE;
+ }
+ i++;
+ }
+ argv[1] = "groff"; /* rather than troff */
+ } else {
+ while (i < argc) {
+ if (strcmp(argv[i], IMAGEDEVICE) == 0) {
+ argv[i] = "-Thtml2";
+ }
+ i++;
+ }
+ argv[1] = "troff"; /* use troff */
+ }
+}
+
+/*
+ * do_html - sets the troff number htmlflip and
+ * writes out the buffer to troff -Thtml
+ */
+
+int char_buffer::do_html(int argc, char *argv[])
+{
+ int pdes[2];
+ PID_T pid;
+
+ if (pipe(pdes) < 0)
+ sys_fatal("pipe");
+
+ alterDeviceTo(argc, argv, 0);
+ argv++; // skip pre-grohtml argv[0]
+ pid = fork();
+ if (pid < 0)
+ sys_fatal("fork");
+
+ if (pid == 0) {
+ // child
+ replaceFd(0, pdes[0]);
+ // close end we are not using
+ if (close(pdes[1])<0)
+ sys_fatal("close");
+
+ execvp(argv[0], argv);
+ error("couldn't exec %1: %2", argv[0], strerror(errno), (char *)0);
+ fflush(stderr); /* just in case error() doesn't */
+ exit(1);
+ } else {
+ // parent
+
+ replaceFd(1, pdes[1]);
+ // close end we are not using
+ if (close(pdes[0])<0)
+ sys_fatal("close");
+
+ write_file_html();
+ waitForChild(pid);
+ }
+ return( 0 );
+}
+
+/*
+ * do_image - sets the troff number htmlflip and
+ * writes out the buffer to troff -Tps
+ */
+
+int char_buffer::do_image(int argc, char *argv[])
+{
+ PID_T pid;
+ int pdes[2];
+
+ if (pipe(pdes) < 0)
+ sys_fatal("pipe");
+
+ alterDeviceTo(argc, argv, 1);
+ argv++; // skip pre-grohtml argv[0]
+
+ pid = fork();
+ if (pid == 0) {
+ // child
+
+#if defined(DEBUGGING)
+ int psFd = creat(psFileName, S_IWUSR|S_IRUSR);
+ int regionFd = creat(regionFileName, S_IWUSR|S_IRUSR);
+#else
+ int psFd = mkstemp(psFileName);
+ int regionFd = mkstemp(regionFileName);
+#endif
+
+ replaceFd(1, psFd);
+ replaceFd(0, pdes[0]);
+ replaceFd(2, regionFd);
+
+ // close end we are not using
+ if (close(pdes[1])<0)
+ sys_fatal("close");
+
+ execvp(argv[0], argv);
+ error("couldn't exec %1: %2", argv[0], strerror(errno), (char *)0);
+ fflush(stderr); /* just in case error() doesn't */
+ exit(1);
+ } else {
+ // parent
+
+ replaceFd(1, pdes[1]);
+ write_file_troff();
+ waitForChild(pid);
+ }
+ return( 0 );
+}
+
+static char_buffer inputFile;
+
+
+/*
+ * usage - emit usage arguments and exit.
+ */
+
+void usage()
+{
+ fprintf(stderr, "usage: %s troffname [ troff flags ] [ files ]\n", program_name);
+ exit(1);
+}
+
+/*
+ * makeTempFiles - name the temporary files
+ */
+
+static void makeTempFiles (void)
+{
+#if defined(DEBUGGING)
+ psFileName = "/tmp/prehtml-ps";
+ regionFileName = "/tmp/prehtml-region";
+#else
+ psFileName = xtmptemplate("-ps-");
+ regionFileName = xtmptemplate("-regions-");
+#endif
+}
+
+int main(int argc, char **argv)
+{
+ program_name = argv[0];
+ int i; // skip over troff name
+ int found=0;
+ int ok=1;
+
+ for (i = 2; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ if (argv[i][1] == 'v') {
+ extern const char *Version_string;
+ fprintf(stderr, "GNU pre-grohtml version %s\n", Version_string);
+ fflush(stderr);
+ }
+ } else {
+ ok = do_file(argv[i]);
+ if (! ok) {
+ return( 0 );
+ }
+ found = 1;
+ }
+ }
+
+ if (! found) {
+ do_file("-");
+ }
+ makeTempFiles();
+ ok = inputFile.do_image(argc, argv);
+ if (ok == 0) {
+ generateImages(regionFileName);
+ ok = inputFile.do_html(argc, argv);
+ }
+ return ok;
+}
+
+static int do_file(const char *filename)
+{
+ FILE *fp;
+
+ current_filename = filename;
+ if (strcmp(filename, "-") == 0) {
+ fp = stdin;
+ } else {
+ fp = fopen(filename, "r");
+ if (fp == 0) {
+ error("can't open `%1': %2", filename, strerror(errno));
+ return 0;
+ }
+ }
+
+ if (inputFile.read_file(fp)) {
+ }
+
+ if (fp != stdin)
+ fclose(fp);
+ current_filename = 0;
+ return 1;
+}
diff --git a/src/preproc/html2/pre-html.h b/src/preproc/html2/pre-html.h
new file mode 100755
index 00000000..739ab4cb
--- /dev/null
+++ b/src/preproc/html2/pre-html.h
@@ -0,0 +1,37 @@
+// -*- C++ -*-
+/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Gaius Mulley (gaius@glam.ac.uk).
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/*
+ * defines functions implemented within pre-html.c
+ */
+
+#if !defined(PREHTMLH)
+# define PREHTMLH
+# if defined(PREHTMLC)
+# define EXTERN
+# else
+# define EXTERN extern
+# endif
+
+
+extern void sys_fatal (const char *s);
+
+#undef EXTERN
+#endif
diff --git a/src/preproc/html2/pushbackbuffer.cc b/src/preproc/html2/pushbackbuffer.cc
new file mode 100755
index 00000000..d556c748
--- /dev/null
+++ b/src/preproc/html2/pushbackbuffer.cc
@@ -0,0 +1,312 @@
+// -*- C++ -*-
+/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Gaius Mulley (gaius@glam.ac.uk).
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "lib.h"
+#include "errarg.h"
+#include "error.h"
+#include "stringclass.h"
+#include "posix.h"
+
+#include <errno.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef errno
+extern int errno;
+#endif
+
+#include "pushbackbuffer.h"
+#include "pre-html.h"
+
+#if !defined(TRUE)
+# define TRUE (1==1)
+#endif
+
+#if !defined(FALSE)
+# define FALSE (1==0)
+#endif
+
+# define ERROR(X) (fprintf(stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) && \
+ (fflush(stderr)) && localexit(1))
+
+
+#define MAXPUSHBACKSTACK 4096 /* maximum number of character that can be pushed back */
+
+
+/*
+ * constructor for pushBackBuffer
+ */
+
+pushBackBuffer::pushBackBuffer (char *filename)
+{
+ charStack = (char *)malloc(MAXPUSHBACKSTACK);
+ if (charStack == 0) {
+ sys_fatal("malloc");
+ }
+ stackPtr = 0; /* index to push back stack */
+ debug = 0;
+ verbose = 0;
+ eofFound = FALSE;
+ lineNo = 1;
+ if (strcmp(filename, "") != 0) {
+ stdIn = dup(0);
+ close(0);
+ if (open(filename, O_RDONLY) != 0) {
+ sys_fatal("when tring to read graph file");
+ } else {
+ fileName = filename;
+ }
+ }
+}
+
+pushBackBuffer::~pushBackBuffer ()
+{
+ int old;
+
+ if (charStack != 0) {
+ free(charStack);
+ }
+ close(0);
+ /* restore stdin in file descriptor 0 */
+ old = dup(stdIn);
+ close(stdIn);
+}
+
+/*
+ * localexit - wraps exit with a return code to aid the ERROR macro.
+ */
+
+int localexit (int i)
+{
+ exit(i);
+ return( 1 );
+}
+
+/*
+ * getPB - returns a character, possibly a pushed back character.
+ */
+
+char pushBackBuffer::getPB (void)
+{
+ if (stackPtr>0) {
+ stackPtr--;
+ return( charStack[stackPtr] );
+ } else {
+ char ch;
+
+ if (read(0, &ch, 1) == 1) {
+ if (verbose) {
+ printf("%c", ch);
+ }
+ if (ch == '\n') {
+ lineNo++;
+ }
+ return( ch );
+ } else {
+ eofFound = TRUE;
+ return( eof );
+ }
+ }
+}
+
+/*
+ * putPB - pushes a character onto the push back stack.
+ * The same character is returned.
+ */
+
+char pushBackBuffer::putPB (char ch)
+{
+ if (stackPtr<MAXPUSHBACKSTACK) {
+ charStack[stackPtr] = ch ;
+ stackPtr++;
+ } else {
+ ERROR("max push back stack exceeded, increase MAXPUSHBACKSTACK constant");
+ }
+ return( ch );
+}
+
+/*
+ * isWhite - returns TRUE if a white character is found. This character is NOT consumed.
+ */
+
+static int isWhite (char ch)
+{
+ return( (ch==' ') || (ch == '\t') || (ch == '\n') );
+}
+
+/*
+ * skipToNewline - skips characters until a newline is seen.
+ */
+
+void pushBackBuffer::skipToNewline (void)
+{
+ char ch;
+
+ while ((putPB(getPB()) != '\n') && (! eofFound)) {
+ ch = getPB();
+ }
+}
+
+/*
+ * skipUntilToken - skips until a token is seen
+ */
+
+void pushBackBuffer::skipUntilToken (void)
+{
+ char ch;
+
+ while ((isWhite(putPB(getPB())) || (putPB(getPB()) == '#')) && (! eofFound)) {
+ ch = getPB();
+ if (ch == '#') {
+ skipToNewline();
+ }
+ }
+}
+
+/*
+ * isString - returns TRUE if the string, s, matches the pushed back string.
+ * if TRUE is returned then this string is consumed, otherwise it is
+ * left alone.
+ */
+
+int pushBackBuffer::isString (char *s)
+{
+ int length=strlen(s);
+ int i=0;
+ int j;
+
+ while ((i<length) && (putPB(getPB())==s[i])) {
+ if (getPB() != s[i]) {
+ ERROR("assert failed");
+ }
+ i++;
+ }
+ if (i==length) {
+ return( TRUE );
+ } else {
+ i--;
+ while (i>=0) {
+ if (putPB(s[i]) != s[i]) {
+ ERROR("assert failed");
+ }
+ i--;
+ }
+ }
+ return( FALSE );
+}
+
+/*
+ * isDigit - returns TRUE if the character, ch, is a digit.
+ */
+
+static int isDigit (char ch)
+{
+ return( ((ch>='0') && (ch<='9')) );
+}
+
+/*
+ * isHexDigit - returns TRUE if the character, ch, is a hex digit.
+ */
+
+static int isHexDigit (char ch)
+{
+ return( (isDigit(ch)) || ((ch>='a') && (ch<='f')) );
+}
+
+/*
+ * readInt - returns an integer from the input stream.
+ */
+
+int pushBackBuffer::readInt (void)
+{
+ int c =0;
+ int i =0;
+ int s =1;
+ char ch=getPB();
+
+ while (isWhite(ch)) {
+ ch=getPB();
+ }
+ // now read integer
+
+ if (ch == '-') {
+ s = -1;
+ ch = getPB();
+ }
+ while (isDigit(ch)) {
+ i *= 10;
+ if ((ch>='0') && (ch<='9')) {
+ i += (int)(ch-'0');
+ }
+ ch = getPB();
+ c++;
+ }
+ if (ch != putPB(ch)) {
+ ERROR("assert failed");
+ }
+ return( i*s );
+}
+
+/*
+ * convertToFloat - converts integers, a and b into a.b
+ */
+
+static float convertToFloat (int a, int b)
+{
+ int c=10;
+ float f;
+
+ while (b>c) {
+ c *= 10;
+ }
+ f = ((float)a) + (((float)b)/((float)c));
+ return( f );
+}
+
+/*
+ * readNumber - returns a float representing the word just read.
+ */
+
+float pushBackBuffer::readNumber (void)
+{
+ int integer;
+ int fraction;
+ char ch;
+ float f;
+
+ integer = readInt();
+ if (putPB(getPB()) == '.') {
+ ch = getPB();
+ fraction = readInt();
+ f = convertToFloat(integer, fraction);
+ return( f );
+ } else {
+ return( (float)integer );
+ }
+}
diff --git a/src/preproc/html2/pushbackbuffer.h b/src/preproc/html2/pushbackbuffer.h
new file mode 100755
index 00000000..569f4050
--- /dev/null
+++ b/src/preproc/html2/pushbackbuffer.h
@@ -0,0 +1,53 @@
+// -*- C -*-
+/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
+ Written by Gaius Mulley (gaius@glam.ac.uk).
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with groff; see the file COPYING. If not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+
+#define eof (char)-1
+
+
+/*
+ * defines the class and methods implemented within pbbuffer.cc
+ */
+
+class pushBackBuffer
+{
+ private:
+ char *charStack;
+ int stackPtr; /* index to push back stack */
+ int debug;
+ int verbose;
+ int eofFound;
+ char *fileName;
+ int lineNo;
+ int stdIn;
+
+ public:
+ pushBackBuffer (char *);
+ ~ pushBackBuffer ();
+ char getPB (void);
+ char putPB (char ch);
+ void skipUntilToken (void);
+ void skipToNewline (void);
+ float readNumber (void);
+ int readInt (void);
+ int isString (char *string);
+};
+
+