summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwlemb <wlemb>2002-07-19 09:32:01 +0000
committerwlemb <wlemb>2002-07-19 09:32:01 +0000
commit122d6946f786f3616a1453470a0c10c232b4c7db (patch)
treed1a3eb9ada0ed7cccb396b12c4b671a146f0e684
parent8ed23b5b55ece9bf5ff2ca33dc6e56af1450dd48 (diff)
downloadgroff-122d6946f786f3616a1453470a0c10c232b4c7db.tar.gz
* font/devhtml/R.proto: Updated to HTML 4, adding many glyphs.
* font/devutf8/R.proto: Adding some missing glyphs. * font/devutf8/NOTES: Updated. * tmac/dvi.tmac: Add more composite glyphs. * tmac/html.tmac: Updated. * man/groff_char.man: Add `sum' and `product' entities. * NEWS: Updated. Improved table, tab, and indenting support. * src/roff/troff/input.cc (file_iterator::suppress_newline_flag, string_iterator::suppress_newline_flag): Removed. Updated all function which have used it. * src/roff/troff/env.cc: Include `input.h'. (environment::add_node): Accept 0 as parameter. (environment::add_html_tag): Add `force' parameter. Updated all callers. (environment::add_html_tag_tabs): Ditto. For the moment, support left-aligned tabs only. (environment::make_html_tag): New function. (fill, no_fill): Set .br html tag additionally. (environment::newline): Emit `eol.ce' or `eol' tag for html. (environment::add_html_tag_eol): Removed. (tab_stops::distance_to_next_tab): Add variant for handling nextpos'. (environment::distance_to_next_tab): Ditto. Updated all callers. (environment::handle_tab): Handle tabs for html. * src/roff/troff/env.h: Updated. * src/roff/troff/div.cc: Updated all callers of `environment::add_html_tag'. * src/devices/grohtml/html-table.cc, src/devices/grohtml/html-table.h: New files. * src/devices/grohtml/html-text.cc (html_text): New members `blank_para' and `start_space'. (html_text::issue_tag): Don't emit TABLE_TAG. Handle indentation for PRE_TAG and P_TAG. (html_text::end_tag): Updated. (html_text::table_is_void, html_text::issue_table_begin, html_text::issue_table_end): Removed. (html_text::do_push): Simplified. [DEBUGGING]: Small fix. (html_text::push_para): Add new parameter for indentation; updated all callers. Handle PRE_TAG. (html_text::do_indent, html_text::do_table, html_text::done_table, html_text::is_in_table): Removed. (html_text::do_pre): Handle P_TAG also. (html_text::shutdown): Handle p->indent. (html_text::check_emit_text): Simplified. (html_text::do_emittext): Reset `blank_para'. (html_text::do_para): Add new parameter for indentation; updated all callers. (html_text::remove_indent): New function. (html_text::do_space): Handle verbatim text properly. (html_text::ever_emitted_text, html_text::starts_with_space, html_text::remove_para_align): New functions. (html_text::dump_stack_element, html_text::dump_stack): Updated. * src/devices/grohtml/html_text.h (HTML_TAG): Remove TABLE_TAG. Updated. * src/devices/grohtml/post-html.cc: Include html-table.h. (INDENTATION): Removed. (text_glob): Added many `is_<foo>' functions. Added table description `tab'. Added `get_arg',`get_tab_args', `remember_table', and `get_table' member functions. (list): Add `insert' and `move_to' member functions. (page): Add `insert_tag' member function. (page::dump_page) [DEBUG_TABLES]: Improved. (html_printer): Add `table' and `max_linelength' elements. Add many `do_<foo>', `insert_<foo>', `next_horiz_pos', `lookahead_for_tables', `shutdown_table', `calc_nf', `calc_po_in', `remove_tabs', `remove_courier_tabs'. (html_printer::emit_raw): Handle indentation. (html_printer::do_center, html_printer::write_header): Updated. (html_printer::is_courier_until_eol): Check for tag. (html_printer::do_linelength): Handle max_linelength. (html_printer::do_page_offset, html_printer::do_indentation): Handle fill_on. (html_printer::do_tempindent): Updated. (html_printer::do_indentedparagraph): Removed. (html_printer::do_indent): Simplified. (html_printer::do_eol): Use `ever_emitted_text'. (html_printer::do_flush, html_printer::do_links): Don't call done_table. (html_printer::do_break): Handle end_tempindent. (html_printer::troff_tag): Get argument. Don't handle `.ip'. Handle `.tab-ts', `.tab-te', `.col', `tab', and `tab0' tags. (html_printer::flush_page): Call `lookahead_for_tables'. Don't call `done_table'. (html_printer::add_to_sbuf): Always call do_indent. * src/devices/grohtml/Makefile.sub: Updated. * tmac/an-old.tmac (TP): Don't handle html device specially. (an-do-tag-html): New function which will be used instead of `an-do-tag' if html device is used. * tmac/html.tmac: Call .po to pass default page offset to grohtml. * tmac/s.tmac (@IP): Don't handle html device specially. (@IP-html): New function which will be used instead of `@IP' if html device is used. * tmac/www.tmac (HTML-NS, HTML-TAG-NS): New auxiliary macros -- this is a hack which will eventually vanish again. (PIMG): Handle `-C' option correctly if not html. (HR): Use HTML-NS.
-rw-r--r--ChangeLog124
-rw-r--r--NEWS2
-rw-r--r--font/devhtml/R.proto184
-rw-r--r--font/devutf8/NOTES19
-rw-r--r--font/devutf8/R.proto16
-rw-r--r--man/groff_char.man2
-rw-r--r--src/devices/grohtml/Makefile.sub3
-rw-r--r--src/devices/grohtml/html-text.cc364
-rw-r--r--src/devices/grohtml/html-text.h98
-rw-r--r--src/devices/grohtml/post-html.cc1056
-rw-r--r--src/preproc/grn/grn.man12
-rw-r--r--src/roff/troff/div.cc8
-rw-r--r--src/roff/troff/env.cc170
-rw-r--r--src/roff/troff/env.h11
-rw-r--r--src/roff/troff/input.cc45
-rw-r--r--tmac/an-old.tmac36
-rw-r--r--tmac/dvi.tmac5
-rw-r--r--tmac/html.tmac13
-rw-r--r--tmac/s.tmac43
-rw-r--r--tmac/www.tmac24
20 files changed, 1680 insertions, 555 deletions
diff --git a/ChangeLog b/ChangeLog
index d4413abd..361d7820 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,127 @@
+2002-07-19 Werner LEMBERG <wl@gnu.org>
+
+ * font/devhtml/R.proto: Updated to HTML 4, adding many glyphs.
+ * font/devutf8/R.proto: Adding some missing glyphs.
+ * font/devutf8/NOTES: Updated.
+
+ * tmac/dvi.tmac: Add more composite glyphs.
+ * tmac/html.tmac: Updated.
+
+ * man/groff_char.man: Add `sum' and `product' entities.
+
+ * NEWS: Updated.
+
+2002-07-18 Gaius Mulley <gaius@glam.ac.uk>
+
+ Improved table, tab, and indenting support.
+
+ * src/roff/troff/input.cc (file_iterator::suppress_newline_flag,
+ string_iterator::suppress_newline_flag): Removed. Updated all
+ function which have used it.
+
+ * src/roff/troff/env.cc: Include `input.h'.
+ (environment::add_node): Accept 0 as parameter.
+ (environment::add_html_tag): Add `force' parameter.
+ Updated all callers.
+ (environment::add_html_tag_tabs): Ditto.
+ For the moment, support left-aligned tabs only.
+ (environment::make_html_tag): New function.
+ (fill, no_fill): Set .br html tag additionally.
+ (environment::newline): Emit `eol.ce' or `eol' tag for html.
+ (environment::add_html_tag_eol): Removed.
+ (tab_stops::distance_to_next_tab): Add variant for handling
+ nextpos'.
+ (environment::distance_to_next_tab): Ditto.
+ Updated all callers.
+ (environment::handle_tab): Handle tabs for html.
+
+ * src/roff/troff/env.h: Updated.
+
+ * src/roff/troff/div.cc: Updated all callers of
+ `environment::add_html_tag'.
+
+ * src/devices/grohtml/html-table.cc,
+ src/devices/grohtml/html-table.h: New files.
+
+ * src/devices/grohtml/html-text.cc (html_text): New members
+ `blank_para' and `start_space'.
+ (html_text::issue_tag): Don't emit TABLE_TAG.
+ Handle indentation for PRE_TAG and P_TAG.
+ (html_text::end_tag): Updated.
+ (html_text::table_is_void, html_text::issue_table_begin,
+ html_text::issue_table_end): Removed.
+ (html_text::do_push): Simplified.
+ [DEBUGGING]: Small fix.
+ (html_text::push_para): Add new parameter for indentation; updated
+ all callers.
+ Handle PRE_TAG.
+ (html_text::do_indent, html_text::do_table, html_text::done_table,
+ html_text::is_in_table): Removed.
+ (html_text::do_pre): Handle P_TAG also.
+ (html_text::shutdown): Handle p->indent.
+ (html_text::check_emit_text): Simplified.
+ (html_text::do_emittext): Reset `blank_para'.
+ (html_text::do_para): Add new parameter for indentation; updated
+ all callers.
+ (html_text::remove_indent): New function.
+ (html_text::do_space): Handle verbatim text properly.
+ (html_text::ever_emitted_text, html_text::starts_with_space,
+ html_text::remove_para_align): New functions.
+ (html_text::dump_stack_element, html_text::dump_stack): Updated.
+
+ * src/devices/grohtml/html_text.h (HTML_TAG): Remove TABLE_TAG.
+ Updated.
+
+ * src/devices/grohtml/post-html.cc: Include html-table.h.
+ (INDENTATION): Removed.
+ (text_glob): Added many `is_<foo>' functions.
+ Added table description `tab'.
+ Added `get_arg',`get_tab_args', `remember_table', and `get_table'
+ member functions.
+ (list): Add `insert' and `move_to' member functions.
+ (page): Add `insert_tag' member function.
+ (page::dump_page) [DEBUG_TABLES]: Improved.
+ (html_printer): Add `table' and `max_linelength' elements.
+ Add many `do_<foo>', `insert_<foo>', `next_horiz_pos',
+ `lookahead_for_tables', `shutdown_table', `calc_nf', `calc_po_in',
+ `remove_tabs', `remove_courier_tabs'.
+ (html_printer::emit_raw): Handle indentation.
+ (html_printer::do_center, html_printer::write_header): Updated.
+ (html_printer::is_courier_until_eol): Check for tag.
+ (html_printer::do_linelength): Handle max_linelength.
+ (html_printer::do_page_offset, html_printer::do_indentation): Handle
+ fill_on.
+ (html_printer::do_tempindent): Updated.
+ (html_printer::do_indentedparagraph): Removed.
+ (html_printer::do_indent): Simplified.
+ (html_printer::do_eol): Use `ever_emitted_text'.
+ (html_printer::do_flush, html_printer::do_links): Don't call
+ done_table.
+ (html_printer::do_break): Handle end_tempindent.
+ (html_printer::troff_tag): Get argument.
+ Don't handle `.ip'.
+ Handle `.tab-ts', `.tab-te', `.col', `tab', and `tab0' tags.
+ (html_printer::flush_page): Call `lookahead_for_tables'.
+ Don't call `done_table'.
+ (html_printer::add_to_sbuf): Always call do_indent.
+
+ * src/devices/grohtml/Makefile.sub: Updated.
+
+ * tmac/an-old.tmac (TP): Don't handle html device specially.
+ (an-do-tag-html): New function which will be used instead of
+ `an-do-tag' if html device is used.
+
+ * tmac/html.tmac: Call .po to pass default page offset to grohtml.
+
+ * tmac/s.tmac (@IP): Don't handle html device specially.
+ (@IP-html): New function which will be used instead of `@IP' if
+ html device is used.
+
+ * tmac/www.tmac (HTML-NS, HTML-TAG-NS): New auxiliary macros -- this
+ is a hack which will eventually vanish again.
+ (PIMG): Handle `-C' option correctly if not html.
+ (HR): Use HTML-NS.
+
2002-07-17 Werner LEMBERG <wl@gnu.org>
* src/utils/afmtodit/afmtodit.pl: Don't use `-P-' for invoking perl.
diff --git a/NEWS b/NEWS
index 62db4a4c..14b6df4e 100644
--- a/NEWS
+++ b/NEWS
@@ -397,6 +397,8 @@ o New options `-a' and `-g' to control the number of bits for anti-aliasing
used for text and graphics, respectively. Default value is 4; 0 means
no anti-aliasing.
+o groff character/glyph entities now map onto HTML 4 character entities.
+
Grolbp
------
diff --git a/font/devhtml/R.proto b/font/devhtml/R.proto
index 15a3726b..3af836de 100644
--- a/font/devhtml/R.proto
+++ b/font/devhtml/R.proto
@@ -12,18 +12,14 @@ 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 0x002D
-hy "
+hy 24 0 0x002D
- "
-mi "
-en "
. 24 0 0x002E
/ 24 0 0x002F
sl "
@@ -40,11 +36,9 @@ sl "
: 24 0 0x003A
; 24 0 0x003B
< 24 0 0x003C &lt;
-la "
= 24 0 0x003D
eq "
> 24 0 0x003E &gt;
-ra "
? 24 0 0x003F
@ 24 0 0x0040
at "
@@ -86,7 +80,8 @@ ha "
_ 24 0 0x005F
ru "
ul "
-` 24 0 0x0060
+\` 24 0 0x0060
+ga "
a 24 0 0x0061
b 24 0 0x0062
c 24 0 0x0063
@@ -221,7 +216,176 @@ tdi "
'y 24 0 0x00FD &yacute;
Tp 24 0 0x00FE &thorn;
:y 24 0 0x00FF &yuml;
-\` 24 0 0x2018 &grave;
-ga "
+.i 24 0 0x0131 &#305;
+/L 24 0 0x0141 &#321;
+/l 24 0 0x0142 &#322;
+OE 24 0 0x0152 &OElig;
+oe 24 0 0x0153 &oelig;
+vS 24 0 0x0160 &Scaron;
+vs 24 0 0x0161 &scaron;
+:Y 24 0 0x0178 &Yuml;
+vZ 24 0 0x017D &#381;
+vz 24 0 0x017E &#382;
+Fn 24 0 0x0192 &fnof;
+ah 24 0 0x02C7 &#711;
+ab 24 0 0x02D8 &#728;
+a. 24 0 0x02D9 &#729;
+ao 24 0 0x02DA &#730;
+ho 24 0 0x02DB &#731;
+a" 24 0 0x02DD &#733;
+*A 24 0 0x0391 &Alpha;
+*B 24 0 0x0392 &Beta;
+*G 24 0 0x0393 &Gamma;
+*D 24 0 0x0394 &Delta;
+*E 24 0 0x0395 &Epsilon;
+*Z 24 0 0x0396 &Zeta;
+*Y 24 0 0x0397 &Eta;
+*H 24 0 0x0398 &Theta;
+*I 24 0 0x0399 &Iota;
+*K 24 0 0x039A &Kappa;
+*L 24 0 0x039B &Lambda;
+*M 24 0 0x039C &Mu;
+*N 24 0 0x039D &Nu;
+*C 24 0 0x039E &Xi;
+*O 24 0 0x039F &Omicron;
+*P 24 0 0x03A0 &Pi;
+*R 24 0 0x03A1 &Rho;
+*S 24 0 0x03A3 &Sigma;
+*T 24 0 0x03A4 &Tau;
+*U 24 0 0x03A5 &Upsilon;
+*F 24 0 0x03A6 &Phi;
+*X 24 0 0x03A7 &Chi;
+*Q 24 0 0x03A8 &Psi;
+*W 24 0 0x03A9 &Omega;
+*a 24 0 0x03B1 &alpha;
+*b 24 0 0x03B2 &beta;
+*g 24 0 0x03B3 &gamma;
+*d 24 0 0x03B4 &delta;
+*e 24 0 0x03B5 &epsilon;
+*z 24 0 0x03B6 &zeta;
+*y 24 0 0x03B7 &eta;
+*h 24 0 0x03B8 &theta;
+*i 24 0 0x03B9 &iota;
+*k 24 0 0x03BA &kappa;
+*l 24 0 0x03BB &lambda;
+*m 24 0 0x03BC &mu;
+*n 24 0 0x03BD &nu;
+*c 24 0 0x03BE &xi;
+*o 24 0 0x03BF &omicron;
+*p 24 0 0x03C0 &pi;
+*r 24 0 0x03C1 &rho;
+ts 24 0 0x03C2 &sigmaf;
+*s 24 0 0x03C3 &sigma;
+*t 24 0 0x03C4 &tau;
+*u 24 0 0x03C5 &upsilon;
+*f 24 0 0x03C6 &phi;
+*x 24 0 0x03C7 &chi;
+*q 24 0 0x03C8 &psi;
+*w 24 0 0x03C9 &omega;
++h 24 0 0x03D1 &thetasym;
++f 24 0 0x03D5 &#981;
++p 24 0 0x03D6 &piv;
+en 24 0 0x2013 &ndash;
+em 24 0 0x2014 &mdash;
+` 24 0 0x2018 &lsquo;
+oq "
+' 24 0 0x2019 &rsquo;
+cq "
+bq 24 0 0x201A &sbquo;
+lq 24 0 0x201C &ldquo;
+rq 24 0 0x201D &rdquo;
+Bq 24 0 0x201E &bdquo;
+dg 24 0 0x2020 &dagger;
+dd 24 0 0x2021 &Dagger;
+bu 24 0 0x2022 &bull;
+%0 24 0 0x2030 &permil;
+fm 24 0 0x2032 &prime;
+sd 24 0 0x2033 &Prime;
+fo 24 0 0x2039 &lsaquo;
+fc 24 0 0x203A &rsaquo;
+rn 24 0 0x203E &oline;
+f/ 24 0 0x2044 &frasl;
Eu 24 0 0x20AC &euro;
eu "
+Im 24 0 0x2111 &image;
+wp 24 0 0x2118 &weierp;
+Re 24 0 0x211C &real;
+tm 24 0 0x2122 &trade;
+Ah 24 0 0x2135 &alefsym;
+<- 24 0 0x2190 &larr;
+ua 24 0 0x2191 &uarr;
+-> 24 0 0x2192 &rarr;
+da 24 0 0x2193 &darr;
+<> 24 0 0x2194 &harr;
+lA 24 0 0x21D0 &lArr;
+uA 24 0 0x21D1 &uArr;
+rA 24 0 0x21D2 &rArr;
+dA 24 0 0x21D3 &dArr;
+hA 24 0 0x21D4 &hArr;
+fa 24 0 0x2200 &forall;
+pd 24 0 0x2202 &part;
+te 24 0 0x2203 &exist;
+es 24 0 0x2205 &empty;
+gr 24 0 0x2207 &nabla;
+mo 24 0 0x2208 &isin;
+nm 24 0 0x2209 &notin;
+st 24 0 0x220B &ni;
+product 24 0 0x220F &prod;
+sum 24 0 0x2211 &sum;
+\- 24 0 0x2212 &minus;
+mi "
+** 24 0 0x2217 &lowast;
+sr 24 0 0x221A &radic;
+pt 24 0 0x221D &prop;
+if 24 0 0x221E &infin;
+/_ 24 0 0x2220 &ang;
+AN 24 0 0x2227 &and;
+OR 24 0 0x2228 &or;
+ca 24 0 0x2229 &cap;
+cu 24 0 0x222A &cup;
+is 24 0 0x222B &int;
+tf 24 0 0x2234 &there4;
+3d "
+ti 24 0 0x223C &sim;
+ap "
+=~ 24 0 0x2245 &cong;
+~~ 24 0 0x2248 &asymp;
+~= "
+!= 24 0 0x2260 &ne;
+== 24 0 0x2261 &equiv;
+<= 24 0 0x2264 &le;
+>= 24 0 0x2265 &ge;
+sb 24 0 0x2282 &sub;
+sp 24 0 0x2283 &sup;
+nb 24 0 0x2284 &nsub;
+ib 24 0 0x2286 &sube;
+ip 24 0 0x2287 &supe;
+c+ 24 0 0x2295 &oplus;
+c* 24 0 0x2297 &otimes;
+pp 24 0 0x22A5 &perp;
+md 24 0 0x22C5 &sdot;
+lc 24 0 0x2308 &lceil;
+rc 24 0 0x2309 &rceil;
+lf 24 0 0x230A &lfloor;
+rf 24 0 0x230B &rfloor;
+la 24 0 0x2329 &lang;
+ra 24 0 0x232A &rang;
+CR 24 0 0x240D &#9229;
+an 24 0 0x2500 &#9472;
+br 24 0 0x2502 &#9474;
+bv "
+rk 24 0 0x251D &#9501;
+lk 24 0 0x2525 &#9509;
+lt 24 0 0x256D &#9581;
+rt 24 0 0x256E &#9582;
+rb 24 0 0x256F &#9583;
+lb 24 0 0x2570 &#9584;
+sq 24 0 0x25A1 &#9633;
+lz 24 0 0x25CA &loz;
+ci 24 0 0x25EF &#9711;
+lh 24 0 0x261C &#9756;
+rh 24 0 0x261E &#9758;
+SP 24 0 0x2660 &spades;
+CL 24 0 0x2663 &clubs;
+HE 24 0 0x2665 &hearts;
+DI 24 0 0x2666 &diams;
diff --git a/font/devutf8/NOTES b/font/devutf8/NOTES
index 12a736f9..52aeec04 100644
--- a/font/devutf8/NOTES
+++ b/font/devutf8/NOTES
@@ -11,8 +11,8 @@ Character 0x002D has not been given a name because its Unicode name
The following, mentioned in the original troff manual, are only approximate:
- \(lk middle part of big left curly brace
- \(rk middle part of big right curly brace
+ \(lk middle part of big left curly brace
+ \(rk middle part of big right curly brace
\(wp has been mapped to 0x2118, because according to unicode.org's
NamesList-3.0.0.txt, U+2118 "SCRIPT CAPITAL P" is really a Weierstrass p,
@@ -20,23 +20,12 @@ neither SCRIPT not CAPITAL.
The following lines could be added, to define names which are known to
"devps" but are not documented and not known to "devdvi".
+
space 24 0 0x0020
-vS 24 0 0x0160
-vs 24 0 0x0161
-:Y 24 0 0x0178
-vZ 24 0 0x017D
-vz 24 0 0x017E
-3d 24 0 0x2234
-nb 24 0 0x2284
-product 24 0 0x220F
-sum 24 0 0x2211
-SP 24 0 0x2660
-CL 24 0 0x2663
-HE 24 0 0x2665
-DI 24 0 0x2666
The following lines could be added, to define names which are known to e.g.
"devdvi" but are not known to "devps".
+
<< 24 0 0x226A
>> 24 0 0x226B
diff --git a/font/devutf8/R.proto b/font/devutf8/R.proto
index f4da0111..423bc6a6 100644
--- a/font/devutf8/R.proto
+++ b/font/devutf8/R.proto
@@ -138,6 +138,7 @@ t+- "
S2 24 0 0x00B2
S3 24 0 0x00B3
aa 24 0 0x00B4
+\' "
mc 24 0 0x00B5
ps 24 0 0x00B6
pc 24 0 0x00B7
@@ -220,6 +221,11 @@ Tp 24 0 0x00FE
/l 24 0 0x0142
OE 24 0 0x0152
oe 24 0 0x0153
+vS 24 0 0x0160
+vs 24 0 0x0161
+:Y 24 0 0x0178
+vZ 24 0 0x017D
+vz 24 0 0x017E
Fn 24 0 0x0192
ah 24 0 0x02C7
ab 24 0 0x02D8
@@ -326,6 +332,8 @@ gr 24 0 0x2207
mo 24 0 0x2208
nm 24 0 0x2209
st 24 0 0x220B
+product 24 0 0x220F
+sum 24 0 0x2211
\- 24 0 0x2212
mi "
** 24 0 0x2217
@@ -339,6 +347,7 @@ ca 24 0 0x2229
cu 24 0 0x222A
is 24 0 0x222B
tf 24 0 0x2234
+3d "
ti 24 0 0x223C
ap "
=~ 24 0 0x2245
@@ -350,12 +359,13 @@ ap "
>= 24 0 0x2265
sb 24 0 0x2282
sp 24 0 0x2283
+nb 24 0 0x2284
ib 24 0 0x2286
ip 24 0 0x2287
c+ 24 0 0x2295
c* 24 0 0x2297
pp 24 0 0x22A5
-pc 24 0 0x22C5
+md 24 0 0x22C5
lc 24 0 0x2308
rc 24 0 0x2309
lf 24 0 0x230A
@@ -377,6 +387,10 @@ lz 24 0 0x25CA
ci 24 0 0x25EF
lh 24 0 0x261C
rh 24 0 0x261E
+SP 24 0 0x2660
+CL 24 0 0x2663
+HE 24 0 0x2665
+DI 24 0 0x2666
ff 24 0 0xFB00
fi 24 0 0xFB01
fl 24 0 0xFB02
diff --git a/man/groff_char.man b/man/groff_char.man
index 721b3a7c..2d934aa3 100644
--- a/man/groff_char.man
+++ b/man/groff_char.man
@@ -909,6 +909,8 @@ Output Input PostScript Notes
.C2 /_ angle
.C2 pp perpendicular
.C2 is integral
+.CN sum sum
+.CN product product
.C2 gr gradient
.C2 sr radical "square root"
.C2 rn \& overline "continuation of square root"
diff --git a/src/devices/grohtml/Makefile.sub b/src/devices/grohtml/Makefile.sub
index be1a305a..f2499139 100644
--- a/src/devices/grohtml/Makefile.sub
+++ b/src/devices/grohtml/Makefile.sub
@@ -4,12 +4,15 @@ XLIBS=$(LIBDRIVER) $(LIBGROFF)
MLIB=$(LIBM)
OBJS=\
post-html.o \
+ html-table.o \
html-text.o \
output.o
CCSRCS=\
$(srcdir)/post-html.cc \
+ $(srcdir)/html-table.cc \
$(srcdir)/html-text.cc \
$(srcdir)/output.cc
HDRS=\
$(srcdir)/html.h \
+ $(srcdir)/html-table.h \
$(srcdir)/html-text.h
diff --git a/src/devices/grohtml/html-text.cc b/src/devices/grohtml/html-text.cc
index 8da70982..8ad3b0d4 100644
--- a/src/devices/grohtml/html-text.cc
+++ b/src/devices/grohtml/html-text.cc
@@ -44,7 +44,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
html_text::html_text (simple_output *op) :
stackptr(NULL), lastptr(NULL), out(op), space_emitted(TRUE),
- current_indentation(-1), pageoffset(-1), linelength(-1)
+ current_indentation(-1), pageoffset(-1), linelength(-1),
+ blank_para(TRUE), start_space(FALSE)
{
}
@@ -77,17 +78,24 @@ void html_text::dump_stack_element (tag_definition *p)
fprintf(stderr, " | ");
switch (p->type) {
- case P_TAG: fprintf(stderr, "<P %s>", (char *)p->arg1); break;
+ case P_TAG: if (p->indent == NULL) {
+ fprintf(stderr, "<P %s>", (char *)p->arg1); break;
+ } else {
+ fprintf(stderr, "<P %s [TABLE]>", (char *)p->arg1); break;
+ }
case I_TAG: fprintf(stderr, "<I>"); break;
case B_TAG: fprintf(stderr, "<B>"); break;
case SUB_TAG: fprintf(stderr, "<SUB>"); break;
case SUP_TAG: fprintf(stderr, "<SUP>"); break;
case TT_TAG: fprintf(stderr, "<TT>"); break;
- case PRE_TAG: fprintf(stderr, "<PRE>"); break;
+ case PRE_TAG: if (p->indent == NULL) {
+ fprintf(stderr, "<PRE>"); break;
+ } else {
+ fprintf(stderr, "<PRE [TABLE]>"); break;
+ }
case SMALL_TAG: fprintf(stderr, "<SMALL>"); break;
case BIG_TAG: fprintf(stderr, "<BIG>"); break;
case BREAK_TAG: fprintf(stderr, "<BREAK>"); break;
- case TABLE_TAG: fprintf(stderr, "<TABLE>"); break;
case COLOR_TAG: {
if (p->col.is_default())
fprintf(stderr, "<COLOR (default)>");
@@ -118,8 +126,9 @@ void html_text::dump_stack (void)
dump_stack_element(p);
p = p->next;
}
- fflush(stderr);
}
+ fprintf(stderr, "\n");
+ fflush(stderr);
}
#else
void html_text::dump_stack (void) {}
@@ -136,19 +145,20 @@ void html_text::end_tag (tag_definition *t)
case I_TAG: out->put_string("</i>"); break;
case B_TAG: out->put_string("</b>"); break;
- case P_TAG: out->put_string("</p>").nl().enable_newlines(FALSE); break;
+ case P_TAG: out->put_string("</p>");
+ if (t->indent != NULL) {
+ delete t->indent;
+ t->indent = NULL;
+ }
+ out->nl(); out->enable_newlines(FALSE);
+ blank_para = TRUE; break;
case SUB_TAG: out->put_string("</sub>"); break;
case SUP_TAG: out->put_string("</sup>"); break;
case TT_TAG: out->put_string("</tt>"); break;
- case PRE_TAG: out->put_string("</pre>");
- if (! is_present(TABLE_TAG)) {
- out->nl();
- out->enable_newlines(TRUE);
- }
- break;
+ case PRE_TAG: out->put_string("</pre>"); out->nl(); out->enable_newlines(TRUE);
+ blank_para = TRUE; break;
case SMALL_TAG: out->put_string("</small>"); break;
case BIG_TAG: out->put_string("</big>"); break;
- case TABLE_TAG: issue_table_end(); break;
case COLOR_TAG: out->put_string("</font>"); break;
default:
@@ -204,16 +214,32 @@ void html_text::start_tag (tag_definition *t)
case I_TAG: issue_tag("<i", (char *)t->arg1); break;
case B_TAG: issue_tag("<b", (char *)t->arg1); break;
- case P_TAG: issue_tag("\n<p", (char *)t->arg1);
+ case P_TAG: if (t->indent == NULL) {
+ out->nl();
+ issue_tag("\n<p", (char *)t->arg1);
+ } else {
+ out->nl();
+ out->simple_comment("INDENTATION");
+ t->indent->begin(start_space);
+ start_space = FALSE;
+ issue_tag("<p", (char *)t->arg1);
+ }
+
out->enable_newlines(TRUE); break;
case SUB_TAG: issue_tag("<sub", (char *)t->arg1); break;
case SUP_TAG: issue_tag("<sup", (char *)t->arg1); break;
case TT_TAG: issue_tag("<tt", (char *)t->arg1); break;
- case PRE_TAG: out->nl(); issue_tag("<pre", (char *)t->arg1);
+ case PRE_TAG: if (t->indent != NULL) {
+ out->nl();
+ out->simple_comment("INDENTATION");
+ t->indent->begin(start_space);
+ start_space = FALSE;
+ }
+ out->enable_newlines(TRUE);
+ out->nl(); issue_tag("<pre", (char *)t->arg1);
out->enable_newlines(FALSE); break;
case SMALL_TAG: issue_tag("<small", (char *)t->arg1); break;
case BIG_TAG: issue_tag("<big", (char *)t->arg1); break;
- case TABLE_TAG: issue_table_begin((char *)t->arg1); break;
case BREAK_TAG: break;
case COLOR_TAG: issue_color_begin(&t->col); break;
@@ -222,53 +248,6 @@ void html_text::start_tag (tag_definition *t)
}
}
-int html_text::table_is_void (tag_definition *t)
-{
-#if 1
- return (linelength > 0
- && current_indentation*100/linelength <= 0);
-
-#else
- if (t->next != NULL
- && linelength > 0
- && current_indentation*100/linelength <= 0) {
- t = t->next;
- while (t != NULL) {
- if (t->text_emitted)
- return FALSE;
- t = t->next;
- }
- }
- return TRUE;
-#endif
-}
-
-void html_text::issue_table_begin (char *arg)
-{
- if (linelength > 0) {
- int width=current_indentation*100/linelength;
-
- if (width > 0) {
- out->put_string("<table width=\"100%\" border=0 rules=\"none\" frame=\"void\"\n cols=\"2\" cellspacing=\"0\" cellpadding=\"0\">").nl();
- out->put_string("<tr valign=\"top\" align=\"left\">").nl();
- if ((arg == 0) || (strcmp(arg, "") == 0))
- out->put_string("<td width=\"").put_number(width).put_string("%\"></td>");
- else {
- out->put_string("<td width=\"").put_number(width).put_string("%\">").nl();
- out->put_string(arg).put_string("</td>");
- arg[0] = (char)0;
- }
- out->put_string("<td width=\"").put_number(100-width).put_string("%\">").nl();
- }
- }
-}
-
-void html_text::issue_table_end (void)
-{
- out->put_string("</td></table>").nl();
- out->enable_newlines(TRUE);
-}
-
/*
* flush_text - flushes html tags which are outstanding on the html stack.
*/
@@ -324,47 +303,21 @@ void html_text::do_push (tag_definition *p)
dump_stack_element(p);
fprintf(stderr, ")\n");
dump_stack();
+ fprintf(stderr, ")\n");
+ fflush(stderr);
#endif
/*
- * if t is a P_TAG or TABLE_TAG or PRE_TAG make sure it goes on the end of the stack.
- * But we insist that a TABLE_TAG is always after a PRE_TAG
- * and that a P_TAG is always after a TABLE_TAG
+ * if t is a P_TAG or PRE_TAG make sure it goes on the end of the stack.
*/
- if (((t == P_TAG) || (t == PRE_TAG) || (t == TABLE_TAG)) &&
- (lastptr != NULL)) {
- if (((lastptr->type == TABLE_TAG) && (t == PRE_TAG)) ||
- ((lastptr->type == P_TAG) && (t == TABLE_TAG))) {
- /*
- * insert p before the lastptr
- */
- if (stackptr == lastptr) {
- /*
- * only one element of the stack
- */
- p->next = stackptr;
- stackptr = p;
- } else {
- /*
- * more than one element is on the stack
- */
- tag_definition *q = stackptr;
-
- while (q->next != lastptr)
- q = q->next;
-
- q->next = p;
- p->next = lastptr;
- }
- } else {
- /*
- * store, p, at the end
- */
- lastptr->next = p;
- lastptr = p;
- p->next = NULL;
- }
+ if (((t == P_TAG) || (t == PRE_TAG)) && (lastptr != NULL)) {
+ /*
+ * store, p, at the end
+ */
+ lastptr->next = p;
+ lastptr = p;
+ p->next = NULL;
} else {
p->next = stackptr;
if (stackptr == NULL)
@@ -382,20 +335,24 @@ void html_text::do_push (tag_definition *p)
* push_para - adds a new entry onto the html paragraph stack.
*/
-void html_text::push_para (HTML_TAG t, void *arg)
+void html_text::push_para (HTML_TAG t, void *arg, html_indent *in)
{
tag_definition *p=(tag_definition *)malloc(sizeof(tag_definition));
p->type = t;
p->arg1 = arg;
p->text_emitted = FALSE;
+ p->indent = in;
+
+ if (t == PRE_TAG && is_present(PRE_TAG))
+ fatal("cannot have multiple PRE_TAGs");
do_push(p);
}
void html_text::push_para (HTML_TAG t)
{
- push_para(t, (void *)"");
+ push_para(t, (void *)"", NULL);
}
void html_text::push_para (color *c)
@@ -406,56 +363,12 @@ void html_text::push_para (color *c)
p->arg1 = NULL;
p->col = *c;
p->text_emitted = FALSE;
+ p->indent = NULL;
do_push(p);
}
/*
- * do_indent - remember the indent parameters and if
- * indent is > pageoff and indent has changed
- * then we start a html table to implement the indentation.
- */
-
-void html_text::do_indent (const char *arg, int indent, int pageoff, int linelen)
-{
- if ((current_indentation != -1) &&
- (pageoffset+current_indentation != indent+pageoff)) {
- /*
- * actual indentation of text has changed, we need to put
- * a table tag onto the stack.
- */
- do_table(arg);
- }
- current_indentation = indent;
- pageoffset = pageoff;
- linelength = linelen;
-}
-
-void html_text::do_table (const char *arg)
-{
- int in_pre = is_in_pre();
- // char *para_type = done_para();
- done_pre();
- shutdown(TABLE_TAG); // shutdown a previous table, if present
- remove_break();
- if (in_pre) {
- do_pre();
- }
- // do_para(para_type);
- push_para(TABLE_TAG, (void *)arg);
-}
-
-/*
- * done_table - terminates a possibly existing table.
- */
-
-void html_text::done_table (void)
-{
- shutdown(TABLE_TAG);
- space_emitted = TRUE;
-}
-
-/*
* do_italic - changes to italic
*/
@@ -503,10 +416,14 @@ void html_text::do_pre (void)
done_bold();
done_italic();
done_tt();
- (void)done_para();
- if (! is_present(PRE_TAG)) {
- push_para(PRE_TAG);
- }
+ if (is_present(P_TAG)) {
+ html_indent *i = remove_indent(P_TAG);
+ (void)done_para();
+ if (! is_present(PRE_TAG))
+ push_para(PRE_TAG, NULL, i);
+ } else if (! is_present(PRE_TAG))
+ push_para(PRE_TAG, NULL, NULL);
+ dump_stack();
}
/*
@@ -520,15 +437,6 @@ int html_text::is_in_pre (void)
}
/*
- * is_in_table - returns TRUE if we are currently within a table.
- */
-
-int html_text::is_in_table (void)
-{
- return is_present(TABLE_TAG);
-}
-
-/*
* do_color - initiates a new color tag.
*/
@@ -596,6 +504,8 @@ char *html_text::shutdown (HTML_TAG t)
stackptr = stackptr->next;
if (stackptr == NULL)
lastptr = NULL;
+ if (p->indent != NULL)
+ delete p->indent;
free(p);
}
@@ -606,7 +516,7 @@ char *html_text::shutdown (HTML_TAG t)
if (temp->type == COLOR_TAG)
push_para(&temp->col);
else
- push_para(temp->type, temp->arg1);
+ push_para(temp->type, temp->arg1, temp->indent);
p = temp;
temp = temp->next;
free(p);
@@ -695,28 +605,9 @@ void html_text::done_big (void)
void html_text::check_emit_text (tag_definition *t)
{
if ((t != NULL) && (! t->text_emitted)) {
- /*
- * we peep and see whether there is a <p> before the <table>
- * in which case we skip the <p>
- */
- if (t->type == TABLE_TAG) {
- if (table_is_void(t)) {
- tag_definition *n = t->next;
- remove_def(t);
- check_emit_text(n);
- } else {
- /*
- * a table which will be emitted, is there a <p> succeeding it?
- */
- check_emit_text(t->next);
- t->text_emitted = TRUE;
- start_tag(t);
- }
- } else {
- check_emit_text(t->next);
- t->text_emitted = TRUE;
- start_tag(t);
- }
+ check_emit_text(t->next);
+ t->text_emitted = TRUE;
+ start_tag(t);
}
}
@@ -744,25 +635,47 @@ void html_text::do_emittext (const char *s, int length)
}
out->put_string(s, length);
space_emitted = FALSE;
+ blank_para = FALSE;
}
/*
* do_para - starts a new paragraph
*/
-void html_text::do_para (const char *arg)
+void html_text::do_para (const char *arg, html_indent *in)
{
- done_pre();
if (! is_present(P_TAG)) {
- remove_sub_sup();
- if ((arg != 0) && (strcmp(arg, "") != 0)) {
- remove_tag(TABLE_TAG);
+ if (is_present(PRE_TAG)) {
+ html_indent *i = remove_indent(PRE_TAG);
+ done_pre();
+ if (i == in || in == NULL)
+ in = i;
+ else
+ delete i;
}
- push_para(P_TAG, (void *)arg);
+ remove_sub_sup();
+ push_para(P_TAG, (void *)arg, in);
space_emitted = TRUE;
}
}
+void html_text::do_para (const char *arg)
+{
+ do_para(arg, NULL);
+}
+
+void html_text::do_para (simple_output *op, const char *arg1,
+ int indentation, int pageoffset, int linelength)
+{
+ html_indent *indent;
+
+ if (indentation == 0)
+ indent = NULL;
+ else
+ indent = new html_indent(op, indentation, pageoffset, linelength);
+ do_para(arg1, indent);
+}
+
/*
* done_para - shuts down a paragraph tag.
*/
@@ -774,14 +687,44 @@ char *html_text::done_para (void)
}
/*
+ * remove_indent - returns the indent associated with, tag.
+ * The indent associated with tag is set to NULL.
+ */
+
+html_indent *html_text::remove_indent (HTML_TAG tag)
+{
+ tag_definition *p=stackptr;
+
+ while (p != NULL) {
+ if (tag == p->type) {
+ html_indent *i = p->indent;
+ p->indent = NULL;
+ return i;
+ }
+ p = p->next;
+ }
+ return NULL;
+}
+
+/*
* do_space - issues an end of paragraph
*/
void html_text::do_space (void)
{
- if (! is_in_pre()) {
- do_para(done_para());
+ if (is_in_pre()) {
+ if (blank_para)
+ start_space = TRUE;
+ else {
+ do_emittext("", 0);
+ out->nl();
+ }
+ } else {
+ html_indent *i = remove_indent(P_TAG);
+
+ do_para(done_para(), i);
space_emitted = TRUE;
+ start_space = TRUE;
}
}
@@ -823,6 +766,24 @@ int html_text::emitted_text (void)
}
/*
+ * ever_emitted_text - returns TRUE if we have ever emitted text in this paragraph.
+ */
+
+int html_text::ever_emitted_text (void)
+{
+ return !blank_para;
+}
+
+/*
+ * starts_with_space - returns TRUE if we have start this paragraph with a .sp
+ */
+
+int html_text::starts_with_space (void)
+{
+ return start_space;
+}
+
+/*
* emit_space - writes a space providing that text was written beforehand.
*/
@@ -946,6 +907,29 @@ int html_text::remove_break (void)
}
/*
+ * remove_para_align - removes a paragraph which has a text
+ * argument. If the paragraph has no text
+ * argument then it is left alone.
+ */
+
+void html_text::remove_para_align (void)
+{
+ if (is_present(P_TAG)) {
+ tag_definition *p=stackptr;
+
+ while (p != NULL) {
+ if (p->type == P_TAG && p->arg1 != NULL) {
+ html_indent *i = remove_indent(P_TAG);
+ done_para();
+ do_para("", i);
+ return;
+ }
+ p = p->next;
+ }
+ }
+}
+
+/*
* do_small - potentially inserts a <small> tag into the html stream.
* However we check for a <big> tag, if present then we terminate it.
* Otherwise a <small> tag is inserted.
diff --git a/src/devices/grohtml/html-text.h b/src/devices/grohtml/html-text.h
index e3073cfa..c43cbda1 100644
--- a/src/devices/grohtml/html-text.h
+++ b/src/devices/grohtml/html-text.h
@@ -26,13 +26,14 @@ 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 "html.h"
+#include "html-table.h"
/*
* html tags
*/
typedef enum {I_TAG, B_TAG, P_TAG, SUB_TAG, SUP_TAG, TT_TAG,
- PRE_TAG, SMALL_TAG, BIG_TAG, BREAK_TAG, TABLE_TAG,
+ PRE_TAG, SMALL_TAG, BIG_TAG, BREAK_TAG,
COLOR_TAG} HTML_TAG;
typedef struct tag_definition {
@@ -40,6 +41,7 @@ typedef struct tag_definition {
void *arg1;
int text_emitted;
color col;
+ html_indent *indent;
tag_definition *next;
} tag_definition ;
@@ -51,58 +53,64 @@ typedef struct tag_definition {
class html_text {
public:
- html_text (simple_output *op);
- ~html_text (void);
- void flush_text (void);
- void do_emittext (const char *s, int length);
- void do_italic (void);
- void do_bold (void);
- void do_roman (void);
- void do_tt (void);
- void do_pre (void);
- void do_small (void);
- void do_big (void);
- void do_para (const char *arg1);
- void do_sup (void);
- void do_sub (void);
- void do_space (void);
- void do_break (void);
- void do_newline (void);
- void do_table (const char *arg);
- void done_bold (void);
- void done_italic (void);
- char *done_para (void);
- void done_sup (void);
- void done_sub (void);
- void done_tt (void);
- void done_pre (void);
- void done_small (void);
- void done_big (void);
- void do_indent (const char *arg, int indent, int pageoff, int linelen);
- void do_color (color *c);
- void done_color (void);
- int emitted_text (void);
- void emit_space (void);
- int is_in_pre (void);
- void remove_tag (HTML_TAG tag);
- void remove_sub_sup (void);
- void done_table (void);
- int is_in_table (void);
+ html_text (simple_output *op);
+ ~html_text (void);
+ void flush_text (void);
+ void do_emittext (const char *s, int length);
+ void do_italic (void);
+ void do_bold (void);
+ void do_roman (void);
+ void do_tt (void);
+ void do_pre (void);
+ void do_small (void);
+ void do_big (void);
+ void do_para (const char *arg); // used for no indentation
+ void do_para (simple_output *op, const char *arg1,
+ int indentation, int pageoffset, int linelength);
+ void do_sup (void);
+ void do_sub (void);
+ void do_space (void);
+ void do_break (void);
+ void do_newline (void);
+ void do_table (const char *arg);
+ void done_bold (void);
+ void done_italic (void);
+ char *done_para (void);
+ void done_sup (void);
+ void done_sub (void);
+ void done_tt (void);
+ void done_pre (void);
+ void done_small (void);
+ void done_big (void);
+ void do_color (color *c);
+ void done_color (void);
+ int emitted_text (void);
+ int ever_emitted_text (void);
+ int starts_with_space (void);
+ void emit_space (void);
+ int is_in_pre (void);
+ void remove_tag (HTML_TAG tag);
+ void remove_sub_sup (void);
+ void remove_para_align (void);
private:
tag_definition *stackptr; /* the current paragraph state */
tag_definition *lastptr; /* the end of the stack */
simple_output *out;
- int space_emitted;
- int current_indentation; /* current .in value */
- int pageoffset; /* .po value */
- int linelength; /* current line length */
+ int space_emitted; /* just emitted a space? */
+ int current_indentation; /* current .in value */
+ int pageoffset; /* .po value */
+ int linelength; /* current line length */
+ int blank_para; /* have we ever written text? */
+ int start_space; /* does para start with a .sp */
+ html_indent *indent; /* our indent class */
int is_present (HTML_TAG t);
void end_tag (tag_definition *t);
void start_tag (tag_definition *t);
- void push_para (HTML_TAG t, void *arg);
+ void do_para (const char *arg, html_indent *in);
void push_para (HTML_TAG t);
+ void push_para (HTML_TAG t, void *arg, html_indent *in);
void push_para (color *c);
void do_push (tag_definition *p);
char *shutdown (HTML_TAG t);
@@ -110,10 +118,8 @@ private:
int remove_break (void);
void issue_tag (char *tagname, char *arg);
void issue_color_begin (color *c);
- void issue_table_begin (char *arg);
- void issue_table_end (void);
- int table_is_void (tag_definition *t);
void remove_def (tag_definition *t);
+ html_indent *remove_indent (HTML_TAG tag);
void dump_stack_element (tag_definition *p);
void dump_stack (void);
};
diff --git a/src/devices/grohtml/post-html.cc b/src/devices/grohtml/post-html.cc
index 854bd372..0d442ee5 100644
--- a/src/devices/grohtml/post-html.cc
+++ b/src/devices/grohtml/post-html.cc
@@ -28,6 +28,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cset.h"
#include "html.h"
#include "html-text.h"
+#include "html-table.h"
#include <time.h>
@@ -55,10 +56,11 @@ extern "C" const char *Version_string;
#define UNICODE_DESC_START 0x80 /* all character entities above this are */
/* either encoded by their glyph names or if */
/* there is no name then we use &#nnn; */
-#define INDENTATION /* #undef INDENTATION to remove .in handling */
-
typedef enum {CENTERED, LEFT, RIGHT, INLINE} TAG_ALIGNMENT;
+#undef DEBUG_TABLES
+
+
/*
* prototypes
*/
@@ -85,20 +87,18 @@ void stop () {}
static int min (int a, int b)
{
- if (a < b) {
- return( a );
- } else {
- return( b );
- }
+ if (a < b)
+ return a;
+ else
+ return b;
}
static int max (int a, int b)
{
- if (a > b) {
- return( a );
- } else {
- return( b );
- }
+ if (a > b)
+ return a;
+ else
+ return b;
}
/*
@@ -107,7 +107,7 @@ static int max (int a, int b)
static int is_intersection (int a1, int a2, int b1, int b2)
{
- // again easier to prove NOT outside limits
+ // easier to prove NOT outside limits
return( ! ((a1 > b2) || (a2 < b1)) );
}
@@ -366,7 +366,25 @@ public:
int is_eol (void);
int is_auto_img (void);
int is_br (void);
+ int is_br_ni (void);
+ int is_in (void);
+ int is_po (void);
+ int is_ti (void);
+ int is_ce (void);
int is_eol_ce (void);
+ int is_col (void);
+ int is_tab (void);
+ int is_tab0 (void);
+ int is_ta (void);
+ int is_tab_ts (void);
+ int is_tab_te (void);
+ int is_nf (void);
+ int is_fi (void);
+ int get_arg (void);
+ int get_tab_args (char *align);
+
+ void remember_table (html_table *t);
+ html_table *get_table (void);
style text_style;
const char *text_string;
@@ -377,6 +395,7 @@ public:
int is_special; // text has come via 'x X html:'
int is_line; // is the command a <line>?
int thickness; // the thickness of a line
+ html_table *tab; // table description
private:
text_glob (style *s, char *str, int length,
@@ -396,18 +415,20 @@ text_glob::text_glob (style *s, char *str, int length,
: text_style(*s), text_string(str), text_length(length),
minv(min_vertical), minh(min_horizontal), maxv(max_vertical), maxh(max_horizontal),
is_tag(is_troff_command), is_img_auto(is_auto_image), is_special(is_special_command),
- is_line(is_a_line), thickness(line_thickness)
+ is_line(is_a_line), thickness(line_thickness), tab(NULL)
{
}
text_glob::text_glob ()
: text_string(0), text_length(0), minv(-1), minh(-1), maxv(-1), maxh(-1),
- is_tag(FALSE), is_special(FALSE), is_line(FALSE), thickness(0)
+ is_tag(FALSE), is_special(FALSE), is_line(FALSE), thickness(0), tab(NULL)
{
}
text_glob::~text_glob ()
{
+ if (tab != NULL)
+ delete tab;
}
/*
@@ -539,6 +560,115 @@ int text_glob::is_eol_ce (void)
return( is_tag && (strcmp(text_string, "html-tag:eol.ce") == 0) );
}
+
+/*
+ * is_nf - returns TRUE if glob contains the tag .nf
+ */
+
+int text_glob::is_nf (void)
+{
+ return( is_tag && (strcmp(text_string, "html-tag:.nf") == 0) );
+}
+
+/*
+ * is_fi - returns TRUE if glob contains the tag .fi
+ */
+
+int text_glob::is_fi (void)
+{
+ return( is_tag && (strcmp(text_string, "html-tag:.fi") == 0) );
+}
+
+/*
+ * is_ce - returns TRUE if glob contains the tag .ce
+ */
+
+int text_glob::is_ce (void)
+{
+ return( is_tag && (strcmp(text_string, "html-tag:.ce") == 0) );
+}
+
+/*
+ * is_in - returns TRUE if glob contains the tag .in
+ */
+
+int text_glob::is_in (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:.in ", strlen("html-tag:.in ")) == 0) );
+}
+
+/*
+ * is_po - returns TRUE if glob contains the tag .po
+ */
+
+int text_glob::is_po (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:.po ", strlen("html-tag:.po ")) == 0) );
+}
+
+/*
+ * is_ti - returns TRUE if glob contains the tag .ti
+ */
+
+int text_glob::is_ti (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:.ti ", strlen("html-tag:.ti ")) == 0) );
+}
+
+/*
+ * is_col - returns TRUE if glob contains the tag .col
+ */
+
+int text_glob::is_col (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:.col", strlen("html-tag:.col")) == 0) );
+}
+
+/*
+ * is_tab_ts - returns TRUE if glob contains the tag .tab_ts
+ */
+
+int text_glob::is_tab_ts (void)
+{
+ return( is_tag && (strcmp(text_string, "html-tag:.tab-ts") == 0) );
+}
+
+/*
+ * is_tab_te - returns TRUE if glob contains the tag .tab_te
+ */
+
+int text_glob::is_tab_te (void)
+{
+ return( is_tag && (strcmp(text_string, "html-tag:.tab-te") == 0) );
+}
+
+/*
+ * is_ta - returns TRUE if glob contains the tag .ta
+ */
+
+int text_glob::is_ta (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:.ta ", strlen("html-tag:.ta ")) == 0) );
+}
+
+/*
+ * is_tab - returns TRUE if glob contains the tag tab
+ */
+
+int text_glob::is_tab (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:tab ", strlen("html-tag:tab ")) == 0) );
+}
+
+/*
+ * is_tab0 - returns TRUE if glob contains the tag tab0
+ */
+
+int text_glob::is_tab0 (void)
+{
+ return( is_tag && (strncmp(text_string, "html-tag:tab0", strlen("html-tag:tab0")) == 0) );
+}
+
/*
* is_auto_img - returns TRUE if the glob contains an automatically
* generated image.
@@ -551,7 +681,9 @@ int text_glob::is_auto_img (void)
/*
* is_br - returns TRUE if the glob is a tag containing a .br
- * or an implied .br
+ * or an implied .br. Note that we do not include .nf or .fi
+ * as grohtml will place a .br after these commands if they
+ * should break the line.
*/
int text_glob::is_br (void)
@@ -559,7 +691,80 @@ int text_glob::is_br (void)
return( is_a_tag() && ((strcmp ("html-tag:.br", text_string) == 0) ||
(strncmp("html-tag:.sp", text_string, 11) == 0) ||
(strcmp ("html-tag:.ce", text_string) == 0) ||
- (strcmp ("html-tag:.nf", text_string) == 0)) );
+ (strncmp ("html-tag:.in", text_string, 11) == 0)) );
+}
+
+/*
+ * is_br_ni - returns TRUE if the glob is a tag containing a .br
+ * or an implied .br, but not an .in
+ */
+
+int text_glob::is_br_ni (void)
+{
+ return( is_a_tag() && ((strcmp ("html-tag:.br", text_string) == 0) ||
+ (strncmp("html-tag:.sp", text_string, 11) == 0) ||
+ (strcmp ("html-tag:.ce", text_string) == 0)) );
+}
+
+int text_glob::get_arg (void)
+{
+ if (strncmp("html-tag:", text_string, strlen("html-tag:")) == 0) {
+ const char *p = text_string;
+
+ while ((*p != (char)0) && (!isspace(*p)))
+ p++;
+ while ((*p != (char)0) && (isspace(*p)))
+ p++;
+ if (*p == (char)0)
+ return -1;
+ return atoi(p);
+ }
+ return -1;
+}
+
+/*
+ * get_tab_args - returns the tab position and alignment of the tab tag
+ */
+
+int text_glob::get_tab_args (char *align)
+{
+ if (strncmp("html-tag:", text_string, strlen("html-tag:")) == 0) {
+ const char *p = text_string;
+
+ // firstly the alignment C|R|L
+ while ((*p != (char)0) && (!isspace(*p)))
+ p++;
+ while ((*p != (char)0) && (isspace(*p)))
+ p++;
+ *align = *p;
+ // now the int value
+ while ((*p != (char)0) && (!isspace(*p)))
+ p++;
+ while ((*p != (char)0) && (isspace(*p)))
+ p++;
+ if (*p == (char)0)
+ return -1;
+ return atoi(p);
+ }
+ return -1;
+}
+
+/*
+ * remember_table - saves table, t, in the text_glob.
+ */
+
+void text_glob::remember_table (html_table *t)
+{
+ tab = t;
+}
+
+/*
+ * get_table - returns the stored table description.
+ */
+
+html_table *text_glob::get_table (void)
+{
+ return tab;
}
/*
@@ -618,6 +823,8 @@ public:
int is_equal_to_head (void);
void start_from_head (void);
void start_from_tail (void);
+ void insert (text_glob *in);
+ void move_to (text_glob *in);
text_glob *move_right_get_data (void);
text_glob *move_left_get_data (void);
text_glob *get_data (void);
@@ -685,6 +892,7 @@ void list::add (text_glob *in, int line_number, int min_vertical, int min_horizo
if (head == 0) {
head = t;
tail = t;
+ ptr = t;
t->left = t;
t->right = t;
} else {
@@ -835,7 +1043,7 @@ text_glob* list::move_right_get_data (void)
/*
* move_left_get_data - returns the datum referenced via ptr and moves
- * ptr right.
+ * ptr right.
*/
text_glob* list::move_left_get_data (void)
@@ -849,6 +1057,39 @@ text_glob* list::move_left_get_data (void)
}
/*
+ * insert - inserts data after the current position.
+ */
+
+void list::insert (text_glob *in)
+{
+ if (is_empty())
+ fatal("list must not be empty if we are inserting data");
+ else {
+ if (ptr == 0)
+ ptr = head;
+
+ element_list *t = new element_list(in, ptr->lineno, ptr->minv, ptr->minh, ptr->maxv, ptr->maxh);
+ if (ptr == tail)
+ tail = t;
+ t->right = ptr->right;
+ ptr->right = t;
+ t->left = ptr;
+ }
+}
+
+/*
+ * move_to - moves the current position to the point where data, in, exists.
+ * This is an expensive method and should be used sparingly.
+ */
+
+void list::move_to (text_glob *in)
+{
+ ptr = head;
+ while (ptr != tail && ptr->datum != in)
+ ptr = ptr->right;
+}
+
+/*
* page class and methods
*/
@@ -871,6 +1112,7 @@ public:
int line_number,
int x1, int y1, int x2, int y2,
int thickness);
+ void insert_tag (const string &str);
void dump_page (void); // debugging method
// and the data
@@ -884,6 +1126,21 @@ page::page()
}
/*
+ * insert_tag - inserts a tag after the current position.
+ */
+
+void page::insert_tag (const string &str)
+{
+ if (str.length() > 0) {
+ text_glob *g=new text_glob();
+ text_glob *f=glyphs.get_data();
+ g->text_glob_tag(&f->text_style, buffer.add_string(str), str.length(),
+ f->minv, f->minh, f->maxv, f->maxh);
+ glyphs.insert(g);
+ }
+}
+
+/*
* add - add html text to the list of glyphs.
*/
@@ -1020,16 +1277,29 @@ void page::add_and_encode (style *s, const string &str,
void page::dump_page(void)
{
+#if defined(DEBUG_TABLES)
+ text_glob *old_pos = glyphs.get_data();
text_glob *g;
+ printf("\n<!--\n");
printf("\n\ndebugging start\n");
glyphs.start_from_head();
do {
g = glyphs.get_data();
+ if (g->is_tab_ts()) {
+ printf("\n\n");
+ if (g->get_table() != NULL)
+ g->get_table()->dump_table();
+ }
printf("%s ", g->text_string);
+ if (g->is_tab_te())
+ printf("\n\n");
glyphs.move_right();
} while (! glyphs.is_equal_to_head());
+ glyphs.move_to(old_pos);
printf("\ndebugging end\n\n");
+ printf("\n-->\n");
+#endif
}
/*
@@ -1177,17 +1447,19 @@ class html_printer : public printer {
char *inside_font_style;
int page_number;
title_desc title;
- title_desc indent; // use title class to remember $1 of .ip
header_desc header;
int header_indent;
int supress_sub_sup;
int cutoff_heading;
page *page_contents;
html_text *current_paragraph;
+ html_indent *indent;
+ html_table *table;
int end_center;
int end_tempindent;
TAG_ALIGNMENT next_tag;
int fill_on;
+ int max_linelength;
int linelength;
int pageoffset;
int indentation;
@@ -1227,6 +1499,7 @@ class html_printer : public printer {
void do_center (char *arg);
void do_break (void);
void do_eol (void);
+ void do_eol_ce (void);
void do_title (void);
void do_fill (int on);
void do_heading (char *arg);
@@ -1256,6 +1529,23 @@ class html_printer : public printer {
font *make_bold (font *f);
int overstrike (unsigned char code, const char *name, const environment *env, int w);
void do_body (void);
+ int next_horiz_pos (int nf);
+ void lookahead_for_tables (void);
+ void insert_tab_te (void);
+ text_glob *insert_tab_ts (text_glob *where);
+ void insert_tab0_foreach_tab (void);
+ void insert_tab_0 (text_glob *where);
+ void do_indent (int in, int pageoff, int linelen);
+ void shutdown_table (void);
+ void do_tab_ts (text_glob *g);
+ void do_tab_te (void);
+ void do_col (char *s);
+ void do_tab (char *s);
+ void do_tab0 (void);
+ int calc_nf (text_glob *g, int nf);
+ void calc_po_in (text_glob *g, int nf);
+ void remove_tabs (void);
+ void remove_courier_tabs (void);
// ADD HERE
public:
@@ -1342,8 +1632,6 @@ void html_printer::emit_raw (text_glob *g)
determine_space(g);
current_paragraph->do_emittext(g->text_string, g->text_length);
} else {
- int in_table=current_paragraph->is_in_table();
-
current_paragraph->done_para();
switch (next_tag) {
@@ -1351,10 +1639,10 @@ void html_printer::emit_raw (text_glob *g)
current_paragraph->do_para("align=center");
break;
case LEFT:
- current_paragraph->do_para("align=left");
+ current_paragraph->do_para(&html, "align=left", indentation, pageoffset, linelength);
break;
case RIGHT:
- current_paragraph->do_para("align=right");
+ current_paragraph->do_para(&html, "align=right", indentation, pageoffset, linelength);
break;
default:
fatal("unknown enumeration");
@@ -1363,13 +1651,14 @@ void html_printer::emit_raw (text_glob *g)
current_paragraph->done_para();
next_tag = INLINE;
supress_sub_sup = TRUE;
-#if defined(INDENTATION)
- if (in_table) {
- current_paragraph->do_indent(NULL, 0, pageoffset, linelength);
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
+ if (indentation > 0) {
+ /*
+ * restore indentation
+ */
+ int newin = indentation;
+ indentation = 0;
+ do_indent(newin, pageoffset, linelength);
}
-#endif
}
}
@@ -1380,16 +1669,16 @@ void html_printer::emit_raw (text_glob *g)
void html_printer::do_center (char *arg)
{
int n = atoi(arg);
-
current_paragraph->do_break();
- current_paragraph->done_para();
- supress_sub_sup = TRUE;
-
+
if (n > 0) {
+ current_paragraph->done_para();
+ supress_sub_sup = TRUE;
current_paragraph->do_para("align=center");
end_center += n;
} else {
end_center = 0;
+ current_paragraph->remove_para_align();
}
}
@@ -1569,7 +1858,6 @@ void html_printer::write_header (void)
// firstly we must terminate any font and type faces
current_paragraph->done_para();
- current_paragraph->done_table();
supress_sub_sup = TRUE;
if (cutoff_heading+2 > header.header_level) {
@@ -1631,7 +1919,7 @@ void html_printer::write_header (void)
html.put_string(">").nl();
}
- current_paragraph->do_para("");
+ current_paragraph->do_para(&html, "", indentation, pageoffset, linelength);
}
}
@@ -1715,22 +2003,20 @@ int html_printer::is_courier_until_eol (void)
page_contents->glyphs.move_right();
do {
g = page_contents->glyphs.get_data();
- if (! is_font_courier(g->text_style.f)) {
+ if (! g->is_a_tag() && (! is_font_courier(g->text_style.f)))
result = FALSE;
- }
page_contents->glyphs.move_right();
- } while ((result) &&
+ } while (result &&
(! page_contents->glyphs.is_equal_to_head()) &&
- (! g->is_eol()));
+ (! g->is_fi()) && (! g->is_eol()));
/*
* now restore our previous position.
*/
- while (page_contents->glyphs.get_data() != orig) {
+ while (page_contents->glyphs.get_data() != orig)
page_contents->glyphs.move_left();
- }
}
- return( result );
+ return result;
}
/*
@@ -1739,13 +2025,11 @@ int html_printer::is_courier_until_eol (void)
void html_printer::do_linelength (char *arg)
{
-#if defined(INDENTATION)
- if (fill_on) {
- linelength = atoi(arg);
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
- }
-#endif
+ if (max_linelength == -1)
+ max_linelength = atoi(arg);
+
+ if (fill_on)
+ do_indent(indentation, pageoffset, atoi(arg));
}
/*
@@ -1754,13 +2038,8 @@ void html_printer::do_linelength (char *arg)
void html_printer::do_pageoffset (char *arg)
{
-#if defined(INDENTATION)
- pageoffset = atoi(arg);
- if (fill_on) {
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
- }
-#endif
+ if (fill_on)
+ do_indent(indentation, atoi(arg), linelength);
}
/*
@@ -1769,13 +2048,8 @@ void html_printer::do_pageoffset (char *arg)
void html_printer::do_indentation (char *arg)
{
-#if defined(INDENTATION)
- if (fill_on) {
- indentation = atoi(arg);
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
- }
-#endif
+ if (fill_on)
+ do_indent(atoi(arg), pageoffset, linelength);
}
/*
@@ -1784,78 +2058,47 @@ void html_printer::do_indentation (char *arg)
void html_printer::do_tempindent (char *arg)
{
-#if defined(INDENTATION)
if (fill_on) {
end_tempindent = 1;
prev_indent = indentation;
- indentation = atoi(arg);
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
+ do_indent(atoi(arg), pageoffset, linelength);
}
-#endif
}
/*
- * do_indentedparagraph - handle the .ip tag, this buffers the next line
- * and passes this to text-text as the left hand
- * column table entry.
+ * shutdown_table - shuts down the current table.
*/
-void html_printer::do_indentedparagraph (void)
+void html_printer::shutdown_table (void)
{
-#if defined(INDENTATION)
- text_glob *t;
- int removed_from_head;
- int found_indent_start = FALSE;
-
- indent.has_been_found = FALSE;
- indent.text.clear();
+ if (table != NULL) {
+ current_paragraph->done_para();
+ table->emit_finish_table();
+ // dont delete this table as it will be deleted when we destroy the text_glob
+ table = NULL;
+ }
+}
- if (! page_contents->glyphs.is_empty()) {
- page_contents->glyphs.sub_move_right(); /* move onto next word */
- do {
- t = page_contents->glyphs.get_data();
- removed_from_head = FALSE;
- if (t->is_auto_img()) {
- string img = generate_img_src((char *)(t->text_string + 20));
+/*
+ * do_indent - remember the indent parameters and if
+ * indent is > pageoff and indent has changed
+ * then we start a html table to implement the indentation.
+ */
- if (! img.empty()) {
- if (found_indent_start)
- indent.text += " ";
+void html_printer::do_indent (int in, int pageoff, int linelen)
+{
+ if ((indentation != -1) &&
+ (pageoffset+indentation != in+pageoff)) {
+
+ current_paragraph->done_para();
+
+ indentation = in;
+ pageoffset = pageoff;
+ if (linelen <= max_linelength)
+ linelength = linelen;
- found_indent_start = TRUE;
- indent.text += img;
- }
- page_contents->glyphs.sub_move_right(); /* move onto next word */
- } else if (t->is_a_tag() && (strncmp(t->text_string, "html-tag:.br", 12) == 0)) {
- /* end of indented para found, but move back so that we read this tag and process it
- */
- page_contents->glyphs.move_left(); /* move backwards to last word */
- indent.has_been_found = TRUE;
- return;
- } else if (t->is_a_tag()) {
- if (strncmp(t->text_string, "html-tag:.ti", 12) == 0) {
- char *a = (char *)t->text_string+12;
- do_tempindent(a);
- }
- page_contents->glyphs.sub_move_right(); /* move onto next word */
- } else if (found_indent_start) {
- indent.text += " " + string(t->text_string, t->text_length);
- page_contents->glyphs.sub_move_right(); /* move onto next word */
- removed_from_head = ((!page_contents->glyphs.is_empty()) &&
- (page_contents->glyphs.is_equal_to_head()));
- } else {
- indent.text += string(t->text_string, t->text_length);
- found_indent_start = TRUE;
- indent.has_been_found = TRUE;
- page_contents->glyphs.sub_move_right(); /* move onto next word */
- removed_from_head = ((!page_contents->glyphs.is_empty()) &&
- (page_contents->glyphs.is_equal_to_head()));
- }
- } while ((! page_contents->glyphs.is_equal_to_head()) || (removed_from_head));
+ current_paragraph->do_para(&html, "", indentation, pageoffset, max_linelength);
}
- // page_contents->glyphs.move_left(); /* move backwards to last word */
-#endif
}
/*
@@ -1887,13 +2130,12 @@ void html_printer::do_fill (int on)
supress_sub_sup = TRUE;
if (fill_on != on) {
- if (on) {
- current_paragraph->done_pre();
- } else {
+ if (on)
+ current_paragraph->do_para("");
+ else
current_paragraph->do_pre();
- }
+ fill_on = on;
}
- fill_on = on;
}
/*
@@ -1903,12 +2145,20 @@ void html_printer::do_fill (int on)
void html_printer::do_eol (void)
{
if (! fill_on) {
- if (current_paragraph->emitted_text()) {
+ if (current_paragraph->ever_emitted_text()) {
current_paragraph->do_newline();
current_paragraph->do_break();
}
}
output_hpos = indentation+pageoffset;
+}
+
+/*
+ * do_eol_ce - handle end of line specifically for a .ce
+ */
+
+void html_printer::do_eol_ce (void)
+{
if (end_center > 0) {
if (end_center > 1)
if (current_paragraph->emitted_text())
@@ -1929,7 +2179,6 @@ void html_printer::do_eol (void)
void html_printer::do_flush (void)
{
current_paragraph->done_para();
- current_paragraph->done_table();
}
/*
@@ -1939,7 +2188,6 @@ void html_printer::do_flush (void)
void html_printer::do_links (void)
{
current_paragraph->done_para();
- current_paragraph->done_table();
auto_links = FALSE; /* from now on only emit under user request */
file_list.add_new_file(xtmpfile());
html.set_file(file_list.get_file());
@@ -1953,21 +2201,108 @@ void html_printer::do_links (void)
void html_printer::do_break (void)
{
current_paragraph->do_break();
-#if defined(INDENTATION)
if (end_tempindent > 0) {
end_tempindent--;
- if (end_tempindent == 0) {
- indentation = prev_indent;
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
- }
+ if (end_tempindent == 0)
+ do_indent(prev_indent, pageoffset, linelength);
}
-#endif
output_hpos = indentation+pageoffset;
supress_sub_sup = TRUE;
}
/*
+ * do_tab_ts - start a table, which will have already been defined.
+ */
+
+void html_printer::do_tab_ts (text_glob *g)
+{
+ html_table *t = g->get_table();
+
+ if (t != NULL) {
+ int need_space = ((! current_paragraph->ever_emitted_text()) &&
+ current_paragraph->starts_with_space());
+
+ current_paragraph->done_pre();
+ current_paragraph->done_para();
+
+ html.simple_comment("TABS");
+ t->set_linelength(max_linelength);
+ t->add_indent(pageoffset);
+ t->emit_table_header(need_space);
+ }
+
+ table = t;
+}
+
+/*
+ * do_tab_te - finish a table.
+ */
+
+void html_printer::do_tab_te (void)
+{
+ if (table) {
+ current_paragraph->done_para();
+ table->emit_finish_table();
+ }
+
+ table = NULL;
+
+ if (indentation > 0) {
+ /*
+ * restore indentation
+ */
+ int newin = indentation;
+ indentation = 0;
+ do_indent(newin, pageoffset, linelength);
+ }
+}
+
+/*
+ * do_tab - handle the "html-tag:tab" tag
+ */
+
+void html_printer::do_tab (char *s)
+{
+ if (table) {
+ while (isspace(*s))
+ s++;
+ s++;
+ int col = table->find_column(atoi(s) + pageoffset + indentation);
+ if (col > 0) {
+ current_paragraph->done_para();
+ table->emit_col(col);
+ }
+ }
+}
+
+/*
+ * do_tab0 - handle the "html-tag:tab0" tag
+ */
+
+void html_printer::do_tab0 (void)
+{
+ if (table) {
+ int col = table->find_column(pageoffset+indentation);
+ if (col > 0) {
+ current_paragraph->done_para();
+ table->emit_col(col);
+ }
+ }
+}
+
+/*
+ * do_col - start column, s.
+ */
+
+void html_printer::do_col (char *s)
+{
+ if (table) {
+ current_paragraph->done_para();
+ table->emit_col(atoi(s));
+ }
+}
+
+/*
* troff_tag - processes the troff tag and manipulates the troff state machine.
*/
@@ -1981,9 +2316,12 @@ void html_printer::troff_tag (text_glob *g)
if (g->is_eol()) {
do_eol();
} else if (g->is_eol_ce()) {
- do_eol();
+ do_eol_ce();
} else if (strncmp(t, ".sp", 3) == 0) {
- current_paragraph->do_space();
+ if (g->get_arg() > 0)
+ current_paragraph->do_space();
+ else
+ current_paragraph->do_break();
supress_sub_sup = TRUE;
} else if (strncmp(t, ".br", 3) == 0) {
do_break();
@@ -2030,12 +2368,22 @@ void html_printer::troff_tag (text_glob *g)
} else if (strncmp(t, ".vs", 3) == 0) {
char *a = (char *)t+3;
do_verticalspacing(a);
- } else if (strncmp(t, ".ip", 3) == 0) {
- do_indentedparagraph();
} else if (strcmp(t, ".links") == 0) {
do_links();
} else if (strcmp(t, ".no-auto-rule") == 0) {
auto_rule = FALSE;
+ } else if (strcmp(t, ".tab-ts") == 0) {
+ do_tab_ts(g);
+ } else if (strcmp(t, ".tab-te") == 0) {
+ do_tab_te();
+ } else if (strncmp(t, ".col ", 5) == 0) {
+ char *a = (char *)t+4;
+ do_col(a);
+ } else if (strncmp(t, "tab ", 4) == 0) {
+ char *a = (char *)t+3;
+ do_tab(a);
+ } else if (strncmp(t, "tab0", 4) == 0) {
+ do_tab0();
}
}
@@ -2061,9 +2409,8 @@ void html_printer::flush_globs (void)
do {
g = page_contents->glyphs.get_data();
- if (strcmp(g->text_string, "XXXXXXX") == 0) {
+ if (strcmp(g->text_string, "XXXXXXX") == 0)
stop();
- }
if (g->is_a_tag()) {
troff_tag(g);
@@ -2082,14 +2429,425 @@ void html_printer::flush_globs (void)
}
}
+/*
+ * calc_nf - calculates the _no_ format flag, given the
+ * text glob, g.
+ */
+
+int html_printer::calc_nf (text_glob *g, int nf)
+{
+ if (g->is_fi())
+ return FALSE;
+ if (g->is_nf())
+ return TRUE;
+ return nf;
+}
+
+/*
+ * calc_po_in - calculates the, in, po, registers
+ */
+
+void html_printer::calc_po_in (text_glob *g, int nf)
+{
+ if (g->is_in())
+ indentation = g->get_arg();
+ else if (g->is_po())
+ pageoffset = g->get_arg();
+ else if (g->is_ti()) {
+ prev_indent = indentation;
+ indentation = g->get_arg();
+ end_tempindent = 1;
+ } else if (g->is_br() && ((end_tempindent > 0) || (nf && g->is_eol()))) {
+ end_tempindent = 0;
+ indentation = prev_indent;
+ }
+}
+
+/*
+ * next_horiz_pos - returns the next horiz position.
+ * -1 is returned if it doesn't exist.
+ */
+
+int html_printer::next_horiz_pos (int nf)
+{
+ int next = -1;
+ text_glob *g = page_contents->glyphs.get_data();
+
+ if (g->is_br() || (nf && g->is_eol()))
+ if (! page_contents->glyphs.is_empty()) {
+ page_contents->glyphs.move_right();
+ next = g->minh;
+ page_contents->glyphs.move_left();
+ }
+ return next;
+}
+
+/*
+ * insert_tab_ts - inserts a tab-ts before, where.
+ */
+
+text_glob *html_printer::insert_tab_ts (text_glob *where)
+{
+ text_glob *start_of_table;
+ text_glob *old_pos = page_contents->glyphs.get_data();
+
+ page_contents->glyphs.move_to(where);
+ page_contents->glyphs.move_left();
+ page_contents->insert_tag(string("html-tag:.tab-ts")); // tab table start
+ page_contents->glyphs.move_right();
+ start_of_table = page_contents->glyphs.get_data();
+ page_contents->glyphs.move_to(old_pos);
+ return start_of_table;
+}
+
+/*
+ * insert_tab_te - inserts a tab-te before the current position
+ * (it skips backwards over .sp/.br)
+ */
+
+void html_printer::insert_tab_te (void)
+{
+ text_glob *g = page_contents->glyphs.get_data();
+ page_contents->dump_page();
+
+ while (page_contents->glyphs.get_data()->is_a_tag())
+ page_contents->glyphs.move_left();
+
+ page_contents->insert_tag(string("html-tag:.tab-te")); // tab table end
+ while (g != page_contents->glyphs.get_data())
+ page_contents->glyphs.move_right();
+ page_contents->dump_page();
+}
+
+/*
+ * insert_tab_0 - inserts a tab0 before, where.
+ */
+
+void html_printer::insert_tab_0 (text_glob *where)
+{
+ text_glob *old_pos = page_contents->glyphs.get_data();
+
+ page_contents->glyphs.move_to(where);
+ page_contents->glyphs.move_left();
+ page_contents->insert_tag(string("html-tag:tab0")); // tab0 start of line
+ page_contents->glyphs.move_right();
+ page_contents->glyphs.move_to(old_pos);
+}
+
+/*
+ * remove_tabs - removes the tabs tags on this line.
+ */
+
+void html_printer::remove_tabs (void)
+{
+ text_glob *orig = page_contents->glyphs.get_data();
+ text_glob *g;
+
+ if (! page_contents->glyphs.is_equal_to_tail()) {
+ do {
+ g = page_contents->glyphs.get_data();
+ if (g->is_tab()) {
+ page_contents->glyphs.sub_move_right();
+ if (g == orig)
+ orig = page_contents->glyphs.get_data();
+ } else
+ page_contents->glyphs.move_right();
+ } while ((! page_contents->glyphs.is_equal_to_head()) &&
+ (! g->is_eol()));
+
+ /*
+ * now restore our previous position.
+ */
+ while (page_contents->glyphs.get_data() != orig)
+ page_contents->glyphs.move_left();
+ }
+}
+
+void html_printer::remove_courier_tabs (void)
+{
+ text_glob *g;
+ int line_start = TRUE;
+ int nf = FALSE;
+
+ if (! page_contents->glyphs.is_empty()) {
+ page_contents->glyphs.start_from_head();
+ line_start = TRUE;
+ do {
+ g = page_contents->glyphs.get_data();
+
+ nf = calc_nf(g, nf);
+
+ if (line_start) {
+ if (line_start && nf && is_courier_until_eol()) {
+ remove_tabs();
+ g = page_contents->glyphs.get_data();
+ }
+ }
+
+ line_start = g->is_br() || g->is_nf() || g->is_fi() || (nf && g->is_eol());
+ page_contents->glyphs.move_right();
+ } while (! page_contents->glyphs.is_equal_to_head());
+ }
+}
+
+void html_printer::insert_tab0_foreach_tab (void)
+{
+ text_glob *start_of_line = NULL;
+ text_glob *g = NULL;
+ int seen_tab = FALSE;
+ int seen_col = FALSE;
+ int nf = FALSE;
+
+ if (! page_contents->glyphs.is_empty()) {
+ page_contents->glyphs.start_from_head();
+ start_of_line = page_contents->glyphs.get_data();
+ do {
+ g = page_contents->glyphs.get_data();
+
+ nf = calc_nf(g, nf);
+
+ if (g->is_tab())
+ seen_tab = TRUE;
+
+ if (g->is_col())
+ seen_col = TRUE;
+
+ if (g->is_br() || (nf && g->is_eol())) {
+ do {
+ page_contents->glyphs.move_right();
+ g = page_contents->glyphs.get_data();
+ nf = calc_nf(g, nf);
+ if (page_contents->glyphs.is_equal_to_head()) {
+ if (seen_tab && !seen_col)
+ insert_tab_0(start_of_line);
+ return;
+ }
+ } while (g->is_br() || (nf && g->is_eol()) || g->is_ta());
+ // printf("\nstart_of_line is: %s\n", g->text_string);
+ if (seen_tab && !seen_col) {
+ insert_tab_0(start_of_line);
+ page_contents->glyphs.move_to(g);
+ }
+
+ seen_tab = FALSE;
+ seen_col = FALSE;
+ start_of_line = g;
+ }
+ page_contents->glyphs.move_right();
+ } while (! page_contents->glyphs.is_equal_to_head());
+ if (seen_tab && !seen_col)
+ insert_tab_0(start_of_line);
+
+ }
+}
+
+/*
+ * lookahead_for_tables - checks for .col tags and inserts table start/end tags
+ */
+
+void html_printer::lookahead_for_tables (void)
+{
+ text_glob *g;
+ text_glob *start_of_line = NULL;
+ text_glob *start_of_table = NULL;
+ text_glob *last = NULL;
+ enum {col_tag, tab_tag, tab0_tag, none} type_of_col = none;
+ int left = 0;
+ int found_col = FALSE;
+ int seen_text = FALSE;
+ int ncol = 0;
+ int colmin;
+ int colmax;
+ html_table *table = new html_table(&html, -1);
+ const char *tab_defs = NULL;
+ char align = 'L';
+ int nf = FALSE;
+
+ remove_courier_tabs();
+ page_contents->dump_page();
+ insert_tab0_foreach_tab();
+ page_contents->dump_page();
+ if (! page_contents->glyphs.is_empty()) {
+ page_contents->glyphs.start_from_head();
+ g = page_contents->glyphs.get_data();
+ do {
+#if 0
+ if (strcmp(g->text_string, "XXXXXXX") == 0)
+ stop();
+#endif
+
+ nf = calc_nf(g, nf);
+ calc_po_in(g, nf);
+ if (g->is_col()) {
+ if (type_of_col == tab_tag && start_of_table != NULL) {
+ page_contents->glyphs.move_left();
+ insert_tab_te();
+ start_of_table->remember_table(table);
+ table = new html_table(&html, -1);
+ page_contents->insert_tag(string("*** TAB -> COL ***"));
+ if (tab_defs != NULL)
+ table->tab_stops->init(tab_defs);
+ start_of_table = NULL;
+ last = NULL;
+ }
+ type_of_col = col_tag;
+ found_col = TRUE;
+ ncol = g->get_arg();
+ align = 'L';
+ colmin = 0;
+ colmax = 0;
+ } else if (g->is_tab()) {
+ type_of_col = tab_tag;
+ colmin = g->get_tab_args(&align);
+ align = 'L'; // for now as 'C' and 'R' are broken
+ ncol = table->find_tab_column(colmin);
+ colmin += pageoffset + indentation;
+ colmax = table->get_tab_pos(ncol+1);
+ if (colmax > 0)
+ colmax += pageoffset + indentation;
+ } else if (g->is_tab0()) {
+ if (type_of_col == col_tag && start_of_table != NULL) {
+ page_contents->glyphs.move_left();
+ insert_tab_te();
+ start_of_table->remember_table(table);
+ table = new html_table(&html, -1);
+ page_contents->insert_tag(string("*** COL -> TAB ***"));
+ start_of_table = NULL;
+ last = NULL;
+ }
+ if (tab_defs != NULL)
+ table->tab_stops->init(tab_defs);
+
+ type_of_col = tab0_tag;
+ ncol = 1;
+ colmin = 0;
+ colmax = table->get_tab_pos(2) + pageoffset + indentation;
+ } else if (! g->is_a_tag()) {
+ switch (type_of_col) {
+
+ case tab_tag:
+ break;
+ case tab0_tag:
+ colmin = g->minh;
+ break;
+ case col_tag:
+ colmin = g->minh;
+ colmax = g->maxh;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((! g->is_a_tag()) || g->is_tab())
+ seen_text = TRUE;
+
+ if ((g->is_col() || g->is_tab() || g->is_tab0())
+ && (start_of_line != NULL) && (start_of_table == NULL)) {
+ start_of_table = insert_tab_ts(start_of_line);
+ start_of_line = NULL;
+ seen_text = FALSE;
+ } else if (g->is_ce() && (start_of_table != NULL)) {
+ page_contents->glyphs.move_left();
+ insert_tab_te();
+ start_of_table->remember_table(table);
+ page_contents->insert_tag(string("*** CE ***"));
+ start_of_table = NULL;
+ last = NULL;
+ } else if (g->is_ta()) {
+ tab_defs = g->text_string;
+ if (!table->tab_stops->compatible(tab_defs)) {
+ if (start_of_table != NULL) {
+ page_contents->glyphs.move_left();
+ insert_tab_te();
+ start_of_table->remember_table(table);
+ table = new html_table(&html, -1);
+ page_contents->insert_tag(string("*** TABS ***"));
+ start_of_table = NULL;
+ type_of_col = none;
+ last = NULL;
+ }
+ table->tab_stops->init(tab_defs);
+ }
+ }
+
+ if (((! g->is_a_tag()) || g->is_tab()) && (start_of_table != NULL)) {
+ // we are in a table and have a glyph
+ if ((ncol == 0) || (! table->add_column(ncol, colmin, colmax, align))) {
+ page_contents->glyphs.move_left();
+ insert_tab_te();
+#if defined(DEBUG_TABLES)
+ if (ncol == 0)
+ page_contents->insert_tag(string("*** NCOL == 0 ***"));
+ else
+ page_contents->insert_tag(string("*** CROSSED COLS ***"));
+#endif
+ start_of_table->remember_table(table);
+ table = new html_table(&html, -1);
+ start_of_table = NULL;
+ type_of_col = none;
+ last = NULL;
+ }
+ }
+
+ /*
+ * move onto next glob, check whether we are starting a new line
+ */
+ page_contents->glyphs.move_right();
+ g = page_contents->glyphs.get_data();
+
+#if defined(DEBUG_TABLES)
+ if (g->is_in() && (!seen_text))
+ html.simple_comment("IGNORE .in");
+ else
+#endif
+ if (g->is_br_ni() || (nf && g->is_eol())) {
+ do {
+ page_contents->glyphs.move_right();
+ g = page_contents->glyphs.get_data();
+ nf = calc_nf(g, nf);
+ } while (g->is_br_ni() || (nf && g->is_eol()));
+ start_of_line = g;
+ seen_text = FALSE;
+ ncol = 0;
+ left = next_horiz_pos(nf);
+ if (found_col)
+ last = g;
+ found_col = FALSE;
+ }
+ } while (! page_contents->glyphs.is_equal_to_head());
+ if (start_of_table != NULL) {
+ if (last != NULL)
+ while (last != page_contents->glyphs.get_data())
+ page_contents->glyphs.move_left();
+
+ insert_tab_te();
+ start_of_table->remember_table(table);
+ table = NULL;
+ page_contents->insert_tag(string("*** LAST ***"));
+ }
+ }
+ if (table != NULL)
+ delete table;
+
+ // and reset the registers
+ pageoffset = 0;
+ pageoffset = 0;
+ indentation = 0;
+ prev_indent = 0;
+ end_tempindent = 0;
+}
+
void html_printer::flush_page (void)
{
supress_sub_sup = TRUE;
flush_sbuf();
- // page_contents->dump_page();
+ page_contents->dump_page();
+ lookahead_for_tables();
+ page_contents->dump_page();
+
flush_globs();
current_paragraph->done_para();
- current_paragraph->done_table();
// move onto a new page
delete page_contents;
@@ -2443,10 +3201,13 @@ html_printer::html_printer()
header_indent(-1),
supress_sub_sup(TRUE),
cutoff_heading(100),
+ indent(NULL),
+ table(NULL),
end_center(0),
end_tempindent(0),
next_tag(INLINE),
fill_on(TRUE),
+ max_linelength(-1),
linelength(0),
pageoffset(0),
indentation(0),
@@ -2489,7 +3250,7 @@ html_printer::html_printer()
void html_printer::add_to_sbuf (unsigned char code, const string &s)
{
- char *html_glyph;
+ char *html_glyph = NULL;
if (s.empty()) {
html_glyph = get_html_translation(sbuf_style.f, string(code));
@@ -2678,10 +3439,7 @@ void html_printer::begin_page(int n)
output_vpos = -1;
output_vpos_max = -1;
current_paragraph = new html_text(&html);
-#if defined(INDENTATION)
- current_paragraph->do_indent(page_contents->buffer.add_string(indent.text), indentation, pageoffset, linelength);
- indent.text.clear();
-#endif
+ do_indent(indentation, pageoffset, linelength);
current_paragraph->do_para("");
}
diff --git a/src/preproc/grn/grn.man b/src/preproc/grn/grn.man
index 7c885f1f..ca1703bc 100644
--- a/src/preproc/grn/grn.man
+++ b/src/preproc/grn/grn.man
@@ -408,7 +408,6 @@ format is the use of names for picture objects (e.g., POLYGON, CURVE)
instead of numbers.
Files representing the same picture are shown in Table 1 in each format.
.sp
-.DS
.TS
center, tab(@);
l lw(0.1i) l.
@@ -435,7 +434,6 @@ css.
.sp
Table 1. File examples
.TE
-.DE
.sp
.IP \(bu
The first line of each
@@ -491,7 +489,6 @@ version) or its ASCII name
version).
See Table 2.
.sp
-.DS
.TS
center, tab(@);
css
@@ -519,7 +516,6 @@ css.
Table 2.
Type Specifications in \fIgremlin\fP Files
.TE
-.DE
.sp
.IP \(bu
After the object type comes a variable number of lines, each specifying a
@@ -538,7 +534,6 @@ brush and size for the element.
The brush determines the style in which things are drawn.
For vectors, arcs, and curves there are six legal brush values:
.sp
-.DS
.TS
center, tab(@);
ncw(0.1i)l.
@@ -549,13 +544,11 @@ ncw(0.1i)l.
5 \(mi@@thin solid lines
6 \(mi@@medium solid lines
.TE
-.DE
.sp
For polygons, one more value, 0, is legal.
It specifies a polygon with an invisible border.
For text, the brush selects a font as follows:
.sp
-.DS
.TS
center, tab(@);
ncw(0.1i)l.
@@ -564,7 +557,6 @@ ncw(0.1i)l.
3 \(mi@@bold (B font in groff)
4 \(mi@@special (S font in groff)
.TE
-.DE
.sp
If you're using
.I @g@grn
@@ -572,9 +564,9 @@ to run your pictures through
.IR groff ,
the font is really just a starting font:
The text string can contain formatting sequences like
-``\\fI''
+``\efI''
or
-``\\d''
+``\ed''
which may change the font (as well as do many other things).
For text, the size field is a decimal value between 1 and 4.
It selects the size of the font in which the text will be drawn.
diff --git a/src/roff/troff/div.cc b/src/roff/troff/div.cc
index 718fde32..14c73997 100644
--- a/src/roff/troff/div.cc
+++ b/src/roff/troff/div.cc
@@ -641,7 +641,7 @@ void page_offset()
n = topdiv->prev_page_offset;
topdiv->prev_page_offset = topdiv->page_offset;
topdiv->page_offset = n;
- curenv->add_html_tag(".po", n.to_units());
+ curenv->add_html_tag(0, ".po", n.to_units());
skip_line();
}
@@ -760,7 +760,7 @@ void space_request()
else
// The line might have had line spacing that was truncated.
truncated_space += n;
- curenv->add_html_tag(".sp", n.to_units());
+ curenv->add_html_tag(1, ".sp", n.to_units());
tok.next();
}
@@ -769,7 +769,7 @@ void blank_line()
curenv->do_break();
if (!trap_sprung_flag && !curdiv->no_space_mode) {
curdiv->space(curenv->get_vertical_spacing());
- curenv->add_html_tag(".sp", 1);
+ curenv->add_html_tag(1, ".sp", 1);
} else
truncated_space += curenv->get_vertical_spacing();
}
@@ -833,7 +833,7 @@ void flush_output()
curenv->do_break();
if (the_output)
the_output->flush();
- curenv->add_html_tag(".fl");
+ curenv->add_html_tag(1, ".fl");
tok.next();
}
diff --git a/src/roff/troff/env.cc b/src/roff/troff/env.cc
index 57630c92..ed783d46 100644
--- a/src/roff/troff/env.cc
+++ b/src/roff/troff/env.cc
@@ -31,6 +31,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "reg.h"
#include "charinfo.h"
#include "macropath.h"
+#include "input.h"
#include <math.h>
symbol default_family("T");
@@ -299,7 +300,8 @@ node *environment::make_char_node(charinfo *ci)
void environment::add_node(node *n)
{
- assert(n != 0);
+ if (n == 0)
+ return;
if (current_tab || current_field)
n->freeze_space();
if (interrupted) {
@@ -1161,7 +1163,7 @@ void point_size()
if (n <= 0)
n = 1;
curenv->set_size(n);
- curenv->add_html_tag(".ps", n);
+ curenv->add_html_tag(1, ".ps", n);
}
else
curenv->set_size(0);
@@ -1229,7 +1231,8 @@ void fill()
if (break_flag)
curenv->do_break();
curenv->fill = 1;
- curenv->add_html_tag(".fi");
+ curenv->add_html_tag(1, ".fi");
+ curenv->add_html_tag(0, ".br");
tok.next();
}
@@ -1240,8 +1243,9 @@ void no_fill()
if (break_flag)
curenv->do_break();
curenv->fill = 0;
- curenv->add_html_tag(".nf");
- curenv->add_html_tag(".po", topdiv->get_page_offset().to_units());
+ curenv->add_html_tag(1, ".nf");
+ curenv->add_html_tag(0, ".br");
+ curenv->add_html_tag(0, ".po", topdiv->get_page_offset().to_units());
tok.next();
}
@@ -1258,7 +1262,7 @@ void center()
curenv->do_break();
curenv->right_justify_lines = 0;
curenv->center_lines = n;
- curenv->add_html_tag(".ce", n);
+ curenv->add_html_tag(1, ".ce", n);
tok.next();
}
@@ -1275,7 +1279,7 @@ void right_justify()
curenv->do_break();
curenv->center_lines = 0;
curenv->right_justify_lines = n;
- curenv->add_html_tag(".rj", n);
+ curenv->add_html_tag(1, ".rj", n);
tok.next();
}
@@ -1292,7 +1296,7 @@ void line_length()
temp = curenv->prev_line_length;
curenv->prev_line_length = curenv->line_length;
curenv->line_length = temp;
- curenv->add_html_tag(".ll", temp.to_units());
+ curenv->add_html_tag(1, ".ll", temp.to_units());
skip_line();
}
@@ -1379,7 +1383,7 @@ void indent()
curenv->have_temporary_indent = 0;
curenv->prev_indent = curenv->indent;
curenv->indent = temp;
- curenv->add_html_tag(".in", temp.to_units());
+ curenv->add_html_tag(1, ".in", temp.to_units());
tok.next();
}
@@ -1400,7 +1404,7 @@ void temporary_indent()
if (!err) {
curenv->temporary_indent = temp;
curenv->have_temporary_indent = 1;
- curenv->add_html_tag(".ti", temp.to_units());
+ curenv->add_html_tag(1, ".ti", temp.to_units());
}
tok.next();
}
@@ -1654,8 +1658,12 @@ void environment::newline()
hunits x = target_text_length - width_total;
if (x > H0)
saved_indent += x/2;
- add_html_tag("eol.ce");
to_be_output = line;
+ if (is_html) {
+ node *n = make_html_tag("eol.ce");
+ n->next = to_be_output;
+ to_be_output = n;
+ }
to_be_output_width = width_total;
line = 0;
}
@@ -1677,6 +1685,14 @@ void environment::newline()
}
input_line_start = line == 0 ? H0 : width_total;
if (to_be_output) {
+ if (is_html && !fill) {
+ if (curdiv == topdiv) {
+ node *n = make_html_tag("eol");
+
+ n->next = to_be_output;
+ to_be_output = n;
+ }
+ }
output_line(to_be_output, to_be_output_width);
hyphen_line_count = 0;
}
@@ -2119,29 +2135,15 @@ void environment::final_break()
}
/*
- * add_html_tag_eol - add an end of line tag if appropriate.
- */
-
-void environment::add_html_tag_eol()
-{
- if (is_html) {
- if (ignore_next_eol > 0)
- ignore_next_eol--;
- else
- if (!fill && emitted_node) {
- add_html_tag("eol");
- emitted_node = 0;
- }
- }
-}
-
-/*
* add_html_tag - emits a special html-tag: to help post-grohtml understand
* the key troff commands
*/
-void environment::add_html_tag(const char *name)
+void environment::add_html_tag(int force, const char *name)
{
+ if (!force && (curdiv != topdiv))
+ return;
+
if (is_html) {
/*
* need to emit tag for post-grohtml
@@ -2154,7 +2156,7 @@ void environment::add_html_tag(const char *name)
for (const char *p = name; *p; p++)
if (!invalid_input_char((unsigned char)*p))
m->append(*p);
- add_node(new special_node(*m));
+ curdiv->output(new special_node(*m), 1, 0, 0, 0);
if (strcmp(name, ".nf") == 0)
curenv->ignore_next_eol = 1;
}
@@ -2166,8 +2168,11 @@ void environment::add_html_tag(const char *name)
* of i.
*/
-void environment::add_html_tag(const char *name, int i)
+void environment::add_html_tag(int force, const char *name, int i)
{
+ if (!force && (curdiv != topdiv))
+ return;
+
if (is_html) {
/*
* need to emit tag for post-grohtml
@@ -2182,9 +2187,8 @@ void environment::add_html_tag(const char *name, int i)
m->append(*p);
m->append(' ');
m->append_int(i);
- // output_pending_lines();
- output(new special_node(*m), !fill, 0, 0, 0);
- // output_pending_lines();
+ node *n = new special_node(*m);
+ curdiv->output(n, 1, 0, 0, 0);
}
}
@@ -2192,8 +2196,11 @@ void environment::add_html_tag(const char *name, int i)
* add_html_tag_tabs - emits the tab settings for post-grohtml
*/
-void environment::add_html_tag_tabs()
+void environment::add_html_tag_tabs(int force)
{
+ if (!force && (curdiv != topdiv))
+ return;
+
if (is_html) {
/*
* need to emit tag for post-grohtml
@@ -2211,26 +2218,64 @@ void environment::add_html_tag_tabs()
switch (t) {
case TAB_LEFT:
m->append_str(" L ");
- m->append_int(d.to_units());
+ m->append_int(l.to_units());
break;
case TAB_CENTER:
m->append_str(" C ");
- m->append_int(d.to_units());
+ m->append_int(l.to_units());
break;
case TAB_RIGHT:
m->append_str(" R ");
- m->append_int(d.to_units());
+ m->append_int(l.to_units());
break;
case TAB_NONE:
break;
}
} while ((t != TAB_NONE) && (l < get_line_length()));
- output_pending_lines();
- output(new special_node(*m), !fill, 0, 0, 0);
- output_pending_lines();
+ curdiv->output(new special_node(*m), 1, 0, 0, 0);
}
}
+node *environment::make_html_tag(const char *name, int i)
+{
+ if (is_html) {
+ /*
+ * need to emit tag for post-grohtml
+ * but we check to see whether we can emit specials
+ */
+ if (curdiv == topdiv && topdiv->before_first_page)
+ topdiv->begin_page();
+ macro *m = new macro;
+ m->append_str("html-tag:");
+ for (const char *p = name; *p; p++)
+ if (!invalid_input_char((unsigned char)*p))
+ m->append(*p);
+ m->append(' ');
+ m->append_int(i);
+ return new special_node(*m);
+ }
+ return 0;
+}
+
+node *environment::make_html_tag(const char *name)
+{
+ if (is_html) {
+ /*
+ * need to emit tag for post-grohtml
+ * but we check to see whether we can emit specials
+ */
+ if (curdiv == topdiv && topdiv->before_first_page)
+ topdiv->begin_page();
+ macro *m = new macro;
+ m->append_str("html-tag:");
+ for (const char *p = name; *p; p++)
+ if (!invalid_input_char((unsigned char)*p))
+ m->append(*p);
+ return new special_node(*m);
+ }
+ return 0;
+}
+
void environment::do_break(int spread)
{
if (curdiv == topdiv && topdiv->before_first_page) {
@@ -2287,7 +2332,7 @@ void do_break_request(int spread)
tok.next();
if (break_flag) {
curenv->do_break(spread);
- curenv->add_html_tag(".br");
+ curenv->add_html_tag(0, ".br");
}
tok.next();
}
@@ -2491,12 +2536,21 @@ tab_stops::~tab_stops()
tab_type tab_stops::distance_to_next_tab(hunits curpos, hunits *distance)
{
+ hunits nextpos;
+
+ return distance_to_next_tab(curpos, distance, &nextpos);
+}
+
+tab_type tab_stops::distance_to_next_tab(hunits curpos, hunits *distance,
+ hunits *nextpos)
+{
hunits lastpos = 0;
tab *tem;
for (tem = initial_list; tem && tem->pos <= curpos; tem = tem->next)
lastpos = tem->pos;
if (tem) {
*distance = tem->pos - curpos;
+ *nextpos = tem->pos;
return tem->type;
}
if (repeated_list == 0)
@@ -2507,6 +2561,7 @@ tab_type tab_stops::distance_to_next_tab(hunits curpos, hunits *distance)
lastpos = tem->pos;
if (tem) {
*distance = tem->pos + base - curpos;
+ *nextpos = tem->pos + base;
return tem->type;
}
assert(lastpos > 0);
@@ -2681,7 +2736,7 @@ void set_tabs()
}
}
curenv->tabs = tabs;
- curenv->add_html_tag_tabs();
+ curenv->add_html_tag_tabs(1);
skip_line();
}
@@ -2713,6 +2768,14 @@ tab_type environment::distance_to_next_tab(hunits *distance)
: curenv->tabs.distance_to_next_tab(get_input_line_position(), distance);
}
+tab_type environment::distance_to_next_tab(hunits *distance, hunits *leftpos)
+{
+ return line_tabs
+ ? curenv->tabs.distance_to_next_tab(get_text_length(), distance, leftpos)
+ : curenv->tabs.distance_to_next_tab(get_input_line_position(), distance,
+ leftpos);
+}
+
void field_characters()
{
field_delimiter_char = get_optional_char();
@@ -2800,31 +2863,34 @@ node *environment::make_tab_node(hunits d, node *next)
void environment::handle_tab(int is_leader)
{
hunits d;
+ hunits abs;
if (current_tab)
wrap_up_tab();
charinfo *ci = is_leader ? leader_char : tab_char;
delete leader_node;
leader_node = ci ? make_char_node(ci) : 0;
- tab_type t = distance_to_next_tab(&d);
+ tab_type t = distance_to_next_tab(&d, &abs);
switch (t) {
case TAB_NONE:
return;
case TAB_LEFT:
- add_html_tag("tab left");
add_node(make_tab_node(d));
+ add_node(make_html_tag("tab L", abs.to_units()));
return;
case TAB_RIGHT:
+ add_node(make_html_tag("tab R", abs.to_units()));
+ break;
case TAB_CENTER:
- add_html_tag("tab center");
- tab_width = 0;
- tab_distance = d;
- tab_contents = 0;
- current_tab = t;
- tab_field_spaces = 0;
- return;
+ add_node(make_html_tag("tab C", abs.to_units()));
+ break;
default:
assert(0);
}
+ tab_width = 0;
+ tab_distance = d;
+ tab_contents = 0;
+ current_tab = t;
+ tab_field_spaces = 0;
}
void environment::start_field()
diff --git a/src/roff/troff/env.h b/src/roff/troff/env.h
index 1c694916..5d69b119 100644
--- a/src/roff/troff/env.h
+++ b/src/roff/troff/env.h
@@ -85,6 +85,7 @@ public:
~tab_stops();
void operator=(const tab_stops &);
tab_type distance_to_next_tab(hunits pos, hunits *distance);
+ tab_type distance_to_next_tab(hunits curpos, hunits *distance, hunits *leftpos);
void clear();
void add_tab(hunits pos, tab_type type, int repeated);
const char *to_string();
@@ -190,6 +191,7 @@ class environment {
color *prev_fill_color;
tab_type distance_to_next_tab(hunits *);
+ tab_type distance_to_next_tab(hunits *distance, hunits *leftpos);
void start_line();
void output_line(node *, hunits);
void output(node *nd, int retain_size, vunits vs, vunits post_vs,
@@ -287,10 +289,11 @@ public:
void possibly_break_line(int start_here = 0, int forced = 0);
void do_break(int spread = 0); // .br
void final_break();
- void add_html_tag_eol();
- void add_html_tag(const char *);
- void add_html_tag(const char *, int);
- void add_html_tag_tabs();
+ void add_html_tag(int, const char *);
+ void add_html_tag(int, const char *, int);
+ void add_html_tag_tabs(int);
+ node *make_html_tag(const char *name, int i);
+ node *make_html_tag(const char *);
void newline();
void handle_tab(int is_leader = 0); // do a tab or leader
void add_node(node *);
diff --git a/src/roff/troff/input.cc b/src/roff/troff/input.cc
index 0b55133f..0dfa0e01 100644
--- a/src/roff/troff/input.cc
+++ b/src/roff/troff/input.cc
@@ -260,7 +260,6 @@ class file_iterator : public input_iterator {
const char *filename;
int popened;
int newline_flag;
- int suppress_newline_flag; // used by html
int seen_escape;
enum { BUF_SIZE = 512 };
unsigned char buf[BUF_SIZE];
@@ -279,7 +278,7 @@ public:
file_iterator::file_iterator(FILE *f, const char *fn, int po)
: fp(f), lineno(1), filename(fn), popened(po),
- newline_flag(0), suppress_newline_flag(0), seen_escape(0)
+ newline_flag(0), seen_escape(0)
{
if ((font::use_charnames_in_special) && (fn != 0)) {
if (!the_output)
@@ -317,7 +316,6 @@ int file_iterator::next_file(FILE *f, const char *s)
fp = f;
lineno = 1;
newline_flag = 0;
- suppress_newline_flag = 0;
seen_escape = 0;
popened = 0;
ptr = 0;
@@ -327,12 +325,9 @@ int file_iterator::next_file(FILE *f, const char *s)
int file_iterator::fill(node **)
{
- if (newline_flag && !suppress_newline_flag) {
- curenv->add_html_tag_eol();
+ if (newline_flag)
lineno++;
- }
newline_flag = 0;
- suppress_newline_flag = 0;
unsigned char *p = buf;
ptr = p;
unsigned char *e = p + BUF_SIZE;
@@ -345,8 +340,6 @@ int file_iterator::fill(node **)
else {
*p++ = c;
if (c == '\n') {
- if (seen_escape && is_html)
- suppress_newline_flag = 1;
seen_escape = 0;
newline_flag = 1;
break;
@@ -3105,7 +3098,6 @@ class string_iterator : public input_iterator {
macro mac;
const char *how_invoked;
int newline_flag;
- int suppress_newline_flag; // used by html
int lineno;
char_block *bp;
int count; // of characters remaining
@@ -3126,7 +3118,7 @@ public:
string_iterator::string_iterator(const macro &m, const char *p, symbol s)
: mac(m), how_invoked(p),
- newline_flag(0), suppress_newline_flag(0), lineno(1), nm(s)
+ newline_flag(0), lineno(1), nm(s)
{
count = mac.len;
if (count != 0) {
@@ -3147,7 +3139,6 @@ string_iterator::string_iterator()
nd = 0;
ptr = eptr = 0;
newline_flag = 0;
- suppress_newline_flag = 0;
how_invoked = 0;
lineno = 1;
count = 0;
@@ -3181,8 +3172,6 @@ int string_iterator::fill(node **np)
unsigned char c = *p;
if (c == '\n' || c == ESCAPE_NEWLINE) {
newline_flag = 1;
- if (is_html && c == ESCAPE_NEWLINE)
- suppress_newline_flag = 1;
p++;
break;
}
@@ -4904,34 +4893,6 @@ static node *do_suppress(symbol nm)
break;
case '3':
begin_level++;
-#if 0
- // say goodbye to all this code ?
- if ((begin_level == 1) && (!is_html)) {
- if (curdiv == topdiv) {
- if (topdiv->before_first_page) {
- if (!break_flag) {
- if (!topdiv->no_space_mode)
- topdiv->begin_page();
- }
- else if (topdiv->no_space_mode)
- topdiv->begin_page();
- else {
- push_page_ejector();
- topdiv->begin_page();
- topdiv->set_ejecting();
- }
- }
- else {
- push_page_ejector();
- if (break_flag)
- curenv->do_break();
- if (!topdiv->no_space_mode)
- topdiv->set_ejecting();
- }
- }
- }
- // say goodbye to all this code?
-#endif
break;
case '4':
begin_level--;
diff --git a/tmac/an-old.tmac b/tmac/an-old.tmac
index d1b9d03d..4b582bc9 100644
--- a/tmac/an-old.tmac
+++ b/tmac/an-old.tmac
@@ -92,7 +92,7 @@
.\" .TH title section extra1 extra2 extra3
.de1 TH
. if \\n[an-html] \{\
-. HTML-TAG ".tl"
+. HTML-TAG ".tl"
\\$1
. \}
.
@@ -327,12 +327,9 @@
. sp \\n[PD]u
. if \\n[.$] .nr an-prevailing-indent (n;\\$1)
. it 1 an-trap
+. in 0
+. ll -\\n[an-margin]u
. if !\\n[an-div?] .di an-div
-. ie \\n[an-html] .in \\n[an-margin]u
-. el \{\
-. in 0
-. ll -\\n[an-margin]u
-. \}
. nr an-div? 1
..
.
@@ -372,6 +369,27 @@
. \}
..
.
+.de an-do-tag-html
+. nr an-div? 0
+. br
+. ll
+. di
+. ie ((\\n[dl] + \\n[an-tag-sep]) > \\n[an-prevailing-indent]) \{\
+. in \\n[an-margin]u
+. an-div
+. br
+. in (\\n[an-margin]u + \\n[an-prevailing-indent]u + \\n[an-tag-sep]u)
+. \}
+. el \{\
+. in (\\n[an-margin]u + \\n[an-prevailing-indent]u + \\n[an-tag-sep]u)
+. ti \\n[an-margin]u
+. chop an-div
+. HTML-TAG-NS ".col 1"
+\\*[an-div]\\h'|\\n[an-prevailing-indent]u'\\h'\\n[an-tag-sep]u'\c
+. HTML-TAG-NS ".col 2"
+. \}
+..
+.
.de1 LP
. br
. sp \\n[PD]u
@@ -552,7 +570,11 @@
.ds lq \(lq
.ds rq \(rq
.
-.if !\n[an-html] .hy 14
+.ie \n[an-html] \{\
+. rm an-do-tag
+. als an-do-tag an-do-tag-html
+.\}
+.el .hy 14
.
.\" Load local modifications.
.mso man.local
diff --git a/tmac/dvi.tmac b/tmac/dvi.tmac
index bd25942d..4eb03b86 100644
--- a/tmac/dvi.tmac
+++ b/tmac/dvi.tmac
@@ -131,6 +131,7 @@ D\v'-.33m'\s0\v'.33m'
.dvi-achar \[^U] ^ U u
.dvi-achar \[:U] \[ad] U u
.dvi-achar \['Y] \' Y y
+.dvi-achar \[:Y] \[ad] Y y
.dvi-achar \[`a] \` a a
.dvi-achar \['a] \' a a
.dvi-achar \[^a] ^ a a
@@ -157,6 +158,10 @@ D\v'-.33m'\s0\v'.33m'
.dvi-achar \[:u] \[ad] u u
.dvi-achar \['y] \' y y
.dvi-achar \[:y] \[ad] y y
+.dvi-achar \[vs] \[ah] s s
+.dvi-achar \[vS] \[ah] S s
+.dvi-achar \[vz] \[ah] z z
+.dvi-achar \[vZ] \[ah] Z z
.fchar \[,C] \o'\[ac]C'
.hcode \[,C]c
.fchar \[,c] \o'\[ac]c'
diff --git a/tmac/html.tmac b/tmac/html.tmac
index 79868e1c..cd30c28d 100644
--- a/tmac/html.tmac
+++ b/tmac/html.tmac
@@ -14,22 +14,11 @@
.ftr HX HBI
.ftr NX NBI
.
-.fchar \[em] --
-.fchar \[en] \-
.fchar \[fi] fi
.fchar \[fl] fl
.fchar \[ff] ff
.fchar \[Fi] ffi
.fchar \[Fl] ffl
-.fchar \[lq] ``
-.fchar \[rq] ''
-.fchar \[bq] ,,
-.fchar \[OE] OE
-.fchar \[oe] oe
-.fchar \[lh] <-
-.fchar \[rh] ->
-.fchar \[bq] ,
-.fchar \[aq] '
.
.\"
.\" remove hyphenation
@@ -719,4 +708,6 @@
.el \
. do mso cp1047.tmac
.
+.\" tell grohtml the page offset
+.po
.\" end of file, make sure this is the last line
diff --git a/tmac/s.tmac b/tmac/s.tmac
index 7fd95aee..e36c3e2e 100644
--- a/tmac/s.tmac
+++ b/tmac/s.tmac
@@ -3,7 +3,8 @@
s.tmac
-Copyright (C) 1989, 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
+Copyright (C) 1989, 1990, 1991, 1992, 2001, 2002
+ Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.com)
This file is part of groff.
@@ -1154,19 +1155,35 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
. par*pop-tag-env
. di
. chop par*label
-. ie '\*(.T'html' \{\
-. if \\n[dl]+1n<=\\n[\\n[.ev]:ai] .HTML-TAG ".ip"
-. ti 0
-\&\\$1
+. ti -\\n[\\n[.ev]:ai]u
+. ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
+. el \{\
+\\*[par*label]
. br
. \}
+. rm par*label
+.\}
+..
+.de @IP-html
+.if \\n[.$]>1 .nr \\n[.ev]:ai (n;\\$2)
+.par*start \\n[\\n[.ev]:ai] 0
+.if !'\\$1'' \{\
+. \" Divert the label so as to freeze any spaces.
+. di par*label
+. par*push-tag-env
+\&\\$1
+. par*pop-tag-env
+. di
+. chop par*label
+. ti -\\n[\\n[.ev]:ai]u
+. ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \{\
+. HTML-TAG-NS ".col 1"
+\\$1\h'|\\n[\\n[.ev]:ai]u'\c
+. HTML-TAG-NS ".col 2"
+. \}
. el \{\
-. ti -\\n[\\n[.ev]:ai]u
-. ie \\n[dl]+1n<=\\n[\\n[.ev]:ai] \\*[par*label]\h'|\\n[\\n[.ev]:ai]u'\c
-. el \{\
-\\*[par*label]
-. br
-. \}
+\\$1
+. br
. \}
. rm par*label
.\}
@@ -1960,4 +1977,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
. \}
..
.par@load-init
+.if '\*(.T'html' \{\
+. rm @IP
+. als @IP @IP-html
+.\}
.\" Make sure that no blank lines creep in at the end of this file.
diff --git a/tmac/www.tmac b/tmac/www.tmac
index 22f829e1..03d0792a 100644
--- a/tmac/www.tmac
+++ b/tmac/www.tmac
@@ -41,6 +41,13 @@
. \}
..
.\"
+.\" an auxiliary macro for HTML (without following space)
+.\"
+.de HTML-NS
+. if \\n[www-html] \
+. nop \X^html:\\$*^\c
+..
+.\"
.\" HX n
.\"
.\" Automatic heading level cut off.
@@ -161,6 +168,15 @@
. \}
..
.\"
+.\" HTML-TAG-NS
+.\"
+.\" Emit a tag for grohtml (without a space). This is an internal macro.
+.\"
+.de HTML-TAG-NS
+. if \\n[www-html] \
+. nop \X^html-tag:\\$*^\c
+..
+.\"
.\" PIMG [-R|-L|-C] filename [width] [height]
.\"
.\" Include a png image. It will work for -Tps and -Thtml.
@@ -204,7 +220,10 @@
. if !r ps4html \{\
. www-make-unique-name
. sy pngtopnm \\$2 | pnmcrop -white | pnmtops -noturn > \\*[www-unique-name].eps
-. PSPIC \\$1 \\*[www-unique-name].eps \\$3 \\$4
+. ie '\\$1'-C' \
+. PSPIC \\*[www-unique-name].eps \\$3 \\$4
+. el \
+. PSPIC \\$1 \\*[www-unique-name].eps \\$3 \\$4
. \}
. \}
..
@@ -369,7 +388,7 @@
.de HR
. ie \\n[www-html] \{\
. ti 0
-. HTML <hr>
+. HTML-NS <hr>
. \}
. el \
. sp
@@ -582,5 +601,4 @@
.if r ps4html .nop \O[0]
.cp \n(_C
.
-.\" now set
.\" EOF