[Top][All Lists]
[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
- [Groff] grohtml and diversions,
Werner LEMBERG <=