The typehtml package^{∗}

David Carlisle

1996/03/25

1 Intoduction

This package enables the processing of HTML codes. The \dohtml command allows fragments of HTML to be placed within a L^{A}TEX document,

 \dohtml
 <html>
 html markup ...
 </html>

The <html>… </html> is required. (It is anyway a good idea to have these tags in an HTML document.)

The \htmlinput command is similar, but takes a file name as argument. In that case the file need not necessarily start and end with <html>… </html>.

This package covers most of the HTML2 DTD, together with the mathematics extensions from HTML3.^{1} The rest of HTML3 may be added at a later date.

Its current incarnation has not been extensively tested, having been thrown together during the last couple of weeks in response to a question on comp.text.tex about the availability of such a package.

The package falls into three sections. Firstly the options section allows a certain amount of customisation, and enabling of extensions. Not all these options are fully operational at present. Secondly comes a section that implements a kind of SGML parser. This is not a real conforming SGML parser (not even a close approximation to such a thing!) The assumption (sadly false in the anarchic WWW) is that any document will have been validated by a conforming SGML parser before it ever gets to the stage of being printed by this package. Finally are a set of declarations that essentially map the declarations of the HTML DTD into L^{A}TEX constructs.

2 Options

2.1 HTML Level

The options html2 (the default) and html3 control HTML variant supported. Using the the html3 will use up a lot more memory to support the extra features, and the math entity (symbol) names. Against my better judgement there is also a netscape option to allow some of the non-HTML tags accepted by that browser.

∗This file has version number v0.10, last revised 1996/03/25.

1The draft specification of HTML3 has expired, and the W3C group are currently devising a new proposed extension of HTML, so the mathematics typesetting part of this package may need substantial revision once a final specification of the HTML mathematics markup is agreed.

2.2 Headings

The six options chapter, chapter*, section, section*, subsection and

subsection* Determine to which L^{A}TEX sectional command the HTML element h1 is mapped. (h2–h6 will automatically follow suit.) The default is section.

2.3 Double Quote Handling

Most HTML pages use " as as a quotation mark in text, for example:

 quoted "like this" example

This slot in the ISO latin-1 encoding is for ‘straight’ double quotes. Unfortunately the Standard TEX fonts in the OT1 encoding do not have such a character, only left and right quotes, “like this”. By default this package uses the straightquotedbl option which uses the L^{A}TEX command \textquotedbl to render ". If used with the T1 encoded fonts \usepackage[T1]{fontenc} then the straight double quote from the current font is used. With OT1 fonts, the double quote is taken from the \ttfamily font, which looks "like this" which is fairly horrible, but better than the alternative which is ”like this”.

The smartquotedbl option redefines " so that it produces alternatively an open double quote “ then a close ”. As there is a chance of it becoming confused, it is reset to “ at the beginning of every paragraph, whatever the current mode.

Neither of these options affects the use of " as part of the SGML syntax to surround attribute values.

In principle the package ought to have similiar options deaing with the single quote, but their the situation is more complicated due to its dual use as an apostrophe, so currently the package takes no special precautions: all single qutoes are treated as a closing quote/apostrophe. Also the conventions of ‘open’ and ‘close’ quotes only really apply to English. If someone want’s to suggest what the package should do with " in other languages…

2.4 Images

The default option is imgalt This means that all inline images (the HTML img element) are replaced by the text specified by the alt attribute, or [image] if no such attribute is specified.

The imggif option^{2} uses the \includegraphics command so that inline images appear as such in the printed version.

The imgps option^{1} is similar to imggif but first replaces the extension .gif at the end of the source file name by .ps. This will enable drivers that can not include GIF files to be used, as long as the user keeps the image in both PostScript and Gif formats.

2one day

2.5 Hyperref

Several options control how the HTML anchor tag is treated.

The default nohyperref option ignores name anchors, and typesets the body of src elements using \emph.

The ftnhyperref option is similar to nohyperref, but adds a footnote showing the destination address of each link, as specified by the SRC attribute.

If the hyperref option is specified, the hypertext markup in the HTML file will be replicated using the hypertext specials of the HyperTEX group. If in addition the hyperref package is loaded, the extra features of that package may be used, for instance producing ‘native PDF’ specials for direct use by Adobe distiller rather than producing the specials of the hyperTEX conventions.

The dviwindo option converts the hypertext information in the HTML into the \special conventions of Y&Y’s dviwindo previewer for Microsoft Windows.

2.6 Big Integrals

L^{A}TEX does not treat integral signs as variable sized symbols, in the way that it treats delimiters such as brackets. In common with summation signs and a few other operators, they come in just two fixed sizes, a small version for inline mathematics, and a large version used in displays. In fact by default L^{A}TEX always uses the same two sizes (from the 10pt math extension font) even if the document class has been specified with a size option such as 12pt, or if a size comand such as \large has been used.

The standard exscale package loads the math extension font at larger sizes if the current font size is larger than 10 pt.

The HTML3 math description explicitly states that integral signs should be treated like delimiters and stretch if applied to a large math expression. By default this package ignores this advice and treats integral signs in the standard way, however an option bigint does cause integral signs to ‘stretch’ (or at least be taken from a suitably large font). The standard Computer Modern fonts use a very ‘sloped’ integral which means that they are not really suitable for being stretched. Some other math fonts, for instance Lucida, have more vertical integral signs, and one could imagine in those cases making an integral sign with a ‘repeatable’ vertical middle section so that it could grow to an arbitrary size, in the way that brackets grow.

3 Latin-1 characters

The SGML character entities for the ISO-Latin1 characters such as &eacute; are recognised by this style, although as usual, some of them such as the Icelandic thorn character, &thorn;, \th, produce an error if the old ‘OT1’ encoded fonts are being used. These characters will print correctly if ‘T1’ encoded fonts are used,

for example by declaring \usepackage[T1]{fontenc} .

HTML also allows direct 8-bit input of characters according to the ISO-latin1 encoding, to enable this you need to enable latin-1 input for L^{A}TEX with a decla-

ration such as \usepackage[latin1]{inputenc} .

4 Mathematics

The HTML3 MATH element is fairly well supported, including the BOX and CLASS attributes. (Currently only CHEM value for class is supported, and as far as I can see the BOX attribute is only in the report, not in the dtd.) The super and subscripts are supported, including the shortref maps, however only the default right alignment is implemented so far. The convention described in the draft report for using white space to distinguish superscript positioning is fairly horrible!

The documentation that I could find on HTML3 did not include a full list of the entity names to be used for the symbols. This this package currently only defines the following entities, which should be enough for testing purposes at least.

gt (>) lt (<) (Already in the HTML2 DTD)

Some Greek letters.

   alpha (α) beta (β) gamma (γ) Gamma (Γ)

Integral and Sum. ∫ grows large if the bigint package option is given.

   int (∫) sum (∑)

Braces (The delimiters ()[] also stretch as expected in the BOX element)

   lbrace ({) rbrace (})

A random collection of mathematical symbols:

   times (×) cup (∪) cap (∩) vee (∨) wedge (∧) infty (∞) oplus (⊕) ominus
(⊖) otimes (⊗)

A Minimal set of trig functions:

sin (sin) cos (cos) tan (tan)

Also in the special context as attributes to ABOVE and BELOW elemnts the entrities:

overbrace ( ) underbrace ( ) and any (TEX) math accent name.

5 SGML Minimisation features

SGML (and hence HTML) support various minimisation features that aim to make it easier to enter the markp ‘by hand’. These features make the kind of ‘casual’ attempt at parsing SGML as implemented in this package somewhat error prone.

Two particular features are enabled in HTML. The so called SHORTTAG feature means that the name of a tag may be omitted if it may be inferred from the context. Typically in HTML this is used in examples like

 <title>A Document Title</>

The end tag is shortened to </> and the system infers that TITLE is the element to be closed.

The second form of minimisation enabled in HTML is the OMITTAG feature. Here a tag may be omitted altogether in certain circumstances. A typical example is the HTML list, where each list item is started with <li> but the closing </li> at the end of the item may be omitted and inferred by the following <li> or </ol> tag.

This package is reasonably robust with respect to omitted tags. However it only makes a half hearted attempt at supporting the SHORTTAG feature. The TITLE example above would work, but nested elements, with multiple level of minimised end tags will probably break this package.

It would be possible to build a L^{A}TEX system that had full knowledge of the HTML (or any other) DTD and in particular the ‘content model’ of every element, this would produce a more robust parsing system but would take longer than I was prepared to spend this week… In anycase if you need a fully conforming SGML parser, it probably makes sense to use an existing one (excellent free parsers are freely available) and then convert the output of the parser to a form suitable for L^{A}TEX. In that way all such concerns about SGML syntax features such as minimisation will have been resolved by the time L^{A}TEX sees the document.

6 Examples

6.1 A section

This document uses the subsection* option.

 <h1>HTML and LaTeX</h1>

HTML and LaTeX

6.2 An itemised list

 <ul>
 <li> something
 <li> something else
 </ul>

• something

• something else

6.3 Latin1 Characters

 &eacute; &ouml;

é ö

6.4 Images

Currently only the ALT attribute is supported.

 This is an image of me <img alt="DPC" src="dpc.gif">

This is an image of me DPC

6.5 A form

 <form
   action="http://www.cogs.susx.ac.uk/cgi-bin/ltxbugs2html"
   method=get><hr>
 You can search for all the bug reports about: <select name="category">
 <option>AMS LaTeX</option>
 <option>Babel</option>
 <option>Graphics and colour</option>

<option>LaTeX</option>
<option selected>Metafont fonts</option>
<option>PostScript fonts</option>
<option>Tools</option>
</select>
<hr>
</form>

You can search for all the bug reports about: category

AMS LaTeX

Babel

Graphics and colour LaTeX

• Metafont fonts PostScript fonts Tools

6.6 Styles of Mathematics

<math>
H_2_O + CO_2_
</math>
<math class=chem>
H_2_O + CO_2_
</math>
<math box>
H_2_O + CO_2_
</math>
<math class=chem box>
H_2_O + CO_2_
</math>

H_{2}O + CO_{2}

H_{2}O + CO_{2}

H_{2}O + CO_{2}

H_{2}O + CO_{2}

6.7 Integrals

Stretchy integrals with the bigint option.

<math>
{&int;^1^_3_<left>
   1
 <over>
   {x+{1<over>x+{2<over>x+

      {3<over>x+{4<over>x}}}}}
<right>dx}
</math>

∫_{3}^{1} \frac{1}{x +_{\frac{1}{x+_{\frac{2}{x+\frac{3}{x+\frac{4}{x}}}}}}} dx

And the same integral with the standard integral sign.

∫_{3}^{1} \frac{1}{x +_{\frac{1}{x+_{\frac{2}{x+\frac{3}{x+\frac{4}{x}}}}}}} dx

6.8 Oversized delimiters

<math>
<box>(<left>1 <atop> 2 <right>)</box>
<box size=large>(<left>1 <atop> 2 <right>)</box>
</math>

\binom{1}{2}({1 \atop 2})

6.9 Roots, Overbraces etc

<math>
<above sym=overbrace>  abc </above><sup>k</sup>
&emsp;
<root>3<of>x</root>
<sqrt>5</sqrt>
&emsp;
<below sym=underline>  abc </below>
<above sym=widehat>  abc </above>
</math>

\overbrace{abc}^{k}  ^{3} \sqrt{x}\sqrt{5} \underline{abc}âbc

6.10 Arrays

<math>
aa<array align=top>
<row><item><text>first col</text><item><text>second col</text><item>

<text>third col</text><item><text>fourth col</text>
<row><item><text>row 2</text><item> a_22_<item>a_23_<item>a_24_
<row><item><text>row 3</text><item rowspan=3 colspan=2>
                                           a_32_-a_53_<item>a_34_
<row><item><text>row 4</text><item>a_44_
<row><item><text>row 5</text><item>a_54_
<row><item><text>row 6</text><item align=left>
                                   al_62_<item>a_63_<item>a_64_
<row><item><text>row 7</text><item align=right>
                                   ar_72_<item>a_73_<item>a_74_
</array>bb
</math>

aa first col  second col  third col  fourth col row 2  a_{22}  a_{23}  a_{24} row 3  a_{32} − a_{53}  a_{34} row 4  a_{44} row 5  a_{54} row 6  al_{62}  a_{63}  a_{64} row 7  ar_{72}  a_{73}  a_{74}bb

Repeat that element, but change the ARRAY attributes as follows:

<array ldelim="(" rdelim=")" labels>

aa first col  second col  third col  fourth col ( \begin{matrix}row 2 & a_{22} & a_{23} & a_{24} \\ row 3 & a_{32} − a_{53} & & a_{34} \\ row 4 & & & a_{44} \\ row 5 & & & a_{54} \\ row 6 & al_{62} & a_{63} & a_{64} \\ row 7 & ar_{72} & a_{73} & a_{74} \end{matrix}  )bb

and finally an example of COLSPEC

<math>
<array colspec="R+C=L">
<row><item>abc_11_<item>abc_12_<item>abc_13_
<row><item>a_21_<item>a_22_<item>a_23_
<row><item>a_31_<item>a_32_<item>a_33_
</array>
</math>

\begin{aligned}abc_{11} & + abc_{12} & = abc_{13} \\ a_{21} & + a_{22} & = a_{23} \\ a_{31} & + a_{32} & = a_{33} \end{aligned}

7 The Code

7.1 Option Handling

1 ⟨∗package⟩

 2 \DeclareOption{html2}{\let\HTML@two@stop\endinput}
 3 \DeclareOption{netscape}
 4  {\def\HTML@not#1{\SGML@w{<#1> is not valid HTML}}}
 5 \DeclareOption{html3}{\let\HTML@two@stop\relax}
 6 \DeclareOption{nohyperref}{%
 7 \let\HTML@doname\@secondoftwo
 8 \def\HTML@dosrc#1#2{\emph{#2}}}
 9 \DeclareOption{ftnhyperref}{%
10 \let\HTML@doname\@secondoftwo
11 \def\HTML@dosrc#1#2{\emph{#2}\footnote{HREF: \texttt{#1}}}}
12 \DeclareOption{hyperref}{%
13 \AtBeginDocument{%
14  \providecommand\href[2]{\special{html:<A href="#1">}%
15  #2\special{html:</A>}}%
16  \providecommand\hypertarget[2]{\special{html:<A name="#1">}%
17  #2\special{html:</A>}}%
18  \let\HTML@doname\hypertarget
19  \let\HTML@dosrc\href}}

Currently only corectly deals with links within a document so a src attribute should always specify a "#name" format. It detects a more general URL and fires a launch: action from the \special, which calls the non-existant command typehtml. Presumably this could be a batch file that calls netscape or some other WWW engine to process the URL.

20 \DeclareOption{dviwindo}{%
21 \def\HTML@dosrc#1#2{{%
22  \leavevmode\sbox\z@{#2}\count@\ht\z@\@tempcnta\wd\z@
23  \if\string##\@car#1\@nil
24  \special{button: \the\@tempcnta\space\the\count@\space
25  "\@gobble#1"}%
26  \else
27  \special{button: \the\@tempcnta\space\the\count@\space
28  launch: typehtml "#1"}
29  \fi
30  \special{color push}\special{color rgb 0 1 0}%
31  \unhbox\z@
32  \special{color pop}}}%
33 \def\HTML@doname#1#2{\leavevmode\special{mark: "#1"}#2}}%
34 \DeclareOption{imgalt}{}
35 \DeclareOption{imggif}{\SGML@w{img gif support not done yet}}
36 \DeclareOption{imgps}{\SGML@w{img ps support not done yet}}
37 \DeclareOption{smartquotedbl}{%
38 \def\SGMLquotedbla{%
39  \textquotedblleft\global\let\SGMLquotedbl\SGMLquotedblb}
40 \def\SGMLquotedblb{%

41  \textquotedblright\global\let\SGMLquotedbl\SGMLquotedbla}
42 \let\SGMLquotedbl\SGMLquotedbla
43 \let\SGML@savedeverypar\everypar
44 \newtoks\everypar
45 \SGML@savedeverypar{%
46  \global\let\SGMLquotedbl\SGMLquotedbla\the\everypar}}

47

48 \DeclareOption{straightquotedbl}{%
49 \DeclareTextCommandDefault{\textquotedbl}{{\ttfamily\char`\"}}%
50 \let\SGMLquotedbl\textquotedbl}
51 \DeclareOption{chapter}{%
52 \def\HTML@headings{%
53  \chapter\section\subsection%
54  \subsubsection\paragraph\subparagraph}}
55 \DeclareOption{chapter*}{%
56 \def\HTML@headings{%
57  {\chapter*}{\section*}{\subsection*}%
58  {\subsubsection*}{\paragraph*}{\subparagraph*}}}
59 \DeclareOption{section}{%
60 \def\HTML@headings{%
61  \section\subsection%
62  \subsubsection\paragraph\subparagraph\endgraf}}
63 \DeclareOption{section*}{%
64 \def\HTML@headings{%
65  {\section*}{\subsection*}%
66  {\subsubsection*}{\paragraph*}{\subparagraph*}\endgraf}}
67 \DeclareOption{subsection}{%
68 \def\HTML@headings{%
69  \subsection%
70  \subsubsection\paragraph\subparagraph\endgraf\endgraf}}
71 \DeclareOption{subsection*}{%
72 \def\HTML@headings{%
73  {\subsection*}%
74  {\subsubsection*}{\paragraph*}{\subparagraph*}\endgraf\endgraf}}
75 \DeclareOption{bigint}{%
76 \let\HTML@int\int
77 \AtEndOfPackage{\RequirePackage{exscale}}}
78 \ExecuteOptions{section*,imgalt,html2,nohyperref,straightquotedbl}
79 \ProcessOptions

7.2 Fake SGML parser

80 \begingroup
81 \catcode`\<=\active
82 \catcode`\&=\active
83 \catcode`\$=\active
84 \catcode`\"=\active
85 \catcode`\^=\active
86 \catcode`\_=\active

 87 \catcode`\A=\active
 88 \catcode`\B=\active
 89 \catcode`\C=\active
 90 \catcode`\D=\active
 91 \lccode`\A=`\{%
 92 \lccode`\B=`\}%
 93 \lccode`\C=`\|%
 94 \lccode`\D=`\\%
 95 \lowercase{\endgroup
 96 \def\dohtml{%
 97 \begingroup
 98 \catcode`\<=\active
 99 \catcode`\&=\active
100 \catcode`\{=\active
101 \catcode`\}=\active
102 \catcode`\$=\active
103 \catcode`\"=\active
104 \catcode`\^=\active
105 \catcode`\_=\active
106 \catcode`\\=\active
107 \catcode`\|=\active
108 \catcode\endlinechar=10
109 \catcode`\%=12
110 \catcode`\#=12
111 \catcode`\;=12
112 \def\verbatim@nolig@list{\do\`\do\,\do\'\do\-}
113 \def<{\SGMLopen}%
114 \def&{\SGMLent}%
115 \let^\textasciicircum
116 \let~\textasciitilde
117 \def_{\_}%
118 \let$\$%
119 \def"{\SGMLquotedbl}%
120 \def A{\{}%
121 \def B{\}}%
122 \def C{\texttt{|}}%
123 \def D{\texttt{\char`\\}}%

Need to be careful about writing to table of contents.

124 \def\addcontentsline##1##2##3{%
125  {\def<{\string<}\def&{\string&}%
126  \addtocontents{##1}{\protect\dotochtml<html>}%
127  \addtocontents{##1}{\protect\contentsline{##2}{##3}{\thepage}}%
128  \addtocontents{##1}{\protect</html>}}}}

\dotochtml A ‘compromise’ version of \dohtml for use in table of contents files. Allows HTML markup <, & etc, but also TEX markup \, {, }. As these are incompatible, this is not 100% reliable but it seems to cover most cases in practice.

129 \def\dotochtml{%
130 \dohtml
131 \catcode`\\\z@
132 \catcode`\{\@ne
133 \catcode`\}\tw@}

\SGMLshortend
134 \def\SGMLshortend{/}
\SGMLgrab@
135 \def\SGMLgrab@#1<#2>{%
136 \edef\@tempd{\lowercase{\def\noexpand\@tempd{\gobblespc#2 \relax}}}%
137 \@tempd
138 \ifx\@tempd\SGMLshortend\let\@tempd\@tempc\fi
139 \ifx\@tempb\@tempd
140 \advance\@tempcnta\@ne
141 \else
142  \ifx\@tempc\@tempd
143  \advance\@tempcnta\m@ne
144  \fi
145 \fi
146 \ifnum\@tempcnta=\z@
147  \expandafter\@tempa\expandafter{\the\@temptokena#1}%
148 \else
149  \addto@hook\@temptokena{#1<#2>}%
150  \expandafter\SGMLgrab@
151 \fi}

152 }

\htmlinput
153 \def\htmlinput#1{\dohtml\let\@endhtml\relax\input{#1}\endgroup}
\gobblespc
154 \def\gobblespc#1 #2\relax{#1}
\SGMLgrabber
155 \def\SGMLgrabber#1#2{%
156 \def\@tempa{#2}%
157 \@tempcnta\@ne
158 \@temptokena{}%
159 \lowercase{\def\@tempb{#1}\def\@tempc{/#1}}%
160 \SGMLgrab@}
\SGMLopen
161 \begingroup
162 \catcode`\"=\active
163 \uppercase{\endgroup
164 \def\SGMLopen#1>{%
165 \SGMLopen@#1 \@nil}
\SGMLopen@
166 \def\SGMLopen@#1 #2\@nil{%
167 \toks@{}%
168 \edef\@tempa{\lowercase{\def\noexpand\SGMLelement{#1}}}\@tempa
169 \if!\@car#1\relax\@nil
170  \toks@{#1 #2}%
171  \SGML@w{Declaration ignored\MessageBreak<\the\toks@>\MessageBreak}%
172 \else

173  \if$#2$\else
174  \replacequotes#2"\@nil"%
175  \SGMLafterfi
176  \expandafter\toks@\expandafter{\expandafter}%
177  \expandafter\SGMLgetattrib\the\toks@ \@nil
178  \fi
179  \expandafter\ifx\csname SGML@\SGMLelement
180  \expandafter\endcsname\relax
181  \SGML@w{<\SGMLelement> undefined}%
182  \else
183  \csname SGML@\SGMLelement
184  \expandafter\expandafter\expandafter\endcsname
185  \fi
186 \fi}
\replacequotes
187 \def\replacequotes#1"#2"{%
188 \def\@tempb{#2}%
189 \ifx\@tempb\@nnil
190  \addto@hook\toks@{#1}%
191 \else
192  \addto@hook\toks@{#1{#2}}%
193 \expandafter\replacequotes
194 \fi}}
\SGMLafterfi
195 \def\SGMLafterfi#1\fi{\fi#1}
\SGMLgobbletofi
196 \def\SGMLgobbletofi#1\fi{\fi}
\SGMLgetattrib
197 \def\SGMLgetattrib#1 #2{%
198 \ifx\box#1\box\else
199  \SGMLgetval#1=$=\@nil
200  \def\@tempa{#2}%
201  \ifx\@tempa\@nnil
202  \expandafter\SGMLgobbletofi
203  \else
204  \expandafter\SGMLafterfi
205  \fi
206  \SGMLgetattrib#2%
207 \fi}

\SGMLgetval If no value was supplied #2 will be $ (Even if the value is $ The test is false, as that would be catcode 13. Done this way rather than looking for empty to distinguish alt="" with empty value.

208 \def\SGMLgetval#1=#2=#3\@nil{%
209 \ifcat$#2%
210  \lowercase{\SGML@addattrib\doimplied{#1}}%
211 \else
212  \lowercase{\SGML@addattrib{\do{#1}}}{#2}%
213 \fi}

\SGML@addattrib
214 \def\SGML@addattrib#1#2{\addto@hook\toks@{#1{#2}}}
\SGML@w
215 \def\SGML@w{\PackageWarning{typehtml}}
\SGMLdef
216 \def\SGMLdef<#1>{%
217 \expandafter\def\csname SGML@#1\endcsname}
\SGMLent
218 \expandafter\def\expandafter\SGMLent\expandafter{%
219 \expandafter\protect\csname& \endcsname}
&
220 \expandafter\def\csname& \endcsname{%
221 \futurelet\@let@token\SGMLent@}
\SGMLent@
222 \def\SGMLent@{%
223 \ifx\@let@token\@sptoken
224  \&%
225 \else
226  \expandafter\SGMLent@@
227 \fi}
\SGMLent@@
228 \def\SGMLent@@#1;{%
229 \csname SGML@E@#1\endcsname}
\SGMLentity
230 \def\SGMLentity#1{%
231 \expandafter\def\csname SGML@E@#1\endcsname}

7.3 The HTML2 DTD

232 \SGMLdef<html>{}
233 \SGMLdef</html>{\@endhtml}
234 \let\@endhtml\endgroup
235 \SGMLdef<title>{\typeout{***TITLE***}\SGMLgrabber{title}\typeout}
236 \long\def\@tempa#1#2#3#4#5#6{%
237 \SGMLdef<h1>{\SGMLgrabber{h1}{\HTMLsection{#1}}}%
238 \SGMLdef<h2>{\SGMLgrabber{h2}{\HTMLsection{#2}}}%
239 \SGMLdef<h3>{\SGMLgrabber{h3}{\HTMLsection{#3}}}%
240 \SGMLdef<h4>{\SGMLgrabber{h4}{\HTMLsection{#4}}}%
241 \SGMLdef<h5>{\SGMLgrabber{h5}{\HTMLsection{#5}}}%
242 \SGMLdef<h6>{\SGMLgrabber{h6}{\HTMLsection{#6}}}}
243 \expandafter\@tempa\HTML@headings
244 \def\HTMLsection#1#2{#1{\ignorespaces#2\unskip}}
245 \SGMLdef<head>{}
246 \SGMLdef</head>{}

247 \SGMLdef<body>{}
248 \SGMLdef</body>{}
249 \SGMLdef<bodytext>{}
250 \SGMLdef</bodytext>{}
251 \SGMLdef<p>{\par}
252 \SGMLdef</p>{\par}
253 \SGMLdef<blockquote>{\begin{quote}}
254 \SGMLdef</blockquote>{\end{quote}}
255 \SGMLdef<address>{\begin{quote}}
256 \SGMLdef</address>{\end{quote}}
257 \SGMLdef<ul>{\begin{itemize}}
258 \SGMLdef</ul>{\end{itemize}}
259 \SGMLdef<ol>{\begin{enumerate}}
260 \SGMLdef</ol>{\end{enumerate}}
261 \SGMLdef<li>{\item}
262 \SGMLdef</li>{}
263 \SGMLdef<dl>{%
264 \let\do\dldo
265 \let\doimplied\dlimplied
266 \begin{description}\the\toks@}
267 \SGMLdef</dl>{\end{description}}
268 \def\dldo#1#2{%
269 \def\@tempa{compact}\def\@tempb{#1}%
270 \ifx\@tempa\@tempb
271  \itemsep\z@
272  \advance\@totalleftmargin-\leftmargin
273  \advance\linewidth\leftmargin
274  \itemindent-\labelsep
275  \leftmargin\z@
276  \parshape \@ne \@totalleftmargin \linewidth
277 \fi}
278 \def\dlimplied#1{\dldo{#1}\relax}
279 \def\itx#1{\item[#1]}
280 \SGMLdef<dt>{\begin{lrbox}\z@\bfseries\let\maybeenddt\enddt}
281 \SGMLdef</dt>{\maybeenddt}
282 \SGMLdef<dd>{\maybeenddt}
283 \SGMLdef</dd>{}
284 \def\enddt{\end{lrbox}\item[\unhbox\z@]}
285 \let\maybeenddt\relax
286 \SGMLdef<a>{\SGMLgrabber{a}\HTML@anchor}

\HTML@anchor This handles the A tag.

287 \def\HTML@anchor#1{{%
288 \let\@tempa\@gobble
289 \def\_{\string_}%
290 \let\do\ado
291 \the\toks@
292 \@tempa{#1}}}

\ado Thanks to SPQR for first pass at integrating hyperref.

293 \def\ado#1#2{%
294 \def\@tempb{name}\def\@tempc{#1}%
295 \ifx\@tempb\@tempc
296  \let\@tempa\@firstofone
297  \def\@tempa{\HTML@doname{#2}}%
298 \else
299  \def\@tempa{\HTML@dosrc{#2}}%
300 \fi}
301 \SGMLdef<pre>{%
302 \par
303 \begingroup
304 \obeylines\verbatim@font\@noligs
305 \endlinechar`\^^M%
306 \frenchspacing\@vobeyspaces\HTMLprefudge}
307 \def\HTMLprefudge#1{%
308 \if\space\noexpand#1\else\expandafter#1\fi}
309 \SGMLdef</pre>{\endgroup}
310 \SGMLdef<tt>{\SGMLgrabber{tt}\texttt}
311 \SGMLdef<b>{\SGMLgrabber{b}\textbf}
312 \SGMLdef<i>{\SGMLgrabber{i}\textit}
313 \SGMLdef<em>{\SGMLgrabber{em}\emph}
314 \SGMLdef<strong>{\SGMLgrabber{code}\textbf}
315 \SGMLdef<code>{\SGMLgrabber{code}\texttt}
316 \SGMLdef<samp>{\SGMLgrabber{samp}\textsf}
317 \SGMLdef<kbd>{\SGMLgrabber{kbd}\texttt}
318 \SGMLdef<var>{\SGMLgrabber{var}\textit}
319 \SGMLdef<cite>{\SGMLgrabber{cite}\textit}
320 \SGMLdef<form>{\par\medskip}
321 \SGMLdef</form>{\par\medskip}
322 \SGMLdef<select>{%
323 \let\do\selectdo
324 \the\toks@\par
325 \begin{tabular}{|l|}%
326 \hline\@tempc\\\hline
327 \let\tabularnewline\relax
328 \ignorespaces}
329 \def\selectdo#1#2{%
330 \def\@tempa{name}\def\@tempb{#1}%
331 \ifx\@tempa\@tempb\def\@tempc{#2}\fi}
332 \SGMLdef</select>{\\\hline\end{tabular}}
333 \SGMLdef<option>{%
334 \gdef\optionbul{\phantom{$\bullet$}}%
335 \let\do\optiondo
336 \let\doimplied\optionimplied
337 \the\toks@
338 \tabularnewline
339 \let\tabularnewline\\%
340 \optionbul\space\ignorespaces}
341 \SGMLdef</option>{}

\optiondo Handle attributes to the OPTION element.

342 \def\optiondo#1#2{%
343 \def\@tempa{selected}\def\@tempb{#1}%
344 \ifx\@tempa\@tempb\gdef\optionbul{$\bullet$}\fi}

\optionimplied Handle the case where just the attribute value is given.

345 \def\optionimplied#1{%
346 \def\@tempa{selected}\def\@tempb{#1}%
347 \ifx\@tempa\@tempb\gdef\optionbul{$\bullet$}\fi}
348 \SGMLdef<input>{}
349 \SGMLdef<img>{{%
350 \let\do\imgdo
351 \def\@tempa{\doimage}%
352 \the\toks@
353 \@tempa}}
354 \def\doimage{\textsf{[image]}}

\imgdo Handle IMG attributes (not very usefully)

355 \def\imgdo#1{\csname img=#1\endcsname}
356 \expandafter\def\csname img=align\endcsname#1{%
357 \SGML@w{align=#1 ignored}}
358 \expandafter\def\csname img=src\endcsname#1{%
359 \SGML@w{src=#1 ignored}}
360 \expandafter\def\csname img=height\endcsname#1{%
361 \SGML@w{height=#1 ignored}}
362 \expandafter\def\csname img=alt\endcsname#1{%
363 \def\doimage{#1}}

Horizontal rules and line breaks.

364 \SGMLdef<hr>{\par\smallskip\hrule\smallskip}
365 \SGMLdef<br>{\\}
366 \SGMLdef<xmp>{%
367 \begingroup\endlinechar=`\^^M\obeylines\obeyspaces
368 \ttfamily
369 \def\@tempb{/xmp>}%
370 \let\SGMLopen\HTML@xmptest%
371 \let\SGMLent\&}
372 \SGMLdef<listing>{%
373 \SGML@xmp
374 \def\@tempb{/listing>}%
375 \let\SGMLopen\HTML@listingtest}
376 \SGMLdef<plaintext>{%
377 \SGML@xmp
378 \def\@tempb{/plaintex}%
379 \let\SGMLopen\HTML@plaintexttest}
\HTML@xmptest
380 \def\HTML@xmptest#1#2#3#4#5{%
381 \lowercase{\def\@tempa{#1#2#3#4#5}}%
382 \ifx\@tempa\@tempb

383  \endgroup
384 \else
385  <\expandafter\@tempa
386 \fi}
\HTML@listingtest
387 \def\HTML@listingtest#1#2#3#4#5#6#7#8#9{%
388 \lowercase{\def\@tempa{#1#2#3#4#5#6#7#8#9}}%
389 \ifx\@tempa\@tempb
390  \endgroup
391 \else
392  <\expandafter\@tempa
393 \fi}
\HTML@plaintexttest
394 \def\HTML@plaintexttest#1#2#3#4#5#6#7#8#9{%
395 \lowercase{\def\@tempa{#1#2#3#4#5#6#7#8#9}}%
396 \ifx\@tempa\@tempb
397  \endgroup\expandafter\@gobbletwo
398 \else
399  <\expandafter\@tempa
400 \fi}

SGML syntax Character entities.

401 \SGMLentity{amp}{\&}
402 \SGMLentity{lt}{\ensuremath{<}}
403 \SGMLentity{gt}{\ensuremath{>}}

ISO Latin-1 Character entities.

404 \SGMLentity{aacute}{\'a}
405 \SGMLentity{Aacute}\'A{}
406 \SGMLentity{acirc}{\^a}
407 \SGMLentity{Acirc}{\^A}
408 \SGMLentity{agrave}{\`a}
409 \SGMLentity{Agrave}{\`A}
410 \SGMLentity{aring}{\r a}
411 \SGMLentity{Aring}{\r A}
412 \SGMLentity{atilde}{\~a}
413 \SGMLentity{Atilde}{\~A}
414 \SGMLentity{auml}{\"a}
415 \SGMLentity{Auml}{\"A}
416 \SGMLentity{aelig}{\ae}
417 \SGMLentity{AElig}{\AE}
418 \SGMLentity{ccedil}{\c c}
419 \SGMLentity{Ccedil}{\c C}
420 \SGMLentity{eth}{\dh}
421 \SGMLentity{ETH}{\DH}
422 \SGMLentity{eacute}{\'e}
423 \SGMLentity{Eacute}{\`E}
424 \SGMLentity{ecirc}{\^e}
425 \SGMLentity{Ecirc}{\^E}
426 \SGMLentity{egrave}{\`e}
427 \SGMLentity{Egrave}{\`E}
428 \SGMLentity{euml}{\"e}

429 \SGMLentity{Euml}{\"E}
430 \SGMLentity{iacute}{\'\i}
431 \SGMLentity{Iacute}{\'I}
432 \SGMLentity{icirc}{\^\i}
433 \SGMLentity{Icirc}{\^I}
434 \SGMLentity{igrave}{\`\i}
435 \SGMLentity{Igrave}{\`I}
436 \SGMLentity{iuml}{\"\i}
437 \SGMLentity{Iuml}{\"I}
438 \SGMLentity{ntilde}{\~n}
439 \SGMLentity{Ntilde}{\~N}
440 \SGMLentity{oacute}{\'o}
441 \SGMLentity{Oacute}{\'O}
442 \SGMLentity{ocirc}{\^o}
443 \SGMLentity{Ocirc}{\^O}
444 \SGMLentity{ograve}{\`o}
445 \SGMLentity{Ograve}{\`O}
446 \SGMLentity{oslash}{\oe}
447 \SGMLentity{Oslash}{\OE}
448 \SGMLentity{otilde}{\~o}
449 \SGMLentity{Otilde}{\~O}
450 \SGMLentity{ouml}{\"o}
451 \SGMLentity{Ouml}{\"O}
452 \SGMLentity{szlig}{\ss}
453 \SGMLentity{thorn}{\th}
454 \SGMLentity{THORN}{\TH}
455 \SGMLentity{uacute}{\'u}
456 \SGMLentity{Uacute}{\'U}
457 \SGMLentity{ucirc}{\^u}
458 \SGMLentity{Ucirc}{\^U}
459 \SGMLentity{ugrave}{\`u}
460 \SGMLentity{Ugrave}{\`U}
461 \SGMLentity{uuml}{\"u}
462 \SGMLentity{Uuml}{\"U}
463 \SGMLentity{yacute}{\'y}
464 \SGMLentity{Yacute}{\'Y}
465 \SGMLentity{yuml}{\"y}

7.4 Netscape Non-HTML tags

Netscape allows certain tags that do not correspond to HTML elements. These are Bad Thing. Originally the documentation of this package stated that such ‘extensions’ would not be supported, however as a request came from . . . . . .^{3} Who also supplied most of the code in this section, I have added some support which is enabled if the netscape option is used.

466 \ifx\HTML@not\@undefined\else
467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 %    Do something with bad reprehensible nonstandard tags
469 %    that have the annoying habit of turning up often in html files that
470 %    I want to print. [mjd,1996/03/20]

471 %

3Name withheld to protect the guilty

472 %    |\HTML@not| is defined above in the netscape option:
473 %     Naughty Nonstandard Extension Warning for things like
474 %    |<center>| and |<font>|. (I thought these were
475 %    Netscape-specific but the technical notes at Spyglass's web site
476 %    showed that I was wrong. [mjd,1996/03/20])
477 %    \begin{macrocode}
478 \SGMLdef<center>{\HTML@not{center}\begin{center}}
479 \SGMLdef</center>{\end{center}}
480 \SGMLdef<blink>{\SGMLgrabber{blink}\textbf}
481 \SGMLdef<font>{\HTML@not{font}\begingroup
482 \let\do\fontdo\the\toks@}
483 \SGMLdef</font>{\endgroup}

\fontdo must look at the first character of the ‘size, value to see if it is a relative size change (+ or -). Otherwise it is an absolute size change.

484 \def\fontdo#1#2{%
485 \def\@tempa{size}\def\@tempb{#1}%
486 \ifx\@tempa\@tempb
487  \font@switch#2\relax\@nil
488 \fi}

Let’s hack a nice little hook into \@setfontsize (tsk tsk). If we can set the current font size number there, it makes the rest of the job much easier.

489 \toks@\expandafter{\set@fontsize{#1}{#2}{#3}}
490 \edef\@tempa{%
491 \def\noexpand\set@fontsize##1##2##3{\the\toks@\noexpand\set@fontnum}}
492 \@tempa
493 %    Take |\f@size| which is a real number, convert it to an integer,
494 %    and normalize to the desired range.
495 \def\set@fontnum{\dimen@\f@size\p@
496 \dimen@\mul@ptsize\dimen@
497 \count@\dimen@ \divide\count@\p@
498 \advance\count@ -5\relax
499 \edef\@fontnum{\number\count@}}

Nice consistent naming conventions as always. multiplier if 11pt or 12pt documentclass option is used

500 \def\mul@ptsize{}%

5 = I think

501 \def\@fontnum{5}
    Initialize \mul@ptsize
502 \ifcase 0\@ptsize\relax
503 \global\let\mul@ptsize\@empty% case 0, ptsize = 10
504 \or\gdef\mul@ptsize{.9091}%    case 1, ptsize = 11
505 \else\gdef\mul@ptsize{.8333}%  case 2, ptsize = 12
506 \fi

\font@switch looks for + or - and selects a suitable fontsize command.

507 \def\font@switch#1#2\@nil{\count@\@fontnum\relax
508 \ifx +#1\advance\else\ifx -#1\advance\fi\fi
509 \count@#1#2\relax
510 \ifcase\count@ \tiny\or \tiny\or \scriptsize
511 \or\footnotesize \or\small \or\normalsize \or\large
512 \or\Large \or\LARGE \or\huge \else\Huge \fi}

513 \fi

7.5 The HTML3 DTD

\HTML@two@stop is \endinput (and so the package stops here) unless the HTML3 option is given.

514 \HTML@two@stop
515 \SGML@w{HTML3 support not finished yet}
516 \SGMLdef<math>{\SGMLgrabber{math}\domath}
517 \SGMLdef<sup>{^\bgroup\HTMLscriptmap}
518 \SGMLdef</sup>{\egroup}
519 \SGMLdef<sub>{_\bgroup\HTMLscriptmap}
520 \SGMLdef</sub>{\egroup}

GRUMBLE! GRUMBLE! GRUMBLE! Possibly the worst feature of TEX’s math markup is the nature of the infix operators for fractions and the like. And here it is faithfully (or actually not very faithfully) reconstructed here…

521 \SGMLdef<box>{\SGMLgrabber{box}\dobox}
522 \begingroup
523 \catcode`\<=\active
524 \catcode`\&=\active
525 \catcode`\_=\active
526 \catcode`\^=\active
527 \catcode`\"=\active

\domath Handle the MATH element. The body is pre-expanded one level to replace { } by BOX elements, and to replace any SGML entitity references by single TEX tokens so they can be recognised more easily. Then start math mode with \[ (which may have been redefined locally if the BOX attribute was used) set up the shorteref map.

528 \gdef\domath#1{%
529 {{\def&{\expandafter\expandafter\expandafter\noexpand\SGMLent@@}%
530 \let<\relax\let_\relax\let^\relax\let"\relax
531 \def\{{<box>}\def\}{</box>}%
532 \xdef\@gtempa{#1}}%
533 \let\do\mathdo
534 \let\doimplied\mathimplied
535 \the\toks@
536 \[%
537 \m@th\nulldelimiterspace\z@
538 \def^{<sup>}%
539 \def_{<sub>}%
540 \@gtempa\]}}

\HTMLscriptmap Set up the shortref map used in super and subscripts.

541 \gdef\HTMLscriptmap{%
542 \def^{</sup>}%
543 \def_{</sub>}}

\dobox Handle the BOX element. First deal with the attributes, then set up the shortref map. Then start looking for a LEFT tag.

544 \gdef\dobox#1{%
545 {\let\do\boxdo
546 \let\bigstrut\relax
547 \the\toks@
548 \def^{<sup>}%
549 \def_{<sub>}%
550 \lookleft@#1<left>\@nil}}

\lookleft@ See whether this BOX elemet contains a LEFT tag. Supply a ‘null delimiter’ if not one supplied.

551 \gdef\lookleft@#1<left>#2\@nil{%
552 \if$#2$%
553  {\left.\bgroup#1\mayberight}%
554 \else
555  \lookbox@#1<box>\@nil#2\@nil
556 \fi}

\lookbox@ Having found a LEFT tag, need to check it isn’t inside a nested BOX. The following code looks for an explicit <BOX> (which includes a { shortref as that will have been expanded by now, however it will fail if nested boxes have attributes, so it may need some further modifications later.

557 \gdef\lookbox@#1<box>#2\@nil#3<left>\@nil{%
558 \if$#2$%
559  {\maybeleft#1\@nil#3\mayberight}
560 \else
561  {#1 \boxtofront#2 <left> #3}%
562 \fi}

\boxtofront After all that messing around need to put the BOX tag back where we found it.

563 \gdef\boxtofront#1<box>{<box>#1}
564 \endgroup
\mathdo
565 \def\mathdo#1#2{%
566 \def\@tempa{class-chem}\def\@tempb{#1-#2}%
567 \ifx\@tempa\@tempb
568  \everymath{\fam\z@}\everydisplay{\fam\z@}%
569 \fi}
570 \def\mathimplied#1{%
571 \def\@tempa{box}\def\@tempb{#1}%
572 \ifx\@tempa\@tempb
573  \def\[{\center\setbox\z@\hbox\bgroup$\displaystyle}%
574  \def\]{$\egroup\fbox{\box\z@}\endcenter}%
575 \fi}
\boxdo
576 \def\boxdo#1#2{%
577 \def\@tempa{size}\def\@tempb{#1}%
578 \ifx\@tempa\@tempb
579  \def\@tempb{#2}
580  \def\@tempa{normal}\ifx\@tempa\@tempb\def\@tempc{1}\fi
581  \def\@tempa{medium}\ifx\@tempa\@tempb\def\@tempc{2}\fi

582  \def\@tempa{large}\ifx\@tempa\@tempb\def\@tempc{3}\fi
583  \def\@tempa{huge}\ifx\@tempa\@tempb\def\@tempc{4}\fi
584  \edef\bigstrut{\vrule\@height\@tempc\ht\strutbox\@width\z@}
585 \fi}
\SGML@left
586 \SGMLdef<left>{\left.\bgroup}
\mayberight
587 \def\mayberight{\egroup\bigstrut\right.}
\maybeleft
588 \def\maybeleft#1#2\@nil{%
589 \in@{#1}{()[]\SGML@E@rbrace\SGML@E@lbrace}%
590 \ifin@
591  \left#1\bgroup#2%
592 \else
593  \let\SGML@E@int\HTML@bigint
594  #1#2\left.\bgroup\let\SGML@E@int\int
595 \fi}
\righttest
596 \def\righttest#1{%
597 \in@{#1}{()[]\SGML@E@rbrace\SGML@E@lbrace}%
598 \ifin@
599  \right#1\let\mayberight\relax
600 \else
601  \right.\let\mayberight\relax\expandafter#1%
602 \fi}

7.6 ‘Big int’ processing

I am not sure that strtchy integral signs are good idea in general, and certainly they do not fit well with the Computer Modern style of sloping integral sign as opposed to the nore vertical style of, say, Lucida. However…

\HTML@int
603 \ifx\HTML@int\@undefined

\HTML@bigint Normally just use the standard \int.

604 \let\HTML@bigint\int
605 \else

With the bigint option The original \int (in a big font) together with any saved limits (in the normal font).

606 \def\HTML@int{\int^{\box\tw@}_{\box4}}
607 % \end{macro}
\HTML@bigint
608 \def\HTML@bigint#1\left.\bgroup{%
609 \def\@tempa{#1}%
610 \setbox\z@\hbox\bgroup
611  \aftergroup\HTMLafterbigint$\displaystyle\bgroup
612  \aftergroup$\aftergroup\egroup}

\HTMLafterbigint
613 \def\HTMLafterbigint{%
614 \dimen@.5\ht\z@
615 \advance\dimen@.5\dp\z@
616 {\SGMLdef<sup>{\setbox\tw@\hbox\bgroup\HTMLscriptmap$\scriptstyle}%
617  \SGMLdef<sub>{\setbox4\hbox\bgroup\HTMLscriptmap$\scriptstyle}%
618  \SGMLdef</sup>{$\egroup}%
619  \SGMLdef</sub>{$\egroup}%
620  \setbox\tw@\box\voidb@x
621  \setbox4\box\voidb@x
622  \@tempa
623  \ifdim\dimen@>\f@size\p@

At this point, could do \fontsize\dimen@\z@\selectfont but that would load all the math fonnts at a strange size, so instead just load the extension font, and then subvert NFSS to drop that into the math expression. The NFSS interface is still used so that A size substitution is done on the loading (otherwise every integral may use up a font.

624  \mathop{\hbox{\DeclareFixedFont\@tempa{OMX}{cmex}{m}{n}\dimen@
625  $\displaystyle\textfont\thr@@\@tempa\HTML@int$}}%
626  \else
627  \HTML@int
628  \fi
629  }\left.\box\z@}
630 \fi

See above grumble. The HTML3 DTD comments specifically refer to these as ‘L^{A}TEX commands’ but they are no such thing. They are in plain and survive into L^{A}TEX under protest! The AMS L^{A}TEX documentation contains a much longer diatribe against these infix commands, and they are disabled in the AMS L^{A}TEX styles.

631 \SGMLdef<over>{\over}
632 \SGMLdef<atop>{\atop}
633 \SGMLdef<choose>{\choose}
634 \SGMLdef<right>{\egroup\bigstrut\righttest}
635 \SGMLdef<above>{\SGMLgrabber{above}%
636  {\let\@tempc\overlineop
637  \let\do\abovedo
638  \the\toks@
639  \@tempc}}
640 \SGMLdef<below>{\SGMLgrabber{below}%
641  {\let\@tempc\underlineop
642  \let\do\abovedo
643  \the\toks@
644  \@tempc}}
645 \def\overlineop#1{\mathop{\overline{#1}}}
646 \def\underlineop#1{\mathop{\underline{#1}}}
647 \def\abovedo#1#2{%
648 \def\@tempa{sym}\def\@tempb{#1}%
649 \ifx\@tempa\@tempb\def\@tempc{\csname#2\endcsname}\fi}

650 \SGMLdef<vec>{\SGMLgrabber{vec}\vec}
651 \SGMLdef<bar>{\SGMLgrabber{bar}\bar}
652 \SGMLdef<dot>{\SGMLgrabber{dot}\dot}
653 \SGMLdef<ddot>{\SGMLgrabber{ddot}\ddot}
654 \SGMLdef<hat>{\SGMLgrabber{hat}\hat}
655 \SGMLdef<tilde>{\SGMLgrabber{tilde}\tilde}
656 \SGMLdef<t>{\SGMLgrabber{t}\mathrm}
657 \SGMLdef<bt>{\SGMLgrabber{bt}\mathbf}
658 \SGMLdef<text>{\SGMLgrabber{text}\textnormal}%%%%% not in the dtd????
659 \SGMLdef<root>{\rootfudge}
660 \def\rootfudge#1{%
661 \setbox\rootbox\hbox\bgroup$\m@th\scriptscriptstyle\bgroup#1}

I think the HTML3 DTD is wrong here^{4}, it allows the OF element to take content, which is at variance with the description in the text.

662 \SGMLdef<of>{\egroup$\egroup\SGMLgrabber{root}\offudge}
663 \SGMLdef</of>{}
664 \def\offudge#1{\mathpalette\r@@t{#1}}
665 \SGMLdef<sqrt>{\SGMLgrabber{sqrt}\sqrt}

Hate allocating registers, so this will probably go, but for now Give myself four (global) count registers to play with.

666 \newcount\HTMLrow
667 \newcount\HTMLcol
668 \newcount\HTMLrowspan
669 \newcount\HTMLcolspan

The HTML array element. Support for ALIGN, COLSPAN, ROWSPAN LA-BELS, LDELIM and RDELIM. However not all combinations of alignment and labels do ‘the right thing’.

Uses a TEX primitive \halign construction, rather than use the L^{A}TEXarray environment directly.

670 \SGMLdef<array>{{\ifnum`}=0\fi
671 \let\do\arraydo
672 \let\doimplied\arrayimplied
673 \let\HTMLal.%
674 \let\HTMLar.%
675 \global\HTMLrow\z@
676 \let\HTMLabox\vcenter
677 \the\toks@
678 \setbox\z@\vbox\bgroup\halign\bgroup
679  \strut\span\HTMLacolspec\cr\nocr}
\HTMLacolspec
680 \def\HTMLacolspec{##&&##}
\HTMLamakepream
681 \def\HTMLamakepream#1{%
682 \let\HTMLacolspec\@empty
683 \let\@sharp\relax
684 \lowercase{\@tfor\@tempc:=#1}\do{%

4Since confirmed by Dave Raggett, the HTML3 author

685  \if\@tempc l%
686  \edef\HTMLacolspec{\HTMLacolspec\@sharp\hfill&}%
687  \else
688  \if\@tempc c%
689  \edef\HTMLacolspec{\HTMLacolspec\hfill\@sharp\hfill&}%
690  \else
691  \if\@tempc r%
692  \edef\HTMLacolspec{\HTMLacolspec\hfill\@sharp&}%
693  \else
694  \if\@tempc +%
695  \edef\HTMLacolspec{\HTMLacolspec$+$}%
696  \else
697  \if\@tempc -%
698  \edef\HTMLacolspec{\HTMLacolspec$-$}%
699  \else
700  \if\@tempc =%
701  \edef\HTMLacolspec{\HTMLacolspec$=$}%
702  \fi
703  \fi
704  \fi
705  \fi
706  \fi
707  \fi}%
708 \def\@sharp{########}%
709 \edef\HTMLacolspec{\HTMLacolspec&\@sharp}}
710 \SGMLdef</array>{\HTMLendarray}
711 \let\HTMLcr\cr

\HTMLendarray Non LABELS ending

712 \def\HTMLendarray{%
713 \endi\crcr\egroup\egroup
714 \ifx\HTMLabox\vtop
715  \setbox\z@\vtop{\unvbox\z@}%
716 \else
717  \ifx\HTMLabox\vcenter
718  \dimen@\ht\z@
719  \advance\dimen@\dp\z@
720  \divide\dimen@\tw@
721  \advance\dimen@-\ht\z@
722  \setbox\z@\hbox{\raise\dimen@\box\z@}%
723  \fi
724 \fi
725 \dimen@=\ht\z@
726 \setbox\z@
727 \hbox{$\left\HTMLal\kern-1em\vcenter{\box\z@}\kern-1em\right\HTMLar$}%
728 \advance\dimen@-\ht\z@
729 \raise\dimen@\box\z@
730 \ifnum`{=0\fi}}
\HTMLendarraylabels LABELS ending
731 \def\HTMLendarraylabels{%
732 \endi\crcr\strut\cr\egroup\egroup
733 \setbox2=\vsplit\z@ to \baselineskip

734 \setbox\z@\vbox{\unvbox\z@\global\setbox\@ne\lastbox}%
735 \setbox4\hbox{\unhbox\@ne\unskip\global\setbox\@ne\lastbox}%
736 \vcenter{%
737 \box2
738 \hbox{$\kern\wd\@ne
739  \left\HTMLal\kern-\wd\@ne
740  \vcenter{\box\z@}%
741  \right\HTMLar$}}%
742 \ifnum`{=0\fi}}
743 \def\nocr{\relax\iffalse{\fi\let\HTMLcr\relax\iffalse}\fi}
744 \SGMLdef<row>{%
745 \endi\HTMLcr
746 \global\advance\HTMLrow\@ne
747 \global\HTMLcol\z@}
748 \SGMLdef</row>{}
749 \SGMLdef<item>{%
750 \let\do\itemdo
751 \gdef\@gtempa{\global\advance\HTMLcol\@ne}%
752 \gdef\@gtempb{}%
753 \gdef\@gtempc{}%
754 \global\HTMLcolspan\@ne
755 \the\toks@
756 \endi%
757 \@gtempc
758 \@gtempa

If an earlier row contained an entry spanning down to this point, need to jump across to the next column (and perhaps further).

759 \spanifneeded

\@gtempb is normally empty but will be defined if the item had an ALIGN attribute.

760 \@gtempb

First box each entry which allows measuring needed (but not yet done) for vertical spanning.

761 \setbox\z@\hbox\bgroup$%
762 \def\endi{\unskip$\egroup%
763  \quad\HTMLaleft\box\z@\HTMLaright\quad&}%
764 \ignorespaces}

\spanifneeded If the current row/column is in the list of spanned entries, jump to next column and look again.

765 \def\spanifneeded{%
766 \edef\@tempa{\noexpand\in@{,\the\HTMLrow/\the\HTMLcol,}{\spanitems}}%
767 \@tempa
768 \ifin@
769  \@firstofone{&}\global\advance\HTMLcol\@ne
770 \expandafter\spanifneeded
771 \fi}

As usual handle end tags that may be omitted by making them translate to empty.

772 \SGMLdef</item>{}

\HTMLaleft \HTMLaright Default stuff to put around the entries. Locally redefined by an ALIGN attribute.

773 \let\HTMLaleft\hfil
774 \let\HTMLaright\hfil

\endi Code to end an item. Extra indirection used to handle omitted tags.

775 \let\endi\relax

\arraydo Handle ARRAY attributes.

776 \def\arraydo#1#2{%
777 \def\@tempa{#1}\def\@tempb{#2}%
778 \def\@tempc{align}%
779 \ifx\@tempa\@tempc
780  \def\@tempc{top}%
781  \ifx\@tempb\@tempc
782  \let\HTMLabox\vtop
783  \else
784  \def\@tempc{bottom}%
785  \ifx\@tempb\@tempc
786  \let\HTMLabox\vbox
787  \fi
788  \fi
789 \else
790  \def\@tempc{ldelim}%
791  \ifx\@tempa\@tempc
792  \let\HTMLal\@tempb
793  \else
794  \def\@tempc{rdelim}%
795  \ifx\@tempa\@tempc
796  \let\HTMLar\@tempb
797  \else
798  \def\@tempc{labels}%
799  \ifx\@tempa\@tempc
800  \let\HTMLendarray\HTMLendarraylabels
801  \else
802  \def\@tempc{colspec}%
803  \ifx\@tempa\@tempc
804  \HTMLamakepream{#2}%
805  \fi
806  \fi
807  \fi
808  \fi
809 \fi}
\arrayimplied

\itemdo Handle ITEM attributes

810 \def\itemdo#1#2{%
811 \def\@tempa{#1}\def\@tempb{#2}%
812 \def\@tempc{colspan}%
813 \ifx\@tempa\@tempc
814  \global\HTMLcolspan#2\relax
815  \gdef\@gtempa{\@multispan#2\relax\global\advance\HTMLcol#2\relax}%
816 \else
817  \def\@tempc{align}%

818  \ifx\@tempa\@tempc
819  \def\@tempc{left}%
820  \ifx\@tempb\@tempc
821  \gdef\@gtempb{\let\HTMLaleft\relax}%
822  \else
823  \def\@tempc{right}%
824  \ifx\@tempb\@tempc
825  \gdef\@gtempb{\let\HTMLaright\relax}%
826  \fi
827  \fi
828  \else
829  \def\@tempc{rowspan}%
830  \ifx\@tempa\@tempc
831  \global\HTMLrowspan#2\relax
832  \gdef\@gtempc{%
833  \@tempcnta=\HTMLrow
834  \advance\@tempcnta\HTMLrowspan

Double loop adds all the entries below this a ROWSPAN entry to \spanitems list.

835  \loop
836  \@tempcntb=\HTMLcol
837  \advance\@tempcntb\HTMLcolspan
838  \advance\@tempcnta\m@ne
839  \ifnum\@tempcnta>\HTMLrow
840  {\loop
841  \xdef\spanitems{%
842  \spanitems\the\@tempcnta/\the\@tempcntb,}%
843  \advance\@tempcntb\m@ne
844  \ifnum\@tempcntb>\HTMLcol
845  \repeat}%
846  \repeat}%
847  \fi
848  \fi
849 \fi}

\spanitems Initial value for list of spanned entries.

850 \def\spanitems{,}
851 \SGMLentity{thinsp}{\,}
852 \SGMLentity{emsp}{\quad}

Far from final list of math symbol entity names…

853 \SGMLentity{alpha}{\alpha}
854 \SGMLentity{beta}{\beta}
855 \SGMLentity{gamma}{\gamma}
856 \SGMLentity{Gamma}{\Gamma}
857 \SGMLentity{int}{\int}
858 \SGMLentity{sum}{\sum}
859 \SGMLentity{lbrace}{\lbrace}
860 \SGMLentity{rbrace}{\rbrace}
861 \SGMLentity{times}{\times}
862 \SGMLentity{cup}{\cup}

863 \SGMLentity{cap}{\cap}
864 \SGMLentity{vee}{\vee}
865 \SGMLentity{wedge}{\wedge}
866 \SGMLentity{infty}{\infty}
867 \SGMLentity{oplus}{\oplus}
868 \SGMLentity{ominus}{\ominus}
869 \SGMLentity{otimes}{\otimes}
870 \SGMLentity{sin}{\sin}
871 \SGMLentity{cos}{\cos}
872 \SGMLentity{tan}{\tan}

8 HTML3 Tables

Not done yet, but here is a start…

Final version will probably need primitive \halign coding as for (but hopefully better than) array stuff above. Also will need to be lontable-like.

This is all very slapdash and temporary [mjd,1996/03/20]. Don’t expect goodlooking results, just results, occasionally.

873 \SGMLdef<table>{\begin{table}[htp]\begin{tabular}{cccccccccc}}
874 \SGMLdef</table>{\end{tabular}\end{table}}
875 \SGMLdef<tr>{\ifhmode\expandafter\\\fi\relax}
876 \SGMLdef</tr>{\\\relax}
877 \SGMLdef<td>{\ifvmode\else\expandafter\hiddenamp\fi}
878 \def\hiddenamp{&}

if <td> is present for each cell, then </td> doesn’t need to do anything

879 \SGMLdef</td>{}

Whoa, if I’m to define caption properly I’d have to look up how/where it’s used. Who, lazy old me?

880 \SGMLdef<caption>{\par \begingroup\bfseries}
881 \SGMLdef</caption>{\par\endgroup}

882 ⟨/package⟩