diff options
-rw-r--r-- | ChangeLog | 124 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | font/devhtml/R.proto | 184 | ||||
-rw-r--r-- | font/devutf8/NOTES | 19 | ||||
-rw-r--r-- | font/devutf8/R.proto | 16 | ||||
-rw-r--r-- | man/groff_char.man | 2 | ||||
-rw-r--r-- | src/devices/grohtml/Makefile.sub | 3 | ||||
-rw-r--r-- | src/devices/grohtml/html-text.cc | 364 | ||||
-rw-r--r-- | src/devices/grohtml/html-text.h | 98 | ||||
-rw-r--r-- | src/devices/grohtml/post-html.cc | 1056 | ||||
-rw-r--r-- | src/preproc/grn/grn.man | 12 | ||||
-rw-r--r-- | src/roff/troff/div.cc | 8 | ||||
-rw-r--r-- | src/roff/troff/env.cc | 170 | ||||
-rw-r--r-- | src/roff/troff/env.h | 11 | ||||
-rw-r--r-- | src/roff/troff/input.cc | 45 | ||||
-rw-r--r-- | tmac/an-old.tmac | 36 | ||||
-rw-r--r-- | tmac/dvi.tmac | 5 | ||||
-rw-r--r-- | tmac/html.tmac | 13 | ||||
-rw-r--r-- | tmac/s.tmac | 43 | ||||
-rw-r--r-- | tmac/www.tmac | 24 |
20 files changed, 1680 insertions, 555 deletions
@@ -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. @@ -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 & 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 < -la " = 24 0 0x003D eq " > 24 0 0x003E > -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 ý Tp 24 0 0x00FE þ :y 24 0 0x00FF ÿ -\` 24 0 0x2018 ` -ga " +.i 24 0 0x0131 ı +/L 24 0 0x0141 Ł +/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 ˘ +a. 24 0 0x02D9 ˙ +ao 24 0 0x02DA ˚ +ho 24 0 0x02DB ˛ +a" 24 0 0x02DD ˝ +*A 24 0 0x0391 Α +*B 24 0 0x0392 Β +*G 24 0 0x0393 Γ +*D 24 0 0x0394 Δ +*E 24 0 0x0395 Ε +*Z 24 0 0x0396 Ζ +*Y 24 0 0x0397 Η +*H 24 0 0x0398 Θ +*I 24 0 0x0399 Ι +*K 24 0 0x039A Κ +*L 24 0 0x039B Λ +*M 24 0 0x039C Μ +*N 24 0 0x039D Ν +*C 24 0 0x039E Ξ +*O 24 0 0x039F Ο +*P 24 0 0x03A0 Π +*R 24 0 0x03A1 Ρ +*S 24 0 0x03A3 Σ +*T 24 0 0x03A4 Τ +*U 24 0 0x03A5 Υ +*F 24 0 0x03A6 Φ +*X 24 0 0x03A7 Χ +*Q 24 0 0x03A8 Ψ +*W 24 0 0x03A9 Ω +*a 24 0 0x03B1 α +*b 24 0 0x03B2 β +*g 24 0 0x03B3 γ +*d 24 0 0x03B4 δ +*e 24 0 0x03B5 ε +*z 24 0 0x03B6 ζ +*y 24 0 0x03B7 η +*h 24 0 0x03B8 θ +*i 24 0 0x03B9 ι +*k 24 0 0x03BA κ +*l 24 0 0x03BB λ +*m 24 0 0x03BC μ +*n 24 0 0x03BD ν +*c 24 0 0x03BE ξ +*o 24 0 0x03BF ο +*p 24 0 0x03C0 π +*r 24 0 0x03C1 ρ +ts 24 0 0x03C2 ς +*s 24 0 0x03C3 σ +*t 24 0 0x03C4 τ +*u 24 0 0x03C5 υ +*f 24 0 0x03C6 φ +*x 24 0 0x03C7 χ +*q 24 0 0x03C8 ψ +*w 24 0 0x03C9 ω ++h 24 0 0x03D1 ϑ ++f 24 0 0x03D5 ϕ ++p 24 0 0x03D6 ϖ +en 24 0 0x2013 – +em 24 0 0x2014 — +` 24 0 0x2018 ‘ +oq " +' 24 0 0x2019 ’ +cq " +bq 24 0 0x201A ‚ +lq 24 0 0x201C “ +rq 24 0 0x201D ” +Bq 24 0 0x201E „ +dg 24 0 0x2020 † +dd 24 0 0x2021 ‡ +bu 24 0 0x2022 • +%0 24 0 0x2030 ‰ +fm 24 0 0x2032 ′ +sd 24 0 0x2033 ″ +fo 24 0 0x2039 ‹ +fc 24 0 0x203A › +rn 24 0 0x203E ‾ +f/ 24 0 0x2044 ⁄ Eu 24 0 0x20AC € eu " +Im 24 0 0x2111 ℑ +wp 24 0 0x2118 ℘ +Re 24 0 0x211C ℜ +tm 24 0 0x2122 ™ +Ah 24 0 0x2135 ℵ +<- 24 0 0x2190 ← +ua 24 0 0x2191 ↑ +-> 24 0 0x2192 → +da 24 0 0x2193 ↓ +<> 24 0 0x2194 ↔ +lA 24 0 0x21D0 ⇐ +uA 24 0 0x21D1 ⇑ +rA 24 0 0x21D2 ⇒ +dA 24 0 0x21D3 ⇓ +hA 24 0 0x21D4 ⇔ +fa 24 0 0x2200 ∀ +pd 24 0 0x2202 ∂ +te 24 0 0x2203 ∃ +es 24 0 0x2205 ∅ +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 ∗ +sr 24 0 0x221A √ +pt 24 0 0x221D ∝ +if 24 0 0x221E ∞ +/_ 24 0 0x2220 ∠ +AN 24 0 0x2227 ∧ +OR 24 0 0x2228 ∨ +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 ≅ +~~ 24 0 0x2248 ≈ +~= " +!= 24 0 0x2260 ≠ +== 24 0 0x2261 ≡ +<= 24 0 0x2264 ≤ +>= 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 ⊥ +md 24 0 0x22C5 ⋅ +lc 24 0 0x2308 ⌈ +rc 24 0 0x2309 ⌉ +lf 24 0 0x230A ⌊ +rf 24 0 0x230B ⌋ +la 24 0 0x2329 ⟨ +ra 24 0 0x232A ⟩ +CR 24 0 0x240D ␍ +an 24 0 0x2500 ─ +br 24 0 0x2502 │ +bv " +rk 24 0 0x251D ┝ +lk 24 0 0x2525 ┥ +lt 24 0 0x256D ╭ +rt 24 0 0x256E ╮ +rb 24 0 0x256F ╯ +lb 24 0 0x2570 ╰ +sq 24 0 0x25A1 □ +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 ♦ 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 |