groff
[Top][All Lists]
Advanced

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

[Groff] grohtml and diversions


From: Werner LEMBERG
Subject: [Groff] grohtml and diversions
Date: Mon, 07 Apr 2003 17:06:04 +0200 (CEST)

Gaius,


after some long thinking I believe that I can provide a solution to
the problem how grohtml has to handle diversions without inserting
unwanted whitespace.

The very problem is that we have to preserve the *state* of the troff
engine partially for grohtml, otherwise important high-level
information is lost.  For example, a call to `.ta' normally doesn't
cause anything to be written, but grohtml needs this data to set up
tables properly.

grohtml wants to know the following:

  .br
  .ce
  .fi
  .fl
  .in
  .ll
  .nf
  .po
  .ps
  .rj
  .sp
  .ta
  .ti

As soon as one of those requests is encountered, grohtml currently
adds a special node (equivalent to \X'html-tag: ...') to the current
input line.  In most cases this works, but within diversions it fails.
Consider the following example (already shown in an earlier mail):

  .di xxx
  .ll 5i
  a
  .br
  .ll
  .di
  x\*[xxx]

Normally, the `.ll' right before ending the diversion just changes the
state of troff without any side effects; however, if -Thtml is active,
troff appends a special node (plus a newline input token) to the
diversion which is clearly wrong.

What I've suggested in an earlier mail was not sufficient; I now
think that more changes are necessary.

. First of all, troff must not emit a special html node if there is
  nothing to print.  With other words, troff has to check right before
  emitting a glyph whether the troff state has changed.  In the above
  example, as soon as the letter `a' will be typeset, troff has to
  check whether the line length has been modified and emit a special
  html tag if necessary.  The second `.ll' thus doesn't produce a node
  in the diversion.  Technically speaking, all calls to `add_html_tag'
  have to be moved to `environment::add_char'.

. Secondly, the troff state must be emitted twice, once within the
  diversion (using the internal equivalent of \!\X'...') and once
  after ending the diversion.  Consider the following example:

    .di xxx
    .ll 5i
    a
    .br
    .di
    x\*[xxx]

  Before starting the diversion `xxx', troff has to save the state
  relevant to grohtml on a stack.  Then the line `.ll 5i' makes troff
  emit something like

    \!\X'html-tag: .ll 5i'

  as soon as the letter `a' will be added to the current line.  After
  ending the diversion, troff has to compare the saved state with the
  current one.  It will discover that the line length has changed, and
  it will emit

    \X'html-tag: .ll 5i'

  as soon as the letter `x' will be added to the current line.

. Thirdly, troff has to keep track of the values emitted with
  `html-tag:' (let's call this the html state -- this is something
  different from the state of troff described in the previous item).
  If a diversion is read, troff must save the html state before
  inserting the diversion into the input token stream and restore it
  afterwards.  Consider this example:

    .di xxx
    .ll 5i
    a
    .br
    .ll
    .di
    .ll 3i
    x\*[xxx]

  While `xxx' is read, the \!\X'html-tag: .ll 5i' is finally
  expanded.  After ending the diversion, grohtml still assumes a line
  length of 5i, so troff must emit the internal equivalent to

    \X'html-tag: .ll 3i'

  immediately afterwards.

I hope that my ideas are understandable...


    Werner

reply via email to

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