groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Groff-commit] groff/src/roff/troff column.cpp div.h div.cpp e...


From: Werner LEMBERG
Subject: [Groff-commit] groff/src/roff/troff column.cpp div.h div.cpp e...
Date: Sun, 10 Oct 2004 15:15:15 -0400

CVSROOT:        /cvsroot/groff
Module name:    groff
Branch:         
Changes by:     Werner LEMBERG <address@hidden> 04/10/10 19:08:05

Modified files:
        src/roff/troff : column.cpp div.h div.cpp env.h env.cpp 
                         input.cpp 

Log message:
        * src/roff/troff/column.cpp (vjustify_node::copy): Updated.
        
        * src/roff/troff/div.h: Include `mtsm.h'.
        (diversion): New variables `any_chars_added', `needs_push',
        `saved_seen_break', `saved_seen_space', `saved_seen_eol',
        `saved_suppress_next_eol', `modified_tag'.
        New virtual member function `is_diversion'.  Update all descendants.
        
        * src/roff/troff/div.cpp (diversion::diversion,
        macro_diversion::macro_diversion): Updated.
        (do_divert): Handle `seen_break', `seen_space', `seen_eol',
        `suppress_next_eol'.
        (top_level_diversion::space): Handle `curenv->seen_space'.
        (page_offset): Update tag handling.
        (space_request, blank_line, flush_output): Don't call `add_html_tag'.
        
        * src/roff/troff/env.h (environment): Make `tabs' public.
        Remove `ignore_next_eol', `emitted_node'.
        Update `output_line', `output'.
        New variables `seen_space', `seen_eol', `suppress_next_eol',
        `seen_break'.
        New member functions `construct_state', `make_tag',
        `construct_format_state, `construct_new_line_state,
        `dump_troff_state'.
        Remove `add_html_tag', `make_html_tag'.
        
        * src/roff/troff/env.cpp: New externs `suppress_push',
        `get_diversion_state', `global_diverted_space'.
        (pending_output_line): New variable `was_centered'.
        Update constructor and all callers.
        (pending_output_line::output): Call `curenv->construct_format_state'.
        (environment::environment, environment::copy): Updated.
        (environment::output): Handle `was_centered'.
        (environment::add_char): Handle construct and diversion state.
        (environment::add_node): Handle construct state.
        (environment::newline): Handle `was_centered'.
        (environment::output_line): Updated.
        (environment::possibly_break_line): Updated.
        Update tag handling.
        (environment::add_html_tag): Replaced with...
        (environment::make_tag): New function.
        (environment::add_html_tag_tabs, environment::make_html_tag): Removed.
        (environment::dump_troff_state): New debugging function.
        (environment::construct_state, environment::construct_format_state,
        environment::construct_new_line_state): New functions.
        (environment::do_break): Updated.
        Handle `global_diverted_space'.
        (environment::handle_tag): Update tag handling.
        (point_size, fill, do_break_request): Don't call `add_html_tag'.
        (no_fill): Don't call `add_html_tag'.
        Set `suppress_next_eol'.
        (center, right_justify, line_length, indent, temporary_indent,
        set_tabs):
        Update tag handling.
        
        * src/roff/troff/input.cpp: Don't include `stringclass.h'.
        (input_iterator): New variables `is_diversion', `diversion_state'.
        Update constructors.
        (input_stack): New member functions `get_div_level',
        `get_diversion_state', `check_end_diversion'.
        New variables `div_level', `diversion_state'.  Initialize them.
        (suppress_push, global_diverted_space): New global variables.
        (input_stack::finish_get, input_stack::finish_peek,
        input_stack::remove_boundary, input_stack::end_file,
        input_stack::clear, input_stack::pop_macro): Call
        `check_end_diversion'.
        (input_stack::push): Handle `div_level' and `diversion_state'.
        (get_diversion_state): New function.
        (diverted_space_node::reread): Handle `global_diverted_space'.
        (macro::macro): Update constructors.
        (macro::is_diversion): New function.
        (macro::operator=): Set `is_a_diversion'.
        (string_iterator): New member function `is_diversion'.
        (string_iterator::string_iterator): Update constructors.
        (string_iterator::fill): Set `div_nest_level'.
        (macro_iterator): New member function `is_diversion'.
        (do_if_request): Handle `suppress_push'.
        (tag, taga): New functions.
        (init_input_requests): Add `tag' and `taga' requests.

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/src/roff/troff/column.cpp.diff?tr1=1.1&tr2=1.2&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/src/roff/troff/div.h.diff?tr1=1.11&tr2=1.12&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/src/roff/troff/div.cpp.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/src/roff/troff/env.h.diff?tr1=1.31&tr2=1.32&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/src/roff/troff/env.cpp.diff?tr1=1.8&tr2=1.9&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/groff/groff/src/roff/troff/input.cpp.diff?tr1=1.19&tr2=1.20&r1=text&r2=text

Patches:
Index: groff/src/roff/troff/column.cpp
diff -u groff/src/roff/troff/column.cpp:1.1 groff/src/roff/troff/column.cpp:1.2
--- groff/src/roff/troff/column.cpp:1.1 Tue Apr 15 15:14:08 2003
+++ groff/src/roff/troff/column.cpp     Sun Oct 10 19:08:03 2004
@@ -666,7 +666,7 @@
 
 node *vjustify_node::copy()
 {
-  return new vjustify_node(typ);
+  return new vjustify_node(typ, div_nest_level);
 }
 
 const char *vjustify_node::type()
Index: groff/src/roff/troff/div.cpp
diff -u groff/src/roff/troff/div.cpp:1.6 groff/src/roff/troff/div.cpp:1.7
--- groff/src/roff/troff/div.cpp:1.6    Mon Apr 19 06:17:47 2004
+++ groff/src/roff/troff/div.cpp        Sun Oct 10 19:08:03 2004
@@ -51,7 +51,9 @@
 
 diversion::diversion(symbol s) 
 : prev(0), nm(s), vertical_position(V0), high_water_mark(V0),
-  no_space_mode(0), marked_place(V0)
+  no_space_mode(0), needs_push(0), marked_place(V0),
+  any_chars_added(0), saved_seen_break(0), saved_seen_space(0),
+  saved_seen_eol(0), saved_suppress_next_eol(0)
 {
 }
 
@@ -97,6 +99,10 @@
   symbol nm = get_name();
   if (nm.is_null()) {
     if (curdiv->prev) {
+      curenv->seen_break = curdiv->saved_seen_break;
+      curenv->seen_space = curdiv->saved_seen_space;
+      curenv->seen_eol = curdiv->saved_seen_eol;
+      curenv->suppress_next_eol = curdiv->saved_suppress_next_eol;
       if (boxing) {
        curenv->line = curdiv->saved_line;
        curenv->width_total = curdiv->saved_width_total;
@@ -116,6 +122,13 @@
     macro_diversion *md = new macro_diversion(nm, append);
     md->prev = curdiv;
     curdiv = md;
+    curdiv->saved_seen_break = curenv->seen_break;
+    curdiv->saved_seen_space = curenv->seen_space;
+    curdiv->saved_seen_eol = curenv->seen_eol;
+    curdiv->saved_suppress_next_eol = curenv->suppress_next_eol;
+    curenv->seen_break = 0;
+    curenv->seen_space = 0;
+    curenv->seen_eol = 0;
     if (boxing) {
       curdiv->saved_line = curenv->line;
       curdiv->saved_width_total = curenv->width_total;
@@ -202,7 +215,7 @@
   // We can now catch the situation described above by comparing
   // the length of the charlist in the macro_header with the length
   // stored in the macro. When we detect this, we copy the contents.
-  mac = new macro;
+  mac = new macro(1);
   if (append) {
     request_or_macro *rm 
       = (request_or_macro *)request_dictionary.lookup(s);
@@ -257,9 +270,8 @@
     nd->set_vertical_size(&v);
     node *temp = nd;
     nd = nd->next;
-    if (temp->interpret(mac)) {
+    if (temp->interpret(mac))
       delete temp;
-    }
     else {
 #if 1
       temp->freeze_space();
@@ -445,6 +457,8 @@
   vunits next_trap_pos;
   trap *next_trap = find_next_trap(&next_trap_pos);
   vunits y = vertical_position + n;
+  curenv->seen_space += n.to_units()
+                       / curenv->get_vertical_spacing().to_units();
   if (vertical_position_traps_flag && next_trap != 0 && y >= next_trap_pos) {
     vertical_position = next_trap_pos;
     nl_reg_contents = vertical_position.to_units();
@@ -639,7 +653,7 @@
     n = topdiv->prev_page_offset;
   topdiv->prev_page_offset = topdiv->page_offset;
   topdiv->page_offset = n;
-  curenv->add_html_tag(0, ".po", n.to_units());
+  topdiv->modified_tag.incl(MTSM_PO);
   skip_line();
 }
 
@@ -732,11 +746,11 @@
   skip_line();
 }
 
-/* It is necessary to generate a break before before reading the argument,
-because otherwise arguments using | will be wrong. But if we just
+/* It is necessary to generate a break before reading the argument,
+because otherwise arguments using | will be wrong.  But if we just
 generate a break as usual, then the line forced out may spring a trap
 and thus push a macro onto the input stack before we have had a chance
-to read the argument to the sp request. We resolve this dilemma by
+to read the argument to the sp request.  We resolve this dilemma by
 setting, before generating the break, a flag which will postpone the
 actual pushing of the macro associated with the trap sprung by the
 outputting of the line forced out by the break till after we have read
@@ -758,17 +772,15 @@
   else
     // The line might have had line spacing that was truncated.
     truncated_space += n;
-  curenv->add_html_tag(1, ".sp", n.to_units());
+  
   tok.next();
 }
 
 void blank_line()
 {
   curenv->do_break();
-  if (!trap_sprung_flag && !curdiv->no_space_mode) {
+  if (!trap_sprung_flag && !curdiv->no_space_mode)
     curdiv->space(curenv->get_vertical_spacing());
-    curenv->add_html_tag(1, ".sp", 1);
-  }
   else
     truncated_space += curenv->get_vertical_spacing();
 }
@@ -832,7 +844,6 @@
     curenv->do_break();
   if (the_output)
     the_output->flush();
-  curenv->add_html_tag(1, ".fl");
   tok.next();
 }
 
Index: groff/src/roff/troff/div.h
diff -u groff/src/roff/troff/div.h:1.11 groff/src/roff/troff/div.h:1.12
--- groff/src/roff/troff/div.h:1.11     Fri May 28 21:43:38 2004
+++ groff/src/roff/troff/div.h  Sun Oct 10 19:08:03 2004
@@ -21,6 +21,8 @@
 
 void end_diversions();
 
+#include "mtsm.h"
+
 class diversion {
   friend void do_divert(int append, int boxing);
   friend void end_diversions();
@@ -36,9 +38,17 @@
   vunits vertical_position;
   vunits high_water_mark;
 public:
+  int any_chars_added;
   int no_space_mode;
+  int needs_push;
+  int saved_seen_break;
+  int saved_seen_space;
+  int saved_seen_eol;
+  int saved_suppress_next_eol;
+  state_set modified_tag;
   vunits marked_place;
   diversion(symbol s = NULL_SYMBOL);
+
   virtual ~diversion();
   virtual void output(node *nd, int retain_size, vunits vs, vunits post_vs,
                      hunits width) = 0;
@@ -56,6 +66,7 @@
   virtual void set_diversion_trap(symbol, vunits) = 0;
   virtual void clear_diversion_trap() = 0;
   virtual void copy_file(const char *filename) = 0;
+  virtual int is_diversion() = 0;
 };
 
 class macro;
@@ -80,6 +91,7 @@
   void set_diversion_trap(symbol, vunits);
   void clear_diversion_trap();
   void copy_file(const char *filename);
+  int is_diversion() { return 1; }
 };
 
 struct trap {
@@ -136,6 +148,7 @@
   void set_diversion_trap(symbol, vunits);
   void clear_diversion_trap();
   void set_last_page() { last_page_count = page_count; }
+  int is_diversion() { return 0; }
 };
 
 extern top_level_diversion *topdiv;
Index: groff/src/roff/troff/env.cpp
diff -u groff/src/roff/troff/env.cpp:1.8 groff/src/roff/troff/env.cpp:1.9
--- groff/src/roff/troff/env.cpp:1.8    Tue Jul 27 01:29:24 2004
+++ groff/src/roff/troff/env.cpp        Sun Oct 10 19:08:03 2004
@@ -51,6 +51,8 @@
 dictionary env_dictionary(10);
 environment *curenv;
 static int next_line_number = 0;
+extern int suppress_push;
+extern statem *get_diversion_state();
 
 charinfo *field_delimiter_char;
 charinfo *padding_indicator_char;
@@ -60,6 +62,7 @@
 class pending_output_line {
   node *nd;
   int no_fill;
+  int was_centered;
   vunits vs;
   vunits post_vs;
   hunits width;
@@ -69,20 +72,21 @@
 public:
   pending_output_line *next;
 
-  pending_output_line(node *, int, vunits, vunits, hunits,
+  pending_output_line(node *, int, vunits, vunits, hunits, int,
                      pending_output_line * = 0);
   ~pending_output_line();
   int output();
 
 #ifdef WIDOW_CONTROL
   friend void environment::mark_last_line();
-  friend void environment::output(node *, int, vunits, vunits, hunits);
+  friend void environment::output(node *, int, vunits, vunits, hunits, int);
 #endif /* WIDOW_CONTROL */
 };
 
 pending_output_line::pending_output_line(node *n, int nf, vunits v, vunits pv,
-                                        hunits w, pending_output_line *p)
-: nd(n), no_fill(nf), vs(v), post_vs(pv), width(w),
+                                        hunits w, int ce,
+                                        pending_output_line *p)
+: nd(n), no_fill(nf), was_centered(ce), vs(v), post_vs(pv), width(w),
 #ifdef WIDOW_CONTROL
   last_line(0),
 #endif /* WIDOW_CONTROL */
@@ -108,6 +112,7 @@
     }
   }
 #endif
+  curenv->construct_format_state(nd, was_centered, !no_fill);
   curdiv->output(nd, no_fill, vs, post_vs, width);
   nd = 0;
   return 1;
@@ -115,7 +120,7 @@
 
 void environment::output(node *nd, int no_fill_flag,
                         vunits vs, vunits post_vs,
-                        hunits width)
+                        hunits width, int was_centered)
 {
 #ifdef WIDOW_CONTROL
   while (pending_lines) {
@@ -135,13 +140,14 @@
       && (!widow_control || no_fill_flag)
 #endif /* WIDOW_CONTROL */
       ) {
+    curenv->construct_format_state(nd, was_centered, !no_fill_flag);
     curdiv->output(nd, no_fill_flag, vs, post_vs, width);
-    emitted_node = 1;
   } else {
     pending_output_line **p;
     for (p = &pending_lines; *p; p = &(*p)->next)
       ;
-    *p = new pending_output_line(nd, no_fill_flag, vs, post_vs, width);
+    *p = new pending_output_line(nd, no_fill_flag, vs, post_vs, width,
+                                was_centered);
   }
 }
 
@@ -155,7 +161,7 @@
     curdiv->output(nd, no_fill_flag, vs, post_vs, width);
   else
     pending_lines = new pending_output_line(nd, no_fill_flag, vs, post_vs,
-                                           width, pending_lines);
+                                           width, 0, pending_lines);
 }
 
 void environment::output_pending_lines()
@@ -266,6 +272,7 @@
 void environment::add_char(charinfo *ci)
 {
   int s;
+  node *gc_np = 0;
   if (interrupted)
     ;
   // don't allow fields in dummy environments
@@ -281,18 +288,40 @@
     if (tab_contents == 0)
       tab_contents = new line_start_node;
     if (ci != hyphen_indicator_char)
-      tab_contents = tab_contents->add_char(ci, this, &tab_width, &s);
+      tab_contents = tab_contents->add_char(ci, this, &tab_width, &s, &gc_np);
     else
       tab_contents = tab_contents->add_discretionary_hyphen();
   }
   else {
     if (line == 0)
       start_line();
+#if 0
+    fprintf(stderr, "current line is\n");
+    line->debug_node_list();
+#endif
     if (ci != hyphen_indicator_char)
-      line = line->add_char(ci, this, &width_total, &space_total);
+      line = line->add_char(ci, this, &width_total, &space_total, &gc_np);
     else
       line = line->add_discretionary_hyphen();
   }
+#if 0
+  fprintf(stderr, "now after we have added character the line is\n");
+  line->debug_node_list();
+#endif
+  if ((!suppress_push) && gc_np) {
+    if (gc_np && (gc_np->state == 0)) {
+      gc_np->state = construct_state(0);
+      gc_np->push_state = get_diversion_state();
+    }
+    else if (line && (line->state == 0)) {
+      line->state = construct_state(0);
+      line->push_state = get_diversion_state();
+    }
+  }
+#if 0
+  fprintf(stderr, "now we have possibly added the state the line is\n");
+  line->debug_node_list();
+#endif
 }
 
 node *environment::make_char_node(charinfo *ci)
@@ -304,6 +333,12 @@
 {
   if (n == 0)
     return;
+  if (!suppress_push) {
+    if (n->is_special && n->state == NULL)
+      n->state = construct_state(0);
+    n->push_state = get_diversion_state();
+  }
+
   if (current_tab || current_field)
     n->freeze_space();
   if (interrupted) {
@@ -327,10 +362,10 @@
     space_total += n->nspaces();
     n->next = line;
     line = n;
+    construct_new_line_state(line);
   }
 }
 
-
 void environment::add_hyphen_indicator()
 {
   if (current_tab || interrupted || current_field
@@ -587,6 +622,10 @@
   prev_requested_size(sizescale*10),
   char_height(0),
   char_slant(0),
+  seen_space(0),
+  seen_eol(0),
+  suppress_next_eol(0),
+  seen_break(0),
   space_size(12),
   sentence_space_size(12),
   adjust_mode(ADJUST_BOTH),
@@ -641,8 +680,6 @@
 #ifdef WIDOW_CONTROL
   widow_control(0),
 #endif /* WIDOW_CONTROL */
-  ignore_next_eol(0),
-  emitted_node(0),
   glyph_color(&default_color),
   prev_glyph_color(&default_color),
   fill_color(&default_color),
@@ -677,6 +714,10 @@
   fontno(e->fontno),
   prev_family(e->prev_family),
   family(e->family),
+  seen_space(e->seen_space),
+  seen_eol(e->seen_eol),
+  suppress_next_eol(e->suppress_next_eol),
+  seen_break(e->seen_break),
   space_size(e->space_size),
   sentence_space_size(e->sentence_space_size),
   adjust_mode(e->adjust_mode),
@@ -731,8 +772,6 @@
 #ifdef WIDOW_CONTROL
   widow_control(e->widow_control),
 #endif /* WIDOW_CONTROL */
-  ignore_next_eol(0),
-  emitted_node(0),
   glyph_color(e->glyph_color),
   prev_glyph_color(e->prev_glyph_color),
   fill_color(e->fill_color),
@@ -818,8 +857,6 @@
   hyphenation_space = e->hyphenation_space;
   hyphenation_margin = e->hyphenation_margin;
   composite = 0;
-  ignore_next_eol = e->ignore_next_eol;
-  emitted_node = e->emitted_node;
   glyph_color= e->glyph_color;
   prev_glyph_color = e->prev_glyph_color;
   fill_color = e->fill_color;
@@ -1186,7 +1223,6 @@
     if (n <= 0)
       n = 1;
     curenv->set_size(n);
-    curenv->add_html_tag(0, ".ps", n);
   }
   else
     curenv->set_size(0);
@@ -1254,8 +1290,6 @@
   if (break_flag)
     curenv->do_break();
   curenv->fill = 1;
-  curenv->add_html_tag(1, ".fi");
-  curenv->add_html_tag(0, ".br");
   tok.next();
 }
 
@@ -1266,9 +1300,7 @@
   if (break_flag)
     curenv->do_break();
   curenv->fill = 0;
-  curenv->add_html_tag(1, ".nf");
-  curenv->add_html_tag(0, ".br");
-  curenv->add_html_tag(0, ".po", topdiv->get_page_offset().to_units());
+  curenv->suppress_next_eol = 1;
   tok.next();
 }
 
@@ -1285,7 +1317,7 @@
     curenv->do_break();
   curenv->right_justify_lines = 0;
   curenv->center_lines = n;
-  curenv->add_html_tag(1, ".ce", n);
+  curdiv->modified_tag.incl(MTSM_CE);
   tok.next();
 }
 
@@ -1302,7 +1334,7 @@
     curenv->do_break();
   curenv->center_lines = 0;
   curenv->right_justify_lines = n;
-  curenv->add_html_tag(1, ".rj", n);
+  curdiv->modified_tag.incl(MTSM_RJ);
   tok.next();
 }
 
@@ -1319,7 +1351,7 @@
     temp = curenv->prev_line_length;
   curenv->prev_line_length = curenv->line_length;
   curenv->line_length = temp;
-  curenv->add_html_tag(1, ".ll", temp.to_units());
+  curdiv->modified_tag.incl(MTSM_LL);
   skip_line();
 }
 
@@ -1406,8 +1438,7 @@
   curenv->have_temporary_indent = 0;
   curenv->prev_indent = curenv->indent;
   curenv->indent = temp;
-  if (break_flag)
-    curenv->add_html_tag(1, ".in", temp.to_units());
+  curdiv->modified_tag.incl(MTSM_IN);
   tok.next();
 }
 
@@ -1428,7 +1459,7 @@
   if (!err) {
     curenv->temporary_indent = temp;
     curenv->have_temporary_indent = 1;
-    curenv->add_html_tag(1, ".ti", temp.to_units());
+    curdiv->modified_tag.incl(MTSM_TI);
   }
   tok.next();
 }
@@ -1645,6 +1676,7 @@
 
 void environment::newline()
 {
+  int was_centered = 0;
   if (underline_lines > 0) {
     if (--underline_lines == 0) {
       prev_fontno = fontno;
@@ -1683,11 +1715,7 @@
     if (x > H0)
       saved_indent += x/2;
     to_be_output = line;
-    if (is_html) {
-      node *n = make_html_tag("eol.ce");
-      n->next = to_be_output;
-      to_be_output = n;
-    }
+    was_centered = 1;
     to_be_output_width = width_total;
     line = 0;
   }
@@ -1710,14 +1738,14 @@
   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;
-      }
+      curdiv->modified_tag.incl(MTSM_EOL);
+      if (suppress_next_eol)
+       suppress_next_eol = 0;
+      else
+       seen_eol = 1;
     }
-    output_line(to_be_output, to_be_output_width);
+
+    output_line(to_be_output, to_be_output_width, was_centered);
     hyphen_line_count = 0;
   }
   if (input_trap_count > 0) {
@@ -1727,7 +1755,7 @@
   }
 }
 
-void environment::output_line(node *n, hunits width)
+void environment::output_line(node *n, hunits width, int was_centered)
 {
   prev_text_length = width;
   if (margin_character_flags) {
@@ -1786,7 +1814,8 @@
     width += w;
     ++next_line_number;
   }
-  output(nn, !fill, vertical_spacing, total_post_vertical_spacing(), width);
+  output(nn, !fill, vertical_spacing, total_post_vertical_spacing(), width,
+        was_centered);
 }
 
 void environment::start_line()
@@ -2034,6 +2063,7 @@
 
 void environment::possibly_break_line(int start_here, int forced)
 {
+  int was_centered = center_lines > 0;
   if (!fill || current_tab || current_field || dummy)
     return;
   while (line != 0
@@ -2063,6 +2093,7 @@
       break;
     case ADJUST_CENTER:
       saved_indent += (target_text_length - bp->width)/2;
+      was_centered = 1;
       break;
     case ADJUST_RIGHT:
       saved_indent += target_text_length - bp->width;
@@ -2100,7 +2131,7 @@
     }
     // Do output_line() here so that line will be 0 iff the
     // the environment will be empty.
-    output_line(pre, output_width);
+    output_line(pre, output_width, was_centered);
     while (to_be_discarded != 0) {
       tem = to_be_discarded;
       to_be_discarded = to_be_discarded->next;
@@ -2163,16 +2194,8 @@
     do_break();
 }
 
-/*
- *  add_html_tag - emits a special html-tag: to help post-grohtml understand
- *                 the key troff commands
- */
-
-void environment::add_html_tag(int force, const char *nm)
+node *environment::make_tag(const char *name, int i)
 {
-  if (!force && (curdiv != topdiv))
-    return;
-
   if (is_html) {
     /*
      * need to emit tag for post-grohtml
@@ -2182,131 +2205,117 @@
       topdiv->begin_page();
     macro *m = new macro;
     m->append_str("html-tag:");
-    for (const char *p = nm; *p; p++)
-      if (!invalid_input_char((unsigned char)*p))
-       m->append(*p);
-    curdiv->output(new special_node(*m), 1, 0, 0, 0);
-    if (strcmp(nm, ".nf") == 0)
-      curenv->ignore_next_eol = 1;
-  }
-}
-
-/*
- *  add_html_tag - emits a special html-tag: to help post-grohtml understand
- *                 the key troff commands, it appends a string representation
- *                 of i.
- */
-
-void environment::add_html_tag(int force, const char *nm, int i)
-{
-  if (!force && (curdiv != topdiv))
-    return;
-
-  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 = nm; *p; p++)
+    for (const char *p = name; *p; p++)
       if (!invalid_input_char((unsigned char)*p))
        m->append(*p);
     m->append(' ');
     m->append_int(i);
-    node *n = new special_node(*m);
-    curdiv->output(n, 1, 0, 0, 0);
+    return new special_node(*m);
   }
+  return 0;
 }
 
-/*
- *  add_html_tag_tabs - emits the tab settings for post-grohtml
- */
-
-void environment::add_html_tag_tabs(int force)
+void environment::dump_troff_state()
 {
-  if (!force && (curdiv != topdiv))
-    return;
+#define SPACES "                                            "
+  fprintf(stderr, SPACES "register `in' = %d\n", curenv->indent.to_units());
+  if (curenv->have_temporary_indent)
+    fprintf(stderr, SPACES "register `ti' = %d\n",
+           curenv->temporary_indent.to_units());
+  fprintf(stderr, SPACES "centered lines `ce' = %d\n", curenv->center_lines);
+  fprintf(stderr, SPACES "register `ll' = %d\n",
+         curenv->line_length.to_units());
+  fprintf(stderr, SPACES "fill `fi=1/nf=0' = %d\n", curenv->fill);
+  fprintf(stderr, SPACES "page offset `po' = %d\n",
+         topdiv->get_page_offset().to_units());
+  fprintf(stderr, SPACES "seen_break = %d\n", curenv->seen_break);
+  fprintf(stderr, SPACES "seen_space = %d\n", curenv->seen_space);
+  fflush(stderr);
+#undef SPACES
+}
 
+statem *environment::construct_state(int only_eol)
+{
   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;
-    hunits d, l;
-    enum tab_type t;
-    m->append_str("html-tag:.ta ");  
-    do {
-      t = curenv->tabs.distance_to_next_tab(l, &d);
-      l += d;
-      switch (t) {
-      case TAB_LEFT:
-       m->append_str(" L ");
-       m->append_int(l.to_units());
-       break;
-      case TAB_CENTER:
-       m->append_str(" C ");
-       m->append_int(l.to_units());
-       break;
-      case TAB_RIGHT:
-       m->append_str(" R ");
-       m->append_int(l.to_units());
-       break;
-      case TAB_NONE:
-       break;
-      }
-    } while ((t != TAB_NONE) && (l < get_line_length()));
-    curdiv->output(new special_node(*m), 1, 0, 0, 0);
+    statem *s = new statem();
+    if (!only_eol) {
+      s->add_tag(MTSM_IN, indent);
+      s->add_tag(MTSM_LL, line_length);
+      s->add_tag(MTSM_PO, topdiv->get_page_offset().to_units());
+      s->add_tag(MTSM_RJ, right_justify_lines);
+      if (have_temporary_indent)
+       s->add_tag(MTSM_TI, temporary_indent);
+      s->add_tag_ta();
+      if (seen_break)
+       s->add_tag(MTSM_BR);
+      if (seen_space != 0)
+       s->add_tag(MTSM_SP, seen_space);
+      seen_break = 0;
+      seen_space = 0;
+    }
+    if (seen_eol) {
+      s->add_tag(MTSM_EOL);
+      s->add_tag(MTSM_CE, center_lines);
+    }
+    seen_eol = 0;
+    return s;
   }
+  else
+    return NULL;
 }
 
-node *environment::make_html_tag(const char *nm, int i)
+void environment::construct_format_state(node *n, int was_centered, int fill)
 {
   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 = nm; *p; p++)
-      if (!invalid_input_char((unsigned char)*p))
-       m->append(*p);
-    m->append(' ');
-    m->append_int(i);
-    return new special_node(*m);
+    // find first glyph node which has a state.
+    while (n != 0 && n->state == 0)
+      n = n->next;
+    if (n == 0 || (n->state == 0))
+      return;
+    if (seen_space != 0)
+      n->state->add_tag(MTSM_SP, seen_space);
+    if (seen_eol && topdiv == curdiv)
+      n->state->add_tag(MTSM_EOL);
+    seen_space = 0;
+    seen_eol = 0;
+    if (was_centered)
+      n->state->add_tag(MTSM_CE, center_lines+1);
+    else
+      n->state->add_tag_if_unknown(MTSM_CE, 0);
+    n->state->add_tag_if_unknown(MTSM_FI, fill);
+    n = n->next;
+    while (n != 0) {
+      if (n->state != 0) {
+       n->state->sub_tag_ce();
+       n->state->add_tag_if_unknown(MTSM_FI, fill);
+      }
+      n = n->next;
+    }
   }
-  return 0;
 }
 
-node *environment::make_html_tag(const char *nm)
+void environment::construct_new_line_state(node *n)
 {
   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 = nm; *p; p++)
-      if (!invalid_input_char((unsigned char)*p))
-       m->append(*p);
-    return new special_node(*m);
+    // find first glyph node which has a state.
+    while (n != 0 && n->state == 0)
+      n = n->next;
+    if (n == 0 || n->state == 0)
+      return;
+    if (seen_space != 0)
+      n->state->add_tag(MTSM_SP, seen_space);
+    if (seen_eol && topdiv == curdiv)
+      n->state->add_tag(MTSM_EOL);
+    seen_space = 0;
+    seen_eol = 0;
   }
-  return 0;
 }
 
+extern int global_diverted_space;
+
 void environment::do_break(int do_spread)
 {
+  int was_centered = 0;
   if (curdiv == topdiv && topdiv->before_first_page) {
     topdiv->begin_page();
     return;
@@ -2333,6 +2342,7 @@
       switch (adjust_mode) {
       case ADJUST_CENTER:
        saved_indent += (target_text_length - width_total)/2;
+       was_centered = 1;
        break;
       case ADJUST_RIGHT:
        saved_indent += target_text_length - width_total;
@@ -2341,7 +2351,7 @@
     }
     node *tem = line;
     line = 0;
-    output_line(tem, width_total);
+    output_line(tem, width_total, was_centered);
     hyphen_line_count = 0;
   }
   prev_line_interrupted = 0;
@@ -2349,6 +2359,10 @@
   mark_last_line();
   output_pending_lines();
 #endif /* WIDOW_CONTROL */
+  if (!global_diverted_space) {
+    curdiv->modified_tag.incl(MTSM_BR);
+    seen_break = 1;
+  }
 }
 
 int environment::is_empty()
@@ -2360,10 +2374,8 @@
 {
   while (!tok.newline() && !tok.eof())
     tok.next();
-  if (break_flag) {
+  if (break_flag)
     curenv->do_break(spread);
-    curenv->add_html_tag(0, ".br");
-  }
   tok.next();
 }
 
@@ -2770,7 +2782,7 @@
     }
   }
   curenv->tabs = tabs;
-  curenv->add_html_tag_tabs(1);
+  curdiv->modified_tag.incl(MTSM_TA);
   skip_line();
 }
 
@@ -2892,14 +2904,14 @@
   case TAB_NONE:
     return;
   case TAB_LEFT:
+    add_node(make_tag("tab L", absolute.to_units()));
     add_node(make_tab_node(d));
-    add_node(make_html_tag("tab L", absolute.to_units()));
     return;
   case TAB_RIGHT:
-    add_node(make_html_tag("tab R", absolute.to_units()));
+    add_node(make_tag("tab R", absolute.to_units()));
     break;
   case TAB_CENTER:
-    add_node(make_html_tag("tab C", absolute.to_units()));
+    add_node(make_tag("tab C", absolute.to_units()));
     break;
   default:
     assert(0);
Index: groff/src/roff/troff/env.h
diff -u groff/src/roff/troff/env.h:1.31 groff/src/roff/troff/env.h:1.32
--- groff/src/roff/troff/env.h:1.31     Tue Jun 29 07:11:03 2004
+++ groff/src/roff/troff/env.h  Sun Oct 10 19:08:03 2004
@@ -19,6 +19,8 @@
 with groff; see the file COPYING.  If not, write to the Free Software
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
+class statem;
+
 struct size_range {
   int min;
   int max;
@@ -149,7 +151,6 @@
   hunits width_total;
   int space_total;
   hunits input_line_start;
-  tab_stops tabs;
   node *tab_contents;
   hunits tab_width;
   hunits tab_distance;
@@ -185,8 +186,6 @@
 #ifdef WIDOW_CONTROL
   int widow_control;
 #endif /* WIDOW_CONTROL */
-  int ignore_next_eol;
-  int emitted_node;    // have we emitted a node since the last html eol tag?
   color *glyph_color;
   color *prev_glyph_color;
   color *fill_color;
@@ -195,9 +194,9 @@
   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_line(node *, hunits, int);
   void output(node *nd, int retain_size, vunits vs, vunits post_vs,
-             hunits width);
+             hunits width, int was_centered);
   void output_title(node *nd, int retain_size, vunits vs, vunits post_vs,
                    hunits width);
 #ifdef WIDOW_CONTROL
@@ -211,6 +210,11 @@
   node *make_tab_node(hunits d, node *next = 0);
   node *get_prev_char();
 public:
+  int seen_space;
+  int seen_eol;
+  int suppress_next_eol;
+  int seen_break;
+  tab_stops tabs;
   const symbol name;
   unsigned char control_char;
   unsigned char no_break_control_char;
@@ -219,6 +223,7 @@
   environment(symbol);
   environment(const environment *);    // for temporary environment
   ~environment();
+  statem *construct_state(int only_eol);
   void copy(const environment *);
   int is_dummy() { return dummy; }
   int is_empty();
@@ -291,11 +296,7 @@
   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(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 *);
+  node *make_tag(const char *name, int i);
   void newline();
   void handle_tab(int is_leader = 0); // do a tab or leader
   void add_node(node *);
@@ -314,6 +315,9 @@
   const char *get_point_size_string();
   const char *get_requested_point_size_string();
   void output_pending_lines();
+  void construct_format_state(node *n, int was_centered, int fill);
+  void construct_new_line_state(node *n);
+  void dump_troff_state();
   
   friend void title_length();
   friend void space_size();
Index: groff/src/roff/troff/input.cpp
diff -u groff/src/roff/troff/input.cpp:1.19 groff/src/roff/troff/input.cpp:1.20
--- groff/src/roff/troff/input.cpp:1.19 Mon Sep 27 06:09:40 2004
+++ groff/src/roff/troff/input.cpp      Sun Oct 10 19:08:03 2004
@@ -19,6 +19,8 @@
 with groff; see the file COPYING.  If not, write to the Free Software
 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 
+#define DEBUGGING
+
 #include "troff.h"
 #include "dictionary.h"
 #include "hvunits.h"
@@ -29,7 +31,6 @@
 #include "token.h"
 #include "div.h"
 #include "charinfo.h"
-#include "stringclass.h"
 #include "font.h"
 #include "macropath.h"
 #include "defs.h"
@@ -117,6 +118,7 @@
 
 double warn_scale;
 char warn_scaling_indicator;
+int debug_state = 0;            // turns on debugging of the html troff state
 
 search_path *mac_path = &safer_macro_path;
 
@@ -195,9 +197,12 @@
 class input_iterator {
 public:
   input_iterator();
+  input_iterator(int is_div);
   virtual ~input_iterator() {}
   int get(node **);
   friend class input_stack;
+  int is_diversion;
+  statem *diversion_state;
 protected:
   const unsigned char *ptr;
   const unsigned char *eptr;
@@ -221,7 +226,12 @@
 };
 
 input_iterator::input_iterator()
-: ptr(0), eptr(0)
+: ptr(0), eptr(0), is_diversion(0)
+{
+}
+
+input_iterator::input_iterator(int is_div)
+: ptr(0), eptr(0), is_diversion(is_div)
 {
 }
 
@@ -415,18 +425,21 @@
   static int is_return_boundary();
   static void remove_boundary();
   static int get_level();
+  static int get_div_level();
   static void increase_level();
   static void decrease_level();
   static void clear();
   static void pop_macro();
   static void save_compatible_flag(int);
   static int get_compatible_flag();
-
+  static statem *get_diversion_state();
+  static void check_end_diversion(input_iterator *t);
   static int limit;
+  static int div_level;
+  static statem *diversion_state;
 private:
   static input_iterator *top;
   static int level;
-
   static int finish_get(node **);
   static int finish_peek();
 };
@@ -434,6 +447,10 @@
 input_iterator *input_stack::top = &nil_iterator;
 int input_stack::level = 0;
 int input_stack::limit = DEFAULT_INPUT_STACK_LIMIT;
+int input_stack::div_level = 0;
+statem *input_stack::diversion_state = NULL;
+int suppress_push=0;
+
 
 inline int input_stack::get_level()
 {
@@ -450,6 +467,11 @@
   level--;
 }
 
+inline int input_stack::get_div_level()
+{
+  return div_level;
+}
+
 inline int input_stack::get(node **np)
 {
   int res = (top->ptr < top->eptr) ? *top->ptr++ : finish_get(np);
@@ -469,6 +491,12 @@
     if (top == &nil_iterator)
       break;
     input_iterator *tem = top;
+    check_end_diversion(tem);
+#if defined(DEBUGGING)
+  if (debug_state)
+    if (tem->is_diversion)
+      fprintf(stderr, "in diversion level = %d\n", 
input_stack::get_div_level());
+#endif
     top = top->next;
     level--;
     delete tem;
@@ -484,6 +512,14 @@
   return (top->ptr < top->eptr) ? *top->ptr : finish_peek();
 }
 
+void input_stack::check_end_diversion(input_iterator *t)
+{
+  if (t->is_diversion) {
+    div_level--;
+    diversion_state = t->diversion_state;
+  }
+}
+
 int input_stack::finish_peek()
 {
   for (;;) {
@@ -493,6 +529,7 @@
     if (top == &nil_iterator)
       break;
     input_iterator *tem = top;
+    check_end_diversion(tem);
     top = top->next;
     level--;
     delete tem;
@@ -522,6 +559,8 @@
 {
   assert(top->is_boundary());
   input_iterator *temp = top->next;
+  check_end_diversion(top);
+
   delete top;
   top = temp;
   level--;
@@ -535,6 +574,37 @@
     fatal("input stack limit exceeded (probable infinite loop)");
   in->next = top;
   top = in;
+  if (top->is_diversion) {
+    div_level++;
+    in->diversion_state = diversion_state;
+    diversion_state = curenv->construct_state(0);
+#if defined(DEBUGGING)
+    if (debug_state) {
+      curenv->dump_troff_state();
+      fflush(stderr);
+    }
+#endif
+  }
+#if defined(DEBUGGING)
+  if (debug_state)
+    if (top->is_diversion) {
+      fprintf(stderr, "in diversion level = %d\n", 
input_stack::get_div_level());
+      fflush(stderr);
+    }
+#endif
+}
+
+statem *get_diversion_state()
+{
+  return input_stack::get_diversion_state();
+}
+
+statem *input_stack::get_diversion_state()
+{
+  if (diversion_state == NULL)
+    return NULL;
+  else
+    return new statem(diversion_state);
 }
 
 input_iterator *input_stack::get_arg(int i)
@@ -613,6 +683,7 @@
   for (input_iterator **pp = &top; *pp != &nil_iterator; pp = &(*pp)->next)
     if ((*pp)->is_file()) {
       input_iterator *tem = *pp;
+      check_end_diversion(tem);
       *pp = (*pp)->next;
       delete tem;
       level--;
@@ -627,6 +698,7 @@
     if (top->is_boundary())
       nboundaries++;
     input_iterator *tem = top;
+    check_end_diversion(tem);
     top = top->next;
     level--;
     delete tem;
@@ -647,6 +719,7 @@
       nboundaries++;
     is_macro = top->is_macro();
     input_iterator *tem = top;
+    check_end_diversion(tem);
     top = top->next;
     level--;
     delete tem;
@@ -1031,6 +1104,7 @@
   int same(node *);
   const char *type();
   int force_tprint();
+  int is_tag();
 };
 
 int non_interpreted_char_node::same(node *nd)
@@ -1048,6 +1122,11 @@
   return 0;
 }
 
+int non_interpreted_char_node::is_tag()
+{
+  return 0;
+}
+
 non_interpreted_char_node::non_interpreted_char_node(unsigned char n) : c(n)
 {
   assert(n != 0);
@@ -1495,6 +1574,7 @@
   int same(node *);
   const char *type();
   int force_tprint();
+  int is_tag();
 };
 
 token_node::token_node(const token &t) : tk(t)
@@ -1526,6 +1606,11 @@
   return 0;
 }
 
+int token_node::is_tag()
+{
+  return 0;
+}
+
 token::token() : nd(0), type(TOKEN_EMPTY)
 {
 }
@@ -2579,12 +2664,16 @@
   return 0;
 }
 
+int global_diverted_space = 0;
+
 int diverted_space_node::reread(int *bolp)
 {
+  global_diverted_space = 1;
   if (curenv->get_fill())
     trapping_blank_line();
   else
     curdiv->space(n);
+  global_diverted_space = 0;
   *bolp = 1;
   return 1;
 }
@@ -2641,10 +2730,33 @@
            tok.next();
          } while (tok.white_space());
          symbol nm = get_name();
+#if defined(DEBUGGING)
+         if (debug_state) {
+           if (! nm.is_null()) {
+             if (strcmp(nm.contents(), "test") == 0) {
+               fprintf(stderr, "found it!\n");
+               fflush(stderr);
+             }
+             fprintf(stderr, "interpreting [%s]", nm.contents());
+             if (strcmp(nm.contents(), "di") == 0 && topdiv != curdiv)
+               fprintf(stderr, " currently in diversion: %s",
+                       curdiv->get_diversion_name());
+             fprintf(stderr, "\n");
+             fflush(stderr);
+           }
+         }
+#endif
          if (nm.is_null())
            skip_line();
-         else
+         else {
            interpolate_macro(nm);
+#if defined(DEBUGGING)
+           if (debug_state) {
+             fprintf(stderr, "finished interpreting [%s] and environment state 
is\n", nm.contents());
+             curenv->dump_troff_state();
+           }
+#endif
+         }
          suppress_next = 1;
        }
        else {
@@ -2652,6 +2764,11 @@
            ;
          else {
            for (;;) {
+#if defined(DEBUGGING)
+             if (debug_state) {
+               fprintf(stderr, "found [%c]\n", ch); fflush(stderr);
+             }
+#endif
              curenv->add_char(charset_table[ch]);
              tok.next();
              if (tok.type != token::TOKEN_CHAR)
@@ -3029,6 +3146,7 @@
 }
 
 macro::macro()
+: is_a_diversion(0)
 {
   if (!input_stack::get_location(1, &filename, &lineno)) {
     filename = 0;
@@ -3041,12 +3159,29 @@
 
 macro::macro(const macro &m)
 : p(m.p), filename(m.filename), lineno(m.lineno), len(m.len),
-  empty_macro(m.empty_macro)
+  empty_macro(m.empty_macro), is_a_diversion(m.is_a_diversion)
 {
   if (p != 0)
     p->count++;
 }
 
+macro::macro(int is_div)
+  : is_a_diversion(is_div)
+{
+  if (!input_stack::get_location(1, &filename, &lineno)) {
+    filename = 0;
+    lineno = 0;
+  }
+  len = 0;
+  empty_macro = 1;
+  p = 0;
+}
+
+int macro::is_diversion()
+{
+  return is_a_diversion;
+}
+
 macro &macro::operator=(const macro &m)
 {
   // don't assign object
@@ -3059,6 +3194,7 @@
   lineno = m.lineno;
   len = m.len;
   empty_macro = m.empty_macro;
+  is_a_diversion = m.is_a_diversion;
   return *this;
 }
 
@@ -3209,11 +3345,12 @@
   void backtrace();
   void save_compatible_flag(int f) { saved_compatible_flag = f; }
   int get_compatible_flag() { return saved_compatible_flag; }
+  int is_diversion();
 };
 
 string_iterator::string_iterator(const macro &m, const char *p, symbol s)
-: mac(m), how_invoked(p),
-  newline_flag(0), lineno(1), nm(s)
+: input_iterator(m.is_a_diversion), mac(m), how_invoked(p), newline_flag(0),
+  lineno(1), nm(s)
 {
   count = mac.len;
   if (count != 0) {
@@ -3239,6 +3376,11 @@
   count = 0;
 }
 
+int string_iterator::is_diversion()
+{
+  return mac.is_diversion();
+}
+
 int string_iterator::fill(node **np)
 {
   if (newline_flag)
@@ -3254,6 +3396,10 @@
   if (*p == '\0') {
     if (np)
       *np = nd->copy();
+    if (is_diversion())
+      (*np)->div_nest_level = input_stack::get_div_level();
+    else
+      (*np)->div_nest_level = 0;
     nd = nd->next;
     eptr = ptr = p + 1;
     count--;
@@ -3441,6 +3587,7 @@
   void add_arg(const macro &m);
   void shift(int n);
   int is_macro() { return 1; }
+  int is_diversion();
 };
 
 input_iterator *macro_iterator::get_arg(int i)
@@ -4953,6 +5100,7 @@
   int same(node *);
   const char *type();
   int force_tprint();
+  int is_tag();
 };
 
 non_interpreted_node::non_interpreted_node(const macro &m) : mac(m)
@@ -4979,6 +5127,11 @@
   return 0;
 }
 
+int non_interpreted_node::is_tag()
+{
+  return 0;
+}
+
 node *non_interpreted_node::copy()
 {
   return new non_interpreted_node(mac);
@@ -5363,6 +5516,7 @@
     environment env2(curenv);
     environment *oldenv = curenv;
     curenv = &env1;
+    suppress_push = 1;
     for (int i = 0; i < 2; i++) {
       for (;;) {
        tok.next();
@@ -5386,6 +5540,7 @@
     delete_node_list(n2);
     curenv = oldenv;
     have_input = 0;
+    suppress_push = 0;
     tok.next();
   }
   else {
@@ -5898,6 +6053,54 @@
   return buf;
 }
 
+void tag()
+{
+  if (!tok.newline() && !tok.eof()) {
+    string s;
+    int c;
+    for (;;) {
+      c = get_copy(0);
+      if (c == '"') {
+       c = get_copy(0);
+       break;
+      }
+      if (c != ' ' && c != '\t')
+       break;
+    }
+    s = "x X ";
+    for (; c != '\n' && c != EOF; c = get_copy(0))
+      s += (char)c;
+    s += '\n';
+    if (is_html)
+      curenv->add_node(new tag_node(s, 0));
+  }
+  tok.next();
+}
+
+void taga()
+{
+  if (!tok.newline() && !tok.eof()) {
+    string s;
+    int c;
+    for (;;) {
+      c = get_copy(0);
+      if (c == '"') {
+       c = get_copy(0);
+       break;
+      }
+      if (c != ' ' && c != '\t')
+       break;
+    }
+    s = "x X ";
+    for (; c != '\n' && c != EOF; c = get_copy(0))
+      s += (char)c;
+    s += '\n';
+    if (is_html)
+      curenv->add_node(new tag_node(s, 1));
+  }
+  tok.next();
+}
+
 // .tm, .tm1, and .tmc
 
 void do_terminal(int newline, int string_like)
@@ -7066,8 +7269,12 @@
     { "version", no_argument, 0, 'v' },
     { 0, 0, 0, 0 }
   };
-  while ((c = getopt_long(argc, argv, "abciI:vw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU",
-                         long_options, 0))
+#if defined(DEBUGGING)
+#define DEBUG_OPTION "D"
+#endif
+  while ((c = getopt_long(argc, argv,
+                         "abciI:vw:W:zCEf:m:n:o:r:d:F:M:T:tqs:RU"
+                         DEBUG_OPTION, long_options, 0))
         != EOF)
     switch(c) {
     case 'v':
@@ -7160,6 +7367,11 @@
     case 'U':
       safer_flag = 0;  // unsafe behaviour
       break;
+#if defined(DEBUGGING)
+    case 'D':
+      debug_state = 1;
+      break;
+#endif
     case CHAR_MAX + 1: // --help
       usage(stdout, argv[0]);
       exit(0);
@@ -7395,6 +7607,8 @@
   init_request("spreadwarn", spreadwarn_request);
   init_request("substring", substring_request);
   init_request("sy", system_request);
+  init_request("tag", tag);
+  init_request("taga", taga);
   init_request("tm", terminal);
   init_request("tm1", terminal1);
   init_request("tmc", terminal_continue);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]