texlive[72815] Build/source/texk/web2c/hitexdir: [HiTeX] Adding the

commits+mruckert at tug.org commits+mruckert at tug.org
Mon Nov 11 14:34:38 CET 2024


Revision: 72815
          https://tug.org/svn/texlive?view=revision&revision=72815
Author:   mruckert
Date:     2024-11-11 14:34:37 +0100 (Mon, 11 Nov 2024)
Log Message:
-----------
[HiTeX] Adding the color extensions and moving to version 2.1

Modified Paths:
--------------
    trunk/Build/source/texk/web2c/hitexdir/ChangeLog
    trunk/Build/source/texk/web2c/hitexdir/doc/hiformat.hnt
    trunk/Build/source/texk/web2c/hitexdir/doc/hiformat.pdf
    trunk/Build/source/texk/web2c/hitexdir/doc/hintmac.tex
    trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.hnt
    trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.pdf
    trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.tex
    trunk/Build/source/texk/web2c/hitexdir/hiformat.w
    trunk/Build/source/texk/web2c/hitexdir/hilexer.c
    trunk/Build/source/texk/web2c/hitexdir/hiparser.c
    trunk/Build/source/texk/web2c/hitexdir/hiparser.h
    trunk/Build/source/texk/web2c/hitexdir/hitex.w

Modified: trunk/Build/source/texk/web2c/hitexdir/ChangeLog
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/ChangeLog	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/ChangeLog	2024-11-11 13:34:37 UTC (rev 72815)
@@ -1,3 +1,8 @@
+2024-11-11  Martin Ruckert <ruckert at cs.hm.edu>
+
+	* Adding the color extensions
+	* Moving to version 2.1 of hitex and the HINT file format
+	
 2024-03-10  Karl Berry  <karl at tug.org>
 
 	* TL'24 release.

Modified: trunk/Build/source/texk/web2c/hitexdir/doc/hiformat.hnt
===================================================================
(Binary files differ)

Modified: trunk/Build/source/texk/web2c/hitexdir/doc/hiformat.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/texk/web2c/hitexdir/doc/hintmac.tex
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/doc/hintmac.tex	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/doc/hintmac.tex	2024-11-11 13:34:37 UTC (rev 72815)
@@ -92,7 +92,7 @@
 \newif\ifpdf
 
 % HINT
-\ifx\HINTversion\undefined
+\expandafter\ifx\csname HINTversion\endcsname\relax
   \hintfalse
 \else 
   \hinttrue
@@ -99,7 +99,7 @@
 \fi
 
 % PDF
-\ifx\pdfliteral\undefined %  postscript und ps2pdf
+\expandafter\ifx\csname pdfliteral\endcsname\relax
   \pdffalse
 \else
   \pdftrue
@@ -106,7 +106,7 @@
 \fi
 
 % Book
-\ifx\book\undefined
+\expandafter\ifx\csname book\endcsname\relax
   \ifhint\bookfalse
   \else\ifpdf\bookfalse % This might change
   \else\bookfalse
@@ -785,7 +785,7 @@
 
 \def\tocsection#1#2#3{% depth sectionnumber sectiontitle
 \global\advance\toccount by 1%
-\newdest{SC.\the\toccount}%
+\newtopdest{SC.\the\toccount}%
 \ifhint
   \immediate\write\cont{\noexpand\ZZ {#1}{#2}{#3}% write to contents file
     {\noexpand\thepageno}{\the\toccount}}
@@ -1303,6 +1303,16 @@
   \HINTdest name {#1}%\message{Defining HINT label #1}%
 \fi\fi\fi}
 
+\def\newtopdest#1{% used to make a new destination
+%\message{New destination #1}%
+\ifbook
+\else\ifpdf
+  \pdfdest name {#1} fith%\message{Defining pdf label #1}%
+\else\ifhint
+  \HINTdest name {#1} top%\message{Defining HINT label #1 top}%
+\fi\fi\fi}
+
+
 \def\newlink#1#2{%
   \ifbook #2\else
   \ifpdf

Modified: trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.hnt
===================================================================
(Binary files differ)

Modified: trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.pdf
===================================================================
(Binary files differ)

Modified: trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.tex
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.tex	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/doc/hitexman.tex	2024-11-11 13:34:37 UTC (rev 72815)
@@ -28,6 +28,25 @@
 \input btxmac.tex
 \input hintmac.tex
 
+\hyphenation{HINT-ver-sion}
+\hyphenation{HINT-mi-nor-ver-sion}
+\hyphenation{HINT-image}
+\hyphenation{HINT-global-color}
+\hyphenation{HINT-color}
+\hyphenation{HINT-end-color}
+\hyphenation{HINT-start-link}
+\hyphenation{HINT-end-link}
+\hyphenation{HINT-global-link-color}
+\hyphenation{HINT-link-color}
+\hyphenation{HINT-dest}
+\hyphenation{HINT-out-line}
+\hyphenation{HINT-set-page}
+\hyphenation{HINT-stream}
+\hyphenation{HINT-set-stream}
+\hyphenation{HINT-before}
+\hyphenation{HINT-after}
+
+
 \makeindex
 \maketoc
 
@@ -96,8 +115,8 @@
 \medskip
 {\tt ruckert\:@cs.hm.edu}
 \medskip
-\def\lastrevision{Date: Mon Dec 4 15:00:09 2023}
-\lastrevision\par
+Last commit: Sat Sep 14 14:38:07 2024
+\par
 }
 \eject
 \endgroup
@@ -109,31 +128,35 @@
 
 \mainmatter
 
-\def\rs{\hskip 2pt plus 3pt minus 2pt\penalty0\relax}
+%\def\rs{\penalty100\hskip 2pt plus 3pt minus 2pt\penalty100\relax}
+%\def\rs{\kern 2pt}
 \def\rule#1:#2.{\par{\hangindent32pt\hangafter1\parindent0pt\rightskip 0pt plus 60pt#1{\bf:}\quad%
   \hskip 0pt plus 60pt\penalty-300\hskip 0pt plus -60pt#2{\bf.}\par}}
-\def\sym#1{\rs$<${\it #1\/}$>$\rs}
-\def\OR{\rs${}\vert{}$\rs}
-\def\opt#1{\rs$[{}$#1${}]$\rs}
+\def\prim#1.{\par{\hangindent32pt\hangafter1\parindent0pt\rightskip 0pt plus 60pt#1\par}}  
+\def\sym#1{$\left<\right.${\it #1\/}$\left.\right>$}
+\def\OR{${}\vert{}$}
+\def\opt#1{$\left[\right.$#1$\left.\right]$}
 \def\ctl#1{{\tt\BS #1}}
 
+
 \section{Introduction}
 When I started the \HINT\ project in 2017,
 I tried to keep the project as small as possible to increase the
 chances that I would be able to complete it. So one design decision
-was to keep things simple---or to quote Albert Einstein: ``Make things 
-as simple as possible, but not simpler''. The other imperative was:
+was to keep things simple---or to quote an aphorism attributed to
+Albert Einstein: ``Make things as simple as possible, but not simpler''.
+The other imperative was:
 keep things out of the viewer if possible because I do not know
 how much processing power or battery power is available.
 
 As a consequence, I focused on Donald Knuth' original \TeX,
-disregarding all later extensions like \eTeX\ or \LaTeX, and I
+disregarding all later developments like \eTeX\ or \LaTeX, and I
 decided that the \TeX\ interpreter would not need to run in the
 viewer.
 Of course \TeX's line breaking routine will run in the viewer
 and modifications of \TeX's page breaking routine. 
-But the decision to keep the TeX interpreter
-out of the HINT viewer implies that \HINT\ files do
+But the decision to keep the \TeX\ interpreter
+out of the \HINT\ viewer implies that \HINT\ files do
 not contain token lists and that there are
 neither output routines nor marks.
 To replace them, the \HINT\ file format includes
@@ -149,7 +172,7 @@
 
 The following sections will describe all the primitive control sequences
 that are special for Hi\TeX. I tried to be as close to similar primitives
-that have proven to be useful in other engines, notably pdftex, to make
+that have proven to be useful in other engines, notably pdf\TeX, to make
 it easy for package writers to support the Hi\TeX\ engine.
 
 While currently Hi\TeX\ is the only \TeX\ engine that supports output in the \HINT\ file
@@ -171,10 +194,10 @@
 file format will enjoy support in Hi\TeX\ by corresponding primitives.
 Everything that is not available through primitives in Hi\TeX\ should
 be considered ``internal'' and might change in the future.
-Second, Hi\TeX\ is not considered a replacement but 
+Second, Hi\TeX\ is not considered a replacement for but 
 a supplement to other engines. If your aim is the production of a printed
-book, your will probably target one of the engines that produce PDF output.
-But if, on occassion, you want to read what you wrote on a computer screen,
+book, your will target one of the engines that produce PDF output.
+But if, on occasion, you want to read what you wrote on a computer screen,
 you might just use Hi\TeX\ to process your source file. At this point you
 do not want to write \ctl{special} commands for the new target; you want
 Hi\TeX\ as a plug-in replacement for your main target engine, even if it
@@ -209,6 +232,8 @@
 \medskip
 \rule\sym{integer}: \index{integer+\sym{integer}}
   an integer as in  \ctl{penalty}\sym{integer}.
+\rule\sym{number}: \index{number+\sym{number}}
+  a general number as in  \ctl{kern}\sym{number}\.{pt}.
 \rule\sym{normal dimension}:\index{normal dimension+\sym{normal dimension}}
   a dimension as in \ctl{hrule} \.{width} \sym{normal dimension}.
 \rule\sym{dimension}:\index{dimension+\sym{dimension}}
@@ -217,13 +242,13 @@
   a name as in \ctl{input} \sym{name}.
 \rule\sym{vertical list}:\index{vertical list+\sym{vertical list}}
   a token list  with matching braces as in
-  \ctl{vbox}\.{\LB}\sym{vertical list}\.{\RB}.
+  \ctl{vbox}\.{\{}\sym{vertical list}\.{\}}.
 \rule\sym{horizontal list}:\index{horizontal list+\sym{horizontal list}}
   a token list  with matching braces as in
-  \ctl{hbox}\.{\LB}\sym{horizontal list}\.{\RB}.
+  \ctl{hbox}\.{\{}\sym{horizontal list}\.{\}}.
 \rule\sym{general text}:\index{general text+\sym{general text}}
   a token list with matching braces as in
-  \ctl{write}\.{\LB}\sym{general text}\.{\RB}.
+  \ctl{write}\.{\{}\sym{general text}\.{\}}.
 \medskip
 \enditemize
 
@@ -252,8 +277,8 @@
 The syntax is as follows:
 
 \medskip
-\ctl{HINTimage}  \opt{\.{=}} \sym{name}
-\opt{\sym{width}} \opt{\sym{height}} 
+\prim\ctl{HINTimage}  \opt{\.{=}} \sym{name}
+\opt{\sym{width}} \opt{\sym{height}}. 
 \medskip
 
 The optional equal sign can be added to make the code look nicer.
@@ -283,9 +308,299 @@
 It is considered an error if valid settings for the image's width and height
 can not be obtained.
 
+\subsection{Colors}
+Since Hi\TeX\ is designed to produce files for on-screen viewing,
+the only color model supported is the RGBA model, where a color is
+specified by four values: the red, the green, the blue, and the alpha
+value. The first three determine the light intensity of the red,
+green, and blue component of a pixel; the alpha value determines
+the relative share of a color when displaying
+one color on top of another color. 
 
+\subsubsection{Foreground Color}
+The most common color specification is the specification of a
+foreground color. (We will consider background colors below.)
+Because in practice most display devices use one byte for
+each of the four values that define a color,
+it is common to specify the four color
+components using integer values in the range 0 to 255.
+Using this representation, a foreground color can be specified using
+the following syntax:
 
-\subsection{Links, Labels, and Outlines}
+\medskip
+\rule\sym{foreground}\index{foreground+\sym{foreground}}:
+   \.{FG} \.{\{} \sym{integer} \sym{integer} \sym{integer} \opt{\sym{integer}} \.{\}}.
+\medskip
+
+Note that for convenience, the alpha value
+is optional; if no alpha value is given, the value 255 will be used
+and the color is completely opaque.
+
+Here are some examples:
+\.{FG\{255 0 0\}}, \.{FG\{255 0 0 255\}},
+both specify the same plain opaque red;
+\.{FG\{0 0 255\}} is plain blue;
+\.{FG\{255 255 0 127\}} is  a transparent yellow.
+Because each value fits in a single byte, the values are often given in
+hexadecimal notation. In \TeX, hexadecimal values are written with
+a \.{"}~prefix. The same colors as before are then written
+\.{FG\{"FF 0 0\}}, \.{FG\{"FF 0 0 "FF\}},
+\.{FG\{0 0 "FF\}} and \.{FG\{"FF "FF "7F\}}. 
+Values greater than 255 or less than 0 are not allowed.
+
+A common alternative to the color representation just described
+is the device independent notation where each
+value is a real number in the interval from 0 to 1.
+To keep both representations apart, the device independent
+representation (with the smaller numbers) uses the lowercase
+keyword \.{fg} instead of \.{FG}. Here is the syntax:
+
+\medskip
+\rule\sym{foreground}\index{foreground+\sym{foreground}}:
+\.{fg} \.{\{} \sym{number} \sym{number} \sym{number} \opt{\sym{number}} \.{\}}.
+\medskip
+
+Using the new syntax the colors above are written
+\.{fg\{1 0 0\}}, \.{fg\{1 0 0 1\}},
+\.{fg\{0 0 1\}} and \.{fg\{1 1 0 0.5\}}.
+Values greater than 1 and less than 0 are not allowed.
+Note that \.{fg\{1 1 1\}} is pure white while  \.{FG\{1 1 1\}} is
+the darkest possible gray, which on most devices is indistinguishable
+from pure black. 
+
+\subsubsection{Defining and Using Colors}
+As we will see, colors come in whole sets of colors.
+To define such a set of colors, Hi\TeX\ provides
+the primitive \ctl{HINTcolor}. It syntax is
+\medskip
+\prim\ctl{HINTcolor} \.{\{} \sym{color specification} \.{\}}.
+\medskip
+Before we give the complete definition of a  \sym{color specification},
+we start with some examples.
+In its simplest form this primitive just specifies a single color.
+For example \ctl{HINTcolor}\.{\{fg\{ 0 0 0\}\}} specifies
+the foreground color black which is then used for rules and glyphs.
+In addition to the foreground color, you can specify a background color.
+For example, black text on white background is specified by
+\ctl{HINTcolor}\.{\{fg\{0 0 0\}} \.{bg\{1 1 1\}\}} or
+\ctl{HINTcolor}\.{\{fg\{0 0 0\}} \.{BG\{"FF "FF "FF\}\}}.
+
+The viewer for \HINT\ files may provide a ``dark'' mode, and as a document
+author, you can specify the colors also for dark mode.
+If you like white letters on dark blue background you can write
+\ctl{HINTcolor}\.{\{fg\{0 0 0\}} \.{bg\{ 1 1 1\}}
+\.{dark} \.{fg\{1 1 1\}} \.{bg\{0 0 0.3\}\}}.
+
+There are two more colors that an author might care about: When searching
+for a text, all occurrences of the search phrase are highlighted by
+using a different color. And while the user iterates over the occurrences
+on the page, one occurrence has the ``focus'' and is rendered again in a
+different color. You can specify the highlight color right after
+the normal text color and the focus color right after the highlight color.
+The same can be done for the colors in ``dark'' mode.
+
+Here are the remaining rules that complete the \sym{color specification}:
+
+\medskip
+\rule\sym{color specification}\index{color specification+\sym{color specification}}: \sym{color set} \opt{\.{dark} \sym{color set}}.
+\rule\sym{color set}\index{color set+\sym{color set}}:
+    \sym{color} \opt{\sym{color} \opt{\sym{color}}}.
+\rule\sym{color}\index{color+\sym{color}}:
+    \sym{foreground} \opt{\sym{background}}.
+\rule\sym{background}:
+\.{BG} \.{\{} \sym{integer} \sym{integer} \sym{integer} \opt{\sym{integer}} \.{\}}.
+\rule\sym{background}:
+\.{bg} \.{\{} \sym{number} \sym{number} \sym{number} \opt{\sym{number}} \.{\}}.
+\medskip
+If some of the optional parts in the \sym{color specification} are missing,
+the corresponding colors from the set of default colors, as described below,
+are used.
+
+Note that the background colors for highlighted text and focus text
+can be given, but current viewers ignore these background specifications.
+Further note that the current specification of the \HINT\ file format
+limits the total number of different color specifications in a document to 255.
+
+
+The colors given in \ctl{HINTcolor} will have an immediate effect
+on all following rules and glyphs and the background in the enclosing box.
+The effect will persist until the next change of colors or until
+the end of the box---whatever occurs first.
+
+The line breaking algorithm of Hi\TeX\ 
+tracks changes in color within a paragraph and reinsert an appropriate
+color change at the start of every \ctl{hbox} that contains a new line.
+In this way local color changes inside a paragraph can span multiple lines
+but do not affect the inter line glue or material that is inserted with
+\ctl{vadjust}. Similarly, spliting off the initial part of a vertical
+box with \ctl{vsplit} will insert a color node in the remaining part
+if necessary to keep the color consistent accross the split.
+
+Special care is needed if background colors are used.
+Unless the background color is completely transparent
+with an alpha value equal to zero,
+the background color will fill a vertical box from left to right
+and a horizontal box from top to bottom. Since height, depth, and width of
+boxes often depend on the text that is inside, which in turn
+might depend on the outcome of line breaking, it is strongly recommended
+to use background colors with caution, and use \ctl{strut}s to enforce
+a fixed height and depth of horizontal boxes.
+
+
+\subsubsection{Default Colors}
+The \HINT\ file format specifies default values for all colors in a set.
+Hi\TeX\ provides the primitive \ctl{HINTdefaultcolor} to overwrite these
+default colors. This primitive must not be used after defining any custom
+colors using \ctl{HINTcolor}. Its syntax is
+\medskip
+\prim\ctl{HINTdefaultcolor} \.{\{} \sym{color specification} \.{\}}.
+\medskip
+The \HINT\ format specifies the following default colors:
+Normal text is black \.{FG\{0 0 0\}},
+highlight text is a slightly dark red  \.{FG\{"EE 0 0\}},
+and focus text is slighty dark green \.{FG\{0 "EE 0\}}.
+The background is transparent white \.{BG\{"FF "FF "FF 0\}}.
+In dark mode the background is transparent black \.{BG\{0 0 0 0\}},
+normal text is white \.{FG\{"FF "FF "FF\}},
+and a slightly lighter red \.{FG\{"FF "11 "11\}},
+and green \.{FG\{"11 "FF "11\}}, are used for highlighted and focus text.
+
+\subsubsection{Nesting Colors}
+A color change is limited to the enclosing box. Hence the
+nesting of boxes leads to a nesting of color definitions.
+So for example a transparent background color in the inner box
+will not completely replace the background color of the enclosing
+box but will only modify this color like seeing it through colored glas.
+
+A color change ends not only at the end of the enclosing box,
+it will also end at the next use of the \ctl{HINTcolor}
+or \ctl{HINTendcolor} primitive:
+The \ctl{HINTcolor} primitive will replace the current colors by
+a new set of colors; the \ctl{HINTendcolor} primitive will resume
+the color specification that was valid just before the matching use
+of \ctl{HINTcolor}. Hi\TeX\ maintains a color stack tracking
+local color changes within a box or paragraph, and uses it to
+insert appropriate color changes so that the \ctl{HINTendcolor} primitive
+will simply cancel the color change by the matching \ctl{HINTcolor} primitive.
+If there is no matching \ctl{HINTcolor} primitive,
+the \ctl{HINTendcolor} primitive is silently ignored.
+Note that within a single box, there is at any point only a single
+background color: The color stack will switch from one background
+color to an other background color but will not overlay an ``inner''
+background color over an ``outer'' background color.
+This is only the case when multiple boxes are nested as described above.
+
+Here is an example:
+Suppose we want the \TeX\ logo to be rendered in light red,
+and notes in dark green. You can write
+\medskip
+\verbatim/\def\redTeX{\HINTcolor{fg{1 0.3 0.3}}\TeX\HINTendcolor}
+\def\beginnote{\HINTcolor{fg{0 0.5 0}}}
+\def\endnote{\HINTendcolor}/
+\medskip
+{\tt\parindent 0pt\rightskip=0pt plus 160pt
+This is an example showing the \ctl{redTeX}\BS\ logo in red color.
+\ctl{beginnote}\ Note how the \ctl{redTeX}\BS\ logo is still red inside
+this note.\ctl{endnote}\par}
+\medskip
+
+After the first occurrence of the red \TeX\ logo, the color will be switched
+back to normal black, while after the second occurrence the color will
+be switched back to dark green. The color switching will work as intended
+even if the paragraph is spread over several lines by the line breaking routine.
+
+
+\subsubsection{Colors for Pages}
+When a page get rendered in the \HINT\ file viewer,
+the renderer starts with the default colors and the page is initially
+cleared using the default background color. If a different page
+color is desired, color changes can be added to the page templates.
+
+In a vertical box, the color stack of Hi\TeX\ has a similar effect as in
+a horizontal box. Similar to the precautions in the line breaking routine,
+Hi\TeX\ will insert color changes when splitting a vertical box with \ctl{vsplit}.
+Complications arise from color changes in the top level vertical list
+which is split into pages in the \HINT\ file viewer at runtime.
+Because the page builder in the viewer has no global information and
+should not need global information, Hi\TeX\ will insert copies of the
+local color information after every possible breakpoint in the top
+level vertical list. This will ensure that page breaks will not
+affect the colors of the displayed material.
+Note, however, that \TeX\ considers glue (and kerns) as discardable
+and will remove these items from the top of a new page. Because glues and kerns
+are colored using the current background color, these items might be visible
+on a page but disappear when they follow immediately after a page break.
+So if you want the effect of a colored glue or kern that is not affected by
+a page break, you should include it inside a box or use a colored rule instead.
+
+\subsubsection{Colors for Links}
+The most common change in color is caused by the use of links.
+To support this changing of colors, the primitives
+\ctl{HINTstartlink}\index{HINTstartlink+\ctl{HINTstartlink}}
+and \ctl{HINTendlink}\index{HINTendlink+\ctl{HINTendlink}}
+(see section~\secref{llo})
+cause an automatic change of the color specification.
+A document author can set the default colors used for links
+with the  primitive \ctl{HINTdefaultlinkcolor} and change
+the current link color with the primitive \ctl{HINTlinkcolor}.
+The syntax is:
+\medskip
+\prim\ctl{HINTdefaultlinkcolor} \.{\{} \sym{color specification} \.{\}}.
+\prim\ctl{HINTlinkcolor} \.{\{} \sym{color specification} \.{\}}.
+\medskip
+
+For convenience, the \HINT\ file format specifies default colors
+for links as well: for normal text instead of black links use
+dark blue \.{FG\{0 0 "EE\}};  in dark mode instead of white
+links use light blue \.{FG\{"11 "11 "FF\}}.
+The primitive \ctl{HINTdefaultlinkcolor} is used
+to partly or completely redefine these defaults.
+
+Later uses of \ctl{HINTlinkcolor} will set new current link colors.
+Colors that are missing in the new link color specification are taken
+from the corresponding default colors for links.
+
+Whenever the \ctl{HINTstartlink} primitive is used, its effect on the
+colors is equivalent to the \ctl{HINTcolor} primitive using the current
+link color. This implies that the color change caused by \ctl{HINTstartlink}
+is local to the enclosing box.
+
+Whenever the \ctl{HINTendlink} primitive is used, it will restore
+the color stack of Hi\TeX\ to its state before the matching \ctl{HINTstartlink}.
+It is the responsibility of the \TeX\ source code (or package) to keep the
+sequence of  \ctl{HINTstartlink}, \ctl{HINTendlink},
+\ctl{HINTcolor}, and \ctl{HINTendcolor} properly nested.
+A sequence like  ``\ctl{HINTstartlink} \dots\ \ctl{HINTcolor}
+ \dots\ \ctl{HINTendlink} \dots\ \ctl{HINTendcolor}'' is possible,
+but it will cause \ctl{HINTendlink} to restore the colors to those
+in effect before the \ctl{HINTstartlink}.
+The following \ctl{HINTendcolor} will then either restore
+a color of a matching \ctl{HINTcolor} preceeding
+the link in the same box or it will restore the
+color in the outer box, or it will be ignored.
+In effect, the color changes inside a link stay local to the link.
+
+\subsubsection{Color Numbers}
+The \HINT\ file format references a color set by a number in the range
+0 to 254.
+So Hi\TeX\ assigns each color specification a number, using the same
+number for two identical color specifications.
+One extension to the above specification of Hi\TeX's color primitives
+could be to make these numbers accessible to document authors or
+package programmers. For example \ctl{the}\ctl{HINTcolor} could
+expand to the number $n$ of the current color set and
+\ctl{HINTcolor}$n$ would be equivalent to a use of \ctl{HINTcolor}
+with a full color specification that is equivalent to the color specification
+belonging to $n$.
+This would be much more efficient, because it would not be necessary
+to scan the color specification and search the existing color specifications
+for the matching specification with number $n$.
+But because for \TeX\ storing the number or storing the color specification
+as a macro does not make much of a difference, this extension is just
+a matter of efficiency. So currently, there are no plans to implement
+this extension.
+
+\subsection{Links, Labels, and Outlines}\label{llo}
 A link\index{link} in a \HINT\ document refers to another location in the same document.
 It can be used to navigate to that location.
 A link is defined using the primitives 
@@ -297,8 +612,9 @@
 or tapping or otherwise activating the link (e.g. pronouncing)
 will navigate to the destination of the link.
 The user interface might provide a visual clue to make the user aware of the
-available links but it also may choose to leave the visual clues to the author
-of the document (e.g. using a special image or a special font).
+available links for example using a special cursor when hovering over a link.
+But it also may choose to leave the visual clues completely to the author
+of the document (e.g. using a special colors, images, or fonts).
 
 The syntax is 
 \ctl{HINTstartlink}  \sym{destination}
@@ -309,7 +625,7 @@
 \medskip
 \rule \sym{destination}\index{destination+\sym{destination}}:\.{goto} \sym{label}.
 \rule \sym{label}\index{label+\sym{label}}:
-  \.{name} \.{\LB}\sym{general text}\.{\RB} \OR\ \.{num} \sym{integer}.
+  \.{name} \.{\{}\sym{general text}\.{\}} \OR\ \.{num} \sym{integer}.
 \medskip
 
 As you can see, the link refers to its destination using a label
@@ -322,9 +638,10 @@
 document.
 
 The syntax is
-\ctl{HINTdest} \sym{label} \opt{\sym{placement}}
+\medskip
+\prim\ctl{HINTdest} \sym{label} \opt{\sym{placement}}.
+\medskip
 with
-
 \medskip
 \rule\sym{placement}\index{placement+\sym{placement}}:
 \.{top}\index{top+{\tt top}} \OR\ \.{bot}\index{bot+{\tt bot}}.
@@ -345,7 +662,7 @@
 persuade the page builder to start with the chapter heading instead.
 
 There is a special label that has the form
-\.{name} \.{\LB}\.{HINT.home}\.{\RB}\index{HINT.home+{\tt HINT.home}}.
+\.{name} \.{\{}\.{HINT.home}\.{\}}\index{HINT.home+{\tt HINT.home}}.
 It is used to mark the ``home page''\index{home page} of the document. User interfaces
 are encouraged to offer a button or keyboard shortcut to navigate to the
 document location labeled this way. The page should be a convenient
@@ -358,15 +675,15 @@
 refers to a specific location in the document.
 
 The syntax is
-\ctl{HINToutline}\index{HINToutline+\ctl{HINToutline}}
-\sym{destination} \opt{\sym{depth}} \.{\LB}\sym{horizontal list}\.{\RB}.
-
 \medskip
+\prim\ctl{HINToutline}\index{HINToutline+\ctl{HINToutline}}
+\sym{destination} \opt{\sym{depth}} \.{\{}\sym{horizontal list}\.{\}}.
+\medskip
 \rule \sym{depth}\index{depth+\sym{depth}}: \.{depth} \sym{integer}.
 \medskip
 
 The user interface can format the \sym{horizontal list} much like 
-a \ctl{hbox} would do and displays it to the user. When the user selects
+a \ctl{hbox} would do and display it to the user. When the user selects
 this text, the document will be repositioned to show the destination location
 in the same way as with a link. In order to support also simpler
 user interfaces, the current \HINT\ backend also extracts the characters
@@ -396,12 +713,13 @@
 separate section follows at the end.
 
 The syntax of a page template specification is:
-\ctl{HINTsetpage}\index{HINTsetpage+\ctl{HINTsetpage}}
+\medskip
+\prim\ctl{HINTsetpage}\index{HINTsetpage+\ctl{HINTsetpage}}
 \sym{integer} \opt{\.{=}} \sym{name} 
 \opt{\sym{priority}} \opt{\sym{width}} \opt{\sym{height}}
-\.{\LB}\sym{vertical list} \sym{stream definition list}\.{\RB}
+\.{\{}\sym{vertical list} \sym{stream definition list}\.{\}}.
+\medskip
 
-
 The \sym{integer} specifies the page templates number in the range 1
 to 255.  The number 0 is reserved for the build in page template of
 the \HINT\ file format, which is used if no other page template has
@@ -435,7 +753,8 @@
 The following \sym{vertical list} defines the page itself. It should assign suitable values
 to \ctl{topskip} and \ctl{maxdepth} because the values valid at the end of the vertical list
 are stored in the page template and are used in the page building process. 
-The vertical list usually also specifies the insertion of content streams using a \sym{stream insert point}.
+The vertical list usually also specifies the insertion of content streams
+using a \sym{stream insert point}.
 
 \medskip
 \rule\sym{stream insert point}\index{stream insert point+\sym{stream insert point}}:
@@ -445,7 +764,7 @@
 Here  the \sym{integer} must be in the range 0 to 254. The value 255 is invalid;
 the value 0 indicates the main body of text (what \TeX's page builder would normally put into
 box 255 before calling the output routine).
-Otherwise, the \sym{integer} is TeX's insertion number, that is the number of \TeX's box 
+Otherwise, the \sym{integer} is \TeX's insertion number, that is the number of \TeX's box 
 containing the insertions. As usual, this box is filled using \TeX's \ctl{insert} primitive. 
 So after plain \TeX\ has defined \ctl{footins},
 the footnotes for the current page can be inserted after the main body of text in the \sym{vertical list}
@@ -461,7 +780,7 @@
   \ctl{HINTsetstream} \sym{integer}  \opt{\.{=}}
 \opt{{\tt preferred} \sym{integer}}
 \opt{\.{next} \sym{integer}}
-\opt{\.{ratio} \sym{integer}} \.{\LB}\sym{vertical list}\.{\RB}.
+\opt{\.{ratio} \sym{integer}} \.{\{}\sym{vertical list}\.{\}}.
 \medskip
 
 
@@ -488,9 +807,9 @@
 
 \medskip\index{HINTbefore+\ctl{HINTbefore}}\index{HINTafter+\ctl{HINTafter}}
 \rule \sym{before list}\index{before list+\sym{before list}}:
-  \ctl{HINTbefore} \opt{\.{=}} \.{\LB}\sym{vertical list}\.{\RB}.
+  \ctl{HINTbefore} \opt{\.{=}} \.{\{}\sym{vertical list}\.{\}}.
 \rule \sym{after list}\index{after list+\sym{after list}}:
-  \ctl{HINTafter} \opt{\.{=}} \.{\LB}\sym{vertical list}\.{\RB}.
+  \ctl{HINTafter} \opt{\.{=}} \.{\{}\sym{vertical list}\.{\}}.
 \medskip
 
 If you are interested in the design decision that motivate the definitions that have
@@ -542,15 +861,15 @@
 
 
 \subsection{{\tt kpathsearch} and \ctl{input}}
-In Don Knuths implementation of \TeX, the \ctl{input} primitive
+In Don Knuth's implementation of \TeX, the \ctl{input} primitive
 will add the extension {\tt .tex} to any filename that does not have an
-extension. This implies that a file without extension can not be opened
+extension. This implies that a file without extension cannot be opened
 as an input file. The usual engines do not add such an extension but
 pass the filename as given to \verbatim/kpse_find_file/ function. 
 Hi\TeX\ does the same. The {\tt kpathsearch} library will find files
 in a variety of directories and yes, it will also find files without
-extension. Using this library is just mandatory for any engine that
-wants to process \LaTeX\ input.
+extension. Using this library, or equivalent functionality, is just about
+mandatory for any engine that wants to process \LaTeX\ input.
 
 
 \section{Replacing \TeX's Page Builder}\label{build}

Modified: trunk/Build/source/texk/web2c/hitexdir/hiformat.w
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/hiformat.w	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/hiformat.w	2024-11-11 13:34:37 UTC (rev 72815)
@@ -156,7 +156,7 @@
 First printing: August 2019\par
 Second edition: August 2021\par
 \medskip
-Last commit: Mon Dec 4 15:00:09 2023
+Last commit: Wed Oct 30 14:00:17 2024
 \par
 }
 }
@@ -190,7 +190,7 @@
 button because it did not support reading the page content
 ``backwards''. As a consequence, I developed a compact binary file
 format that could be parsed easily in both directions. The \HINT\ 
-short file format war born. I stopped an initial attempt at
+short file format was born. I stopped an initial attempt at
 eliminating the old textual format because it was so much nicer when
 debugging. Instead, I converted the long textual format into the short
 binary format as a preliminary step in the viewer. This was not a long
@@ -587,9 +587,9 @@
 DEF_KIND(s@&tream,s@&tream,25),@/
 DEF_KIND(p@&age,p@&age,26),@/
 DEF_KIND(l@&ink,l@&abel,27),@/
-DEF_KIND(u@&ndefined1,u@&ndefined1,28),@/
-DEF_KIND(u@&ndefined2,u@&ndefined2,29),@/
-DEF_KIND(u@&ndefined3,u@&ndefined3,30),@/
+DEF_KIND(c@&olor,c@&olor,28),@/
+DEF_KIND(u@&ndefined1,u@&ndefined1,29),@/
+DEF_KIND(u@&ndefined2,u@&ndefined2,30),@/
 DEF_KIND(p@&enalty, i@&nt,31)
 @t@>
 @
@@ -598,10 +598,12 @@
 alternative names; we will use them
 to express different intentions when using them.
 @<alternative kind names@>=
-font_kind=glyph_kind,int_kind=penalty_kind, unknown_kind=penalty_kind, dimen_kind=kern_kind, label_kind=link_kind, outline_kind=link_kind@/@t{}@>
+font_kind=glyph_kind,int_kind=penalty_kind, unknown_kind=penalty_kind,
+dimen_kind=kern_kind, label_kind=link_kind, outline_kind=link_kind@/@t{}@>
 @
 
-The info\index{info value} values can be used to represent numbers in the range 0 to 7; for an example
+The info\index{info value} values can be used to represent numbers
+in the range 0 to 7; for an example
 see the |hput_glyph| function later in this section.
 Mostly, however, the individual bits are used as flags indicating the presence
 or absence of immediate parameter values. If the info bit is set, it
@@ -4643,9 +4645,9 @@
 the surrounding glue to fill a horizontal or vertical box.  While I
 thought this would be in line with \TeX's concepts, it proved to be a
 bad decission because images, as opposed to glue, would stretch or
-shrink horizontaly {\it and} vertically at the same time.
+shrink horizontally {\it and} vertically at the same time.
 This would require a two pass algorithm to pack boxes: first to
-determine the glue setting and a secondf pass to determine the proper
+determine the glue setting and a second pass to determine the proper
 image dimensions. Otherwise incorrect width or height values would
 propagate all the way through a sequence of nested boxes. Even worse
 so, this two pass algorithm would be needed in the viewer if images
@@ -4757,7 +4759,7 @@
 eliminate information about the image size when writing the long format
 if that information can be derived from the image file. The latter
 solution might have the disadvantage, that infomation about a
-desired image size might get lost when editing a image file.
+desired image size might get lost when editing an image file.
 
 \writecode
 @<write functions@>=
@@ -4874,18 +4876,22 @@
 static Info hput_image_dimens(int n,float32_t a, Dimen w, Dimen h)
 { Dimen iw,ih;
   double ia;
+  if (w>0 && h>0)
+  {  HPUT32(w); HPUT32(h); return b011; }
+  else if (a>0 && w>0)
+  { hput_float32((float32_t)a); HPUT32(w); return b010; }
+  else if (a>0 && h>0)
+  { hput_float32((float32_t)a); HPUT32(h); return b001; }
   hextract_image_dimens(n,&ia,&iw,&ih);
   @<merge stored image dimensions with dimensions given@>@;
-  if (w!=0 && h!=0)
-  { HPUT32(iw); HPUT32(ih); return b011; }
-  else if (a!=0.0)
-  { if (h!=0)
-    { hput_float32((float32_t)ia); HPUT32(ih); return b001; }
-    else
-    { hput_float32((float32_t)ia); HPUT32(iw); return b010; }
+  if (iw>0)
+  { hput_float32((float32_t)ia); HPUT32(iw); return b010; }
+  else if (ih>0)
+  { hput_float32((float32_t)ia); HPUT32(ih); return b001; }
+  else 
+  { iw=-iw; ih=-h; /*we accept the default resolution*/
+    HPUT32(iw); HPUT32(ih); return b011;
   }
-  else 
-  { HPUT32(iw); HPUT32(ih); return b011; }
 }
 @
 
@@ -4896,26 +4902,29 @@
 It is considered an error, if the function |hextract_image_dimens|
 can not extract the aspect ratio. Absolute width and height values,
 however, might be missing. If the aspect ratio is computed from the
-number of horizontal and vertical pixels, these values are negated and
-returned instead of absolute width and height values.
-Hi\TeX\ for example, will use these values to guess the image size
-assuming square pixels and a fixed resolution of 72.27 dpi.
+number of horizontal and vertical pixels, |hextract_image_dimens|
+makes the reasonable assumption that the intended resolution
+is 72dpi and converts the image dimensions to scaled points.
+It negates these values to indicate
+that the resolution is just a guess. This allows other programs
+to used different default resolutions if desired.
 
 @<merge stored image dimensions with dimensions given@>=
 { if (ia==0.0)
   { if (a!=0.0) ia=a;
     else if(w!=0 && h!=0) ia=(double)w/(double)h;
-    else QUIT("Unable to determine dimensions of image %s",dir[n].file_name);
+    else QUIT("Unable to determine aspect ratio of image %s",dir[n].file_name);
   }
-  if (w==0 && h==0)
+  /* here the aspect ratio |ia| is known */ 
+  if (w==0 && h==0) /*neither width nor height specified*/
   { if (ih>0) iw=round(ih * ia);
     else if (iw>0) ih=round(iw/ia);
   }
-  else if (h==0) 
+  else if (h==0) /*width specified*/
   { iw=w;@+ ih=round(w/ia);@+ }
-  else if (w==0) 
+  else if (w==0) /*height specified*/
   { ih=h;@+ iw=round(h*ia);@+}
-  else 
+  else /* both specified */
   { ih = h;@+
     iw = w;@+
   }
@@ -5033,7 +5042,7 @@
     img_buf_size=0;
     GET_IMG_BUF(17);
     size=BigEndian32(0);
-    if (Match4(4,'p', 'H', 'Y', 's'))
+    if (Match4(4,'p', 'H', 'Y', 's')) /*must occur before IDAT chunk*/
     { xppu =(double)BigEndian32(8);  
       yppu =(double)BigEndian32(12);
       unit=img_buf[16];
@@ -5058,8 +5067,9 @@
     else
       pos=pos+12+size;
   }
-  *w=-wpx;
-  *h=-hpx;
+  /*we assume 72dpi and negate the results*/
+  *w=-floor(0.5+ONE*72.27*wpx/72.0);
+  *h=-floor(0.5+ONE*72.27*hpx/72.0);
   *a =wpx/hpx;
   return true;
 }
@@ -5110,8 +5120,8 @@
       wpx =(double)BigEndian16(7);
       if (unit==0)
       { *a = (wpx/xppu)/(hpx/yppu);
-        *w=-wpx;
-	*h=-hpx;
+        *w=-floor(0.5+ONE*72.27*wpx/xppu);
+	*h=-floor(0.5+ONE*72.27*hpx/yppu);
         return true;
       }
       else if (unit==1)
@@ -5294,8 +5304,8 @@
 
 We call content nodes that reference some position inside the content section 
 ``link'' nodes. The position that is referenced is called the destination of the link.
-Link nodes occur always in pairs of an ``on'' link 
-followed by a corresponding ``off'' link that both reference the same position
+Link nodes occur always in pairs of an ``start'' link 
+followed by a corresponding ``end'' link that both reference the same position
 %, the same nesting level, % not sure!
 and no other link nodes between them. 
 The content between the two will constitute the visible part of the link.
@@ -5386,10 +5396,11 @@
 @<hint basic types@>=
 typedef struct 
 {@+ uint32_t pos; /* position */
+    uint32_t pos0; /* secondary position */
     uint8_t where; /* where on the rendered page */
     bool used; /* label used in a link or an outline */
     int next; /* reference in a linked list */
-    uint32_t pos0;@+ uint8_t f; /* secondary position */
+    uint8_t f; /* font, currently not used */
 } Label;
 @
 
@@ -5464,7 +5475,7 @@
 @<parsing rules@>=
 placement: TOP {$$=LABEL_TOP;} |  BOT {$$=LABEL_BOT;} |  MID {$$=LABEL_MID;} | {$$=LABEL_MID;};
 content_node: START LABEL REFERENCE placement END @|
-              {  hset_label($3,$4); @+}
+              {  hset_label($3,$4); @+};
 @
 
 
@@ -5485,8 +5496,7 @@
 @
 
 
-All that can be done by the above function
-is storing the data obtained in the |labels| array.
+The above function will simply store the data obtained in the |labels| array.
 The generation of the short format output is
 postponed until the entire content section has been parsed and
 the positions of all labels are known.
@@ -5606,7 +5616,7 @@
   if (i&b010) /* secondary position */
   { HGET32(t->pos0); t->f=HGET8;@+}
   else t->pos0=t->pos;
-  DBG(DBGLABEL,"Defining label %d at 0x%x\n",n,t->pos);
+  DBG(DBGLABEL,"Defining label %d at 0x%x/0x%x\n",n,t->pos0,t->pos);
 }
 @
 
@@ -5623,6 +5633,7 @@
   HPUT8(l->where);
   if (l->pos!=l->pos0)
   { i|=b010; HPUT32(l->pos0); HPUT8(l->f); @+} 
+  DBG(DBGLABEL,"Defining label %d at 0x%x/0x%x\n",n,l->pos0,l->pos);
   return TAG(label_kind,i);
 }
 @
@@ -5680,12 +5691,38 @@
 content nodes. Let's look at them next.
 When reading a short format link node,
 we use again the |b001| info bit to indicate a 16 bit reference
-number to a label. The |b010| info bit indicates an ``on'' link.
+number to a label.
+
+To help a reader tell a link from ordinary text, links should be
+visualy different. This is supported in the \HINT\ file format
+by associating  a different color scheme to a link.
+In the short format, the |b100| bit indicates that a color set reference
+(see section~\secref{colors}) follows after the label reference.
+A color reference to 1 in the start node and to |0xFF| in the end node
+is the default and is omitted.
+
+Because color changes are local to the enclosing box or paragraph,
+a link is local as well. Without further mentioning, here and
+in the following, when we say ``box'' it also mean ``paragraph''. 
+A link starts with a ``start'' link and ends with either an ``end''
+link or the end of the enclosing box. Links must not be nested.
+It is an error to have two start links in the same box without
+an end link between them.
+An application can choose to continue a link in the next box
+by inserting a copy of the start link node at the begining of
+the new box.
+In short: ``end'' links are mandatory when separating two links
+but optional if they just preceede the end of the box.
+The |b010| info bit indicates a ``start'' link;
+otherwise it is an ``end'' link. 
+
 \gdef\subcodetitle{Links}
 \getcode
 @<get macros@>=
 #define @[HGET_LINK(I)@] @/\
-{ int n; if (I&b001) HGET16(n);@+ else n=HGET8; @+ hwrite_link(n,I&b010); @+}
+{ int n,c; if (I&b001) HGET16(n);@+ else n=HGET8;\
+  if (I&b100) c=HGET8; else c=(I&b010)?1:0xFF;\
+  hwrite_link(n,c,I&b010); @+}
 @
 
 @<cases to get content@>=
@@ -5694,6 +5731,10 @@
 case TAG(link_kind,b001): @+ HGET_LINK(b001);@+ break;
 case TAG(link_kind,b010): @+ HGET_LINK(b010);@+ break;
 case TAG(link_kind,b011): @+ HGET_LINK(b011);@+ break;
+case TAG(link_kind,b100): @+ HGET_LINK(b100);@+ break;
+case TAG(link_kind,b101): @+ HGET_LINK(b101);@+ break;
+case TAG(link_kind,b110): @+ HGET_LINK(b110);@+ break;
+case TAG(link_kind,b111): @+ HGET_LINK(b111);@+ break;
 @
 
 The function |hput_link| will insert the link in the output stream and return
@@ -5701,12 +5742,13 @@
 
 \putcode
 @<put functions@>=
-Tag hput_link(int n, int on)
+Tag hput_link(int n, int c, int on)
 { Info i;
   REF_RNG(label_kind,n);
   labels[n].used=true;
   if (on) i=b010;@+ else i=b000;
   if (n>0xFF) { i|=b001; HPUT16(n);@+} @+else HPUT8(n);
+  if ((on && c!=1) ||(!on && c!=0xFF)) { i|=b100; HPUT8(c); }
   return TAG(link_kind,i);
 }
 @
@@ -5722,12 +5764,14 @@
 
 @<parsing rules@>=
 content_node:start LINK REFERENCE on_off END
-    {@+ hput_tags($1,hput_link($3,$4));@+ };
+    {@+ hput_tags($1,hput_link($3,$4?1:0xFF,$4));@+ };
+content_node:start LINK REFERENCE on_off REFERENCE END
+    {@+ hput_tags($1,hput_link($3,$5,$4));@+ };
 @
 
 \writecode
 @<write functions@>=
-void hwrite_link(int n, uint8_t on)
+void hwrite_link(int n, int c, uint8_t on)
 { REF_RNG(label_kind,n);
   if (labels[n].where==LABEL_UNDEF)
     MESSAGE("WARNING: Link to an undefined label %d\n",n);
@@ -5734,6 +5778,8 @@
   hwrite_ref(n);
   if (on) hwritef(" on");
   else hwritef(" off");
+  if ((on && c!=1)||(!on && c!=0xFF))
+  { REF_RNG(color_kind,c);  hwrite_ref(c); }
 }
 @
 
@@ -5918,42 +5964,409 @@
 }
 @
 
-\subsection{Colors}
-Colors\index{color} are certainly one of the features you will find in the final \HINT\ file format.
-Here some remarks must suffice.
+\subsection{Colors}\label{colors}
+This is the third draft of implementing color\index{color} specifications in
+a \HINT\ file.
 
-A \HINT\ viewer must be capable of rendering a page given just any valid
-position inside the content section. Therefore \HINT\ files are stateless;
-there is no need to search for preceding commands that might change a state
-variable.
-As a consequence, we can not just define a ``color change node''.
-Colors could be specified as an optional parameter of a glyph node, but the
-amount of data necessary would be considerable. In texts, on the other hand,
-a color change control code would be possible because we parse texts only in forward
-direction. The current font  would then become a current color and font.
+According to the initial philosophy of a \HINT\ file, a viewer must be
+capable of rendering a page given just any valid position in the
+content section without reading the entire file.  This makes it
+impossible to use global information; only the information that is
+localy available can be used.  Given a file position, the viewer will
+compute a representation of the page, insert it into a page template,
+and pass it to the renderer.  Color will not effect the position of
+glyphs or rules and so it is sufficient to process the color
+information when rendering the page.  The renderer will, however,
+render the page always from the top down and from left to right.  As a
+consequence of the rendering order, it is very well possible to work
+with a color state within the top level boxes.
 
-An attractive alternative would be colored fonts. 
-This would require an optional color argument for a font. 
-For example one could have a cmr10 font in black as
-font number 3, and the same cmr10 font in blue as font number 4. Having 256 different fonts,
-this is definitely a possibility because rarely you would need that many fonts 
-or that many colors. If necessary and desired, one could allow 16 bit font numbers
-of overcome the problem.
+A separate issue is the specification of color changes on the top
+level.  While a vertical list contains no character nodes, a color
+specification might still affect the background color and the
+foreground color of rules.  Because we still want to avoid the search
+for color nodes on the top level, we restrict the scope of a color
+node on the top level.  It will extend only to the next possible page
+break and applications like Hi\TeX\ must repeat a top level color node
+after every node that could be used as a page break.
 
-Background colors could be associated with boxes as an optional parameter.
-In addition to the background color, a frame color and frame thickness
-for a box could be desirable. Because pages are using a page template there
-would be no need to an extra page color. The page color could simply be
-given as the color of the outer box in the template.
-Even for extended boxes such aditional parameters can be implemented.
+% Some statisticts
+% format.hnt 4065407 1103094 byte (compressed), 31802 top level content nodes
+% Nodes that could be page breaks:
+% glue nodes 12346 if the preceeding node is a page break
+% kern nodes 0 if the next node is a glue.
+% penalty nodes 2193 (unless they are infinity or bigger)
+% so about 15000 extra color nodes using about 45000 bytes
+% could be needed. The extra space required is close to 1 percent
+% not counting compression.
+% Link nodes 10154 (5077 on and 5077 off nodes)
+% Having extra color nodes for links is at most 30462 byte.
+% This is less than 1 percent --- again without accounting for compression.
+% This could be reduced to 10154 byte if we use the b100 bit
+% and include the color ref in the link node - which might be
+% a good idea.
 
-Colored boxes, however, are not the perfect solution for highlighting text
-because boxes interfer with line breaking. Enclosing a phrase in a box just
-to give it a special background will make it impossible for the line breaking
-routine to insert line breaks. Therefore, paragraph nodes might benefit from
-a color change command for the background (and foreground) color.
+The nesting of boxes on a page together with the transparency of colors
+leads to the problem of stacking several layers of color one on top
+of the other.
+Here is an example: An outer box might specify blue as a background color
+and white as a forground color while  an inside box specifies a transparent
+grey background and a transparent black foreground.
+Then we expect text in the outer box to have white letters on blue background.
+Further we want to see the inner box casting a grey shadown on the blue
+background, resulting in a mix of blue and gray, with black letters on
+top of it that are not completely black but let the background shine through.
 
+To limit the complexity, the \HINT\ file format will allow this stacking
+of colors only when nesting boxes. But inside a box, there is at any position
+only one foreground and one background color; a color change inside a box
+will simply replace the current colors.
 
+If an application like Hi\TeX\ wants
+to implement nesting colors inside a box, it has to implement its own color
+stack and compute the necessary color mixtures.
+There is only one exception to this concept: When a new box starts,
+the current colors will be those of the enclosing box. These colors
+can be restored after a color change by using the \<color off> command.
+
+The limited complexity is necessary to simplifies the spliting of
+boxes, for example by the line breaking routine. Repeating the last
+color node before the split just after the split is sufficient.
+
+Inside a horizontal list, a background color will extend from
+top to bottom; inside a vertical list a background color will extend
+from the left edge to the right edge.
+If the document does not want to change the background color,
+a completely transparent color should be used.
+
+While the current implementation of searching does not use the
+background color, a color set will still specify background and foreground
+for all colors. This is simpler, easier to extend at a later time,
+and the overhead is small.
+
+
+After these preliminaries let's turn our attention to the design of
+a suitable color concept.
+
+
+%Before the present implementation of colors,
+%we used a foreground color and a
+%background color; then we had a special foreground color for links;
+%and finaly the implementation of searching used special forground
+%colors to mark matches and highlight the current search focus.  As if
+%that was not sufficient, viewers could be switched to ``dark mode'' using
+%a different forground and background color, and of course it was
+%desirable to adjust the link, mark, and focus color as well.
+%
+%In the future, a document designer might want to indicate a link using a
+%different background color instead or in combination with a special
+%foreground color. Similar considerations apply to the colors used for
+%searching.  By the way: the interaction of link color with mark or
+%focus color was an open question; probably mixing the colors might be a
+%good solution.  But there is another feature that sets links appart
+%from the matching text in a search: The start and end of a link is
+%already recorded in a \HINT\ file. So an automatic color change might
+%be called for.
+
+%In the first redesign, a color set consisted of eight color pairs for
+%normal, link, mark, and focus colors in day mode
+%and four more color pairs for night mode;
+%each pair specifying a background and a foreground color.
+%
+%It turned out that color switching using three bits in a status
+%byte was inconvenient. Further this solution was mixing two different
+%causes for a color change: The doument author's requests for a color
+%change and the user interface's requests for a color change either
+%by switching between day and night mode or by searching.
+%While switching beween day and night mode requires the author to
+%supply two complete color schemas, searching just needs to change
+%the color of glyphs according the the given color schema.
+%While the color change for links is always known from the document,
+%the color changes due to searching depend on text input at run time.
+%So mixing all that together was possibly not the best solution.
+
+%The new and second redesign tries to seperate the different concerns.
+
+Colors come in sets.
+A color set supports two modes: day and night mode.
+In future extensions it might be possible for 
+an author to invent color sets for winter or summer, fall or
+spring, or any other resonable or unreasonable purpose.
+For each mode a color set specifies three color styles:
+one for normal text, one for marked text and one for in-focus text.
+The switching between different modes and different styles is
+left to the user interface.
+
+We store a color set as an array of 12 words. 
+The first 6 words are for day mode the next 6 byte are for night mode;
+For each mode we have three color pairs and each pair consists
+of a forgraound and a backgraund color each stored as an RGBA value.
+
+@<hint basic types@>=
+typedef uint32_t ColorSet[2*3*2];
+@
+To extract the various sub-arrays, we have the following macros:
+@<hint macros@>=
+#define CURCOLOR(M,S,C) ((C)+6*(M)+2*(S))
+#define DAY(C)   CURCOLOR(0,0,C)
+#define NIGHT(C) CURCOLOR(1,0,C)
+#define HIGH(C)  CURCOLOR(0,1,C)
+#define FOCUS(C) CURCOLOR(0,2,C)
+#define FG(C)    ((C)[0])
+#define BG(C)    ((C)[1])
+@
+
+We will allow up to 255 color sets that are stored in the definition
+section and are referenced in the content section by a single byte.
+The definition of different color sets and the switching between them
+is left to the document author.
+
+The color set with reference number zero specifies the default colors.
+At the root of a page template, the default color set is selected
+and the whole page is filled with the background color for normal text.
+For links, by default the color set with number one is used.
+Section ~\secref{colordefault} specifies default values for both
+color sets; the default colors can be overwritten.
+The color sets with reference numbers zero and one are not stored in the
+definition section of a short format file if they are the same as the default values.
+This makes files not using colors compatible with older versions of the \HINT\ file
+format.
+
+Now we are ready for the implementation.
+
+\vbox{\readcode\vskip -\baselineskip\putcode}
+
+ at s COLOR  symbol
+ at s color symbol
+ at s color_pair symbol
+ at s color_tripple symbol
+ at s color_set symbol
+ at s color_null symbol
+
+@<symbols@>=
+%token COLOR "color"
+@
+
+@<scanning rules@>=
+::@=color@>              :<     return COLOR;    >:
+@
+
+Colors can be specified as a single number, preferably in hexa\-decimal
+notation, giving the red, green, blue, and alpha value in a single
+number. For example \.{0xFF0000FF} would be pure red,
+and \.{0x00FF0080} would be transparent green.
+Of course even decimal values can be used. A good example is the
+value \.{0} which is equivalent to but a bit shorter than \.{0x0} or
+\.{0x00000000} which describes a completely transparent black.
+It is invisible because the alpha value is zero.
+
+Alternatively, colors can be given as a list of three or four numbers
+enclosed in pointed brackets \.{<} \dots \.{>}.
+If only three numbers are given, the color is opaque with an alpha
+value equivalent to \.{0xFF}. Using this format
+the same colors as before can be written \.{<0xFF 0 0>} (pure red),
+\.{<0 0xFF 0 0x80>} (transparent green) and \.{<0 0 0 0>} (transparent black).
+
+The parser will put the color definition into |colors_n|
+using the index |colors_i|. As we will see later, the |colors_n|
+array is initialized with the colors in |colors_0| which in turn
+is initialized from |color_defaults[0]|.
+|colors_0| can be changed but only if that change occurs before
+any other color definition.
+
+@<common variables@>=
+ColorSet colors_0, colors_n; /* default and current color set */
+int colors_i; /* current color */
+@
+
+@<initialize definitions@>=
+{ int i;
+  for (i=0;i<sizeof(ColorSet)/4;i++)
+    colors_0[i]=color_defaults[0][i];
+}
+@
+
+@<parsing rules@>=@/
+color: START UNSIGNED UNSIGNED UNSIGNED UNSIGNED END@|
+     { RNG("red",$2,0,0xFF); RNG("green",$3,0,0xFF);
+       RNG("blue",$4,0,0xFF); RNG("alpha",$5,0,0xFF);
+       colors_n[colors_i++]=($2<<24)|($3<<16)|($4<<8)|$5;
+     }
+     | START UNSIGNED UNSIGNED UNSIGNED END@|
+     { RNG("red",$2,0,0xFF); RNG("green",$3,0,0xFF);
+       RNG("blue",$4,0,0xFF);
+       colors_n[colors_i++]=($2<<24)|($3<<16)|($4<<8)|0xFF;
+     };
+color: UNSIGNED { colors_n[colors_i++]=$1;};
+@
+
+Colors are always specified in pairs: a foreground color folowed by
+background color enclosed in pointed brackets \.{<} \dots \.{>} as
+usual. For convenience, the background color can be omited;
+in this case a completely transparent background is assumed.
+
+@<parsing rules@>=@/
+color_pair: START color color END
+	  | START color END { colors_n[colors_i++]=0; };
+color_unset: { colors_i+=2;};	  
+@
+
+A complete color set consists of six color pairs
+organized in two |color_tripple|s:
+the first three pairs for normal, mark, and focus text
+in day mode are followed by the three pairs in night mode.
+The |color_tripple| for night mode is optional; and within
+a |color_tripple| all color pairs except the first one are
+optional. An omited color is replaced by the
+corresponding color from the color set zero. To make the replacement
+process more predictable, the specification of color set zero---if
+present---must come first.
+If the default color set itself is redefined, an unspecified
+color will not change the default color.
+
+To be open to future changes, color set definitions in the short format
+will contain after the reference number the number of color pairs that follow.
+Currently this value is always six.
+
+
+@<parsing rules@>=@/
+color_tripple: START color_pair color_unset color_unset END 
+          | START color_pair color_pair color_unset END
+          | START color_pair color_pair color_pair END
+          ;
+	  
+color_set: color_tripple color_tripple;
+color_set: color_tripple color_unset color_unset color_unset;
+
+def_node: start COLOR ref { HPUT8(6); color_init(); } color_set END
+        { DEF($$,color_kind,$3); hput_color_def($1,$3); };
+@
+
+@<put functions@>=
+void color_init(void)
+{ int i;
+  for (i=0;i<sizeof(ColorSet)/4;i++) colors_n[i]=colors_0[i];
+  colors_i=0;
+}
+
+static Tag hput_color_set(int n)
+{ static bool first_color=true;
+  int i;
+  if (n==0)
+  { if (first_color)
+      for (i=0;i<sizeof(ColorSet)/4;i++) colors_0[i]=colors_n[i];
+    else
+      QUIT("Redefinition of color set 0 must be the first color definition");
+  }
+  first_color=false;
+  HPUTX(sizeof(ColorSet)+1);
+  for (i=0;i<sizeof(ColorSet)/4;i++) HPUT32(colors_n[i]);
+  return TAG(color_kind,b000);
+}
+@
+
+The |hput_color_def| checks if color sets zero or one need to be written.
+If not, the function will reset |hpos| to undo the writing of the tag
+and the number of colors in the set.
+
+@<put functions@>=
+static bool colors_equal(ColorSet a, ColorSet b)
+{ int i;
+  for (i=0;i<sizeof(ColorSet)/4;i++)
+    if (a[i]!=b[i]) return false;
+  return true;
+}
+
+void hput_color_def(uint32_t pos, int n)
+{ if ((n==0 && colors_equal(color_defaults[0], colors_n)) || 
+      (n==1 && colors_equal(color_defaults[1], colors_n)))
+  { hpos=hstart+pos;
+    return;
+  }
+  hput_tags(pos,hput_color_set(n));
+}
+@
+
+Compared to the definitions, the content nodes are pretty simple.
+The special color number |0xFF| is reserved to indicate an 
+\<color off> node in the short format.
+
+@<parsing rules@>=
+content_node: start COLOR ref END
+    {REF_RNG(color_kind,$3); hput_tags($1,TAG(color_kind,b000));};
+content_node: start COLOR OFF END
+    { HPUT8(0xFF); hput_tags($1,TAG(color_kind,b000));};
+@
+
+\vbox{\writecode\vskip -\baselineskip\getcode}
+
+We contine with the color content nodes:
+@<cases to get content@>=
+ at t\1\kern1em@>
+case TAG(color_kind,b000):
+  { uint8_t n=HGET8;@+
+    if (n==0xFF) hwritef(" off");
+    else { REF(color_kind,n); @+hwrite_ref(n);@+}
+  }
+  break;
+@
+
+And now we turn to the color definitions:
+
+@<get functions@>=
+void hwrite_color_pair(uint32_t f, uint32_t b)
+{ hwritec('<');
+  if (f==0) hwritec('0'); else hwritef("0x%08X",f);
+  if (b!=0) hwritef(" 0x%08X",b);
+  hwritec('>');
+}
+
+void hget_color_set(uint32_t node_pos, ColorSet cs)
+{ int i,m;
+  for (i=0;i<sizeof(ColorSet)/4;i++)
+    HGET32(cs[i]);
+  for(m=0;m<2;m++)  
+  { uint32_t *c, *d;
+    bool diff_high, diff_focus;
+    if (m==0)
+    { c=cs; d=color_defaults[0]; }
+    else
+    { c=NIGHT(cs); d=NIGHT(color_defaults[0]);
+      if (memcmp(c,d,sizeof(ColorSet)/2)==0)
+        return;
+    }
+    hwrite_start();
+    diff_high=FG(HIGH(c))!=FG(HIGH(d))|| BG(HIGH(c))!=BG(HIGH(d));
+    diff_focus=FG(FOCUS(c))!=FG(FOCUS(d))||BG(FOCUS(c))!=BG(FOCUS(d));
+    hwrite_color_pair(FG(c),BG(c));
+    if (diff_high || diff_focus)  
+    { hwritec(' '); hwrite_color_pair(FG(HIGH(c)),BG(HIGH(c)));}
+    if (diff_focus) 
+    { hwritec(' '); hwrite_color_pair(FG(FOCUS(c)),BG(FOCUS(c)));}
+    hwrite_end();
+  }
+}
+@
+
+@<cases to get definitions for |color_kind|@>=
+ case b000:
+   { int k;
+     ColorSet c;
+     static bool first_color=true;
+     k=HGET8;
+     if (k<6) 
+       QUIT("Definition %d of color set needs 6 color pairs only %d given\n",n,k);
+     hget_color_set(node_pos,c);
+     if (n==0)
+     { if (!first_color)
+         QUIT("Definition of color set zero must be first");
+       memcpy(&color_defaults[0],&c,sizeof(ColorSet));
+     }
+     first_color=false;
+   }
+   break;
+@
+
 \subsection{Rotation}
 When it comes to rotation, there is a big difference between printed books and
 computer displays. For example, if a book contains a table that is rotated
@@ -7581,13 +7994,7 @@
 @<compute a local |aux_name|@>=
 { char *path=dir[i].file_name;
   int path_length=(int)strlen(path);
-  int aux_length;
   @<determine whether |path| is absolute or relative@>@;
-  aux_length=stem_length+ext_length+path_length;
-  ALLOCATE(aux_name,aux_length+1,char);
-  strcpy(aux_name,stem_name);
-  strcpy(aux_name+stem_length,aux_ext[name_type]);
-  strcpy(aux_name+stem_length+ext_length,path);
   @<replace links to the parent directory@>@; 
   DBG(DBGDIR,"Replacing auxiliary file name:\n\t%s\n->\t%s\n",path,aux_name);
 }
@@ -7594,17 +8001,24 @@
 @
 
 @<determine whether |path| is absolute or relative@>=
+  int aux_length;
   enum {absolute=0, relative=1} name_type;
   char *aux_ext[2]={".abs/",".rel/"};
   int ext_length=5;
+  aux_length=stem_length+ext_length+path_length;
+  ALLOCATE(aux_name,aux_length+1,char);
+  strcpy(aux_name,stem_name);
   if (path[0]=='/')
   { name_type=absolute;
-    path++; path_length--;
+    strcpy(aux_name+stem_length,aux_ext[name_type]);
+    strcpy(aux_name+stem_length+ext_length,path+1);  
   }
   else if (path_length>3 && isalpha(path[0]) &&
            path[1]==':' && path[2]=='/')
   { name_type=absolute;
-    path[1]='_';
+    strcpy(aux_name+stem_length,aux_ext[name_type]);
+    strcpy(aux_name+stem_length+ext_length,path);
+    aux_name[stem_length+ext_length+1]='_';
   }      
   else
     name_type=relative;
@@ -7617,7 +8031,7 @@
 
 @<replace links to the parent directory@>=
 { int k;
-  for (k=0; k<aux_length-3;k++) 
+  for (k=stem_length+ext_length; k<aux_length-3;k++) 
     if (aux_name[k]=='.'&& aux_name[k+1]=='.'&& aux_name[k+2]=='/')
     { aux_name[k]=aux_name[k+1]='_';k=k+2;}
 }
@@ -7925,7 +8339,7 @@
         aux_names[i]=aux_name;
       else 
       { if (option_aux) QUIT("Unable to find file '%s'",aux_name); 
-        free(aux_name);
+        free(aux_name); aux_name=NULL;
       } 
     }
     if ((aux_names[i]==NULL && !option_aux) || option_global)
@@ -8162,7 +8576,7 @@
          | INTEGER UNSIGNED   { hset_max(int_kind,$2); }
          | DIMEN UNSIGNED     { hset_max(dimen_kind,$2); }
          | LIGATURE UNSIGNED  { hset_max(ligature_kind,$2); }
-         | DISC UNSIGNED    { hset_max(disc_kind,$2); }
+         | DISC UNSIGNED      { hset_max(disc_kind,$2); }
          | GLUE UNSIGNED      { hset_max(glue_kind,$2); }
          | LANGUAGE UNSIGNED  { hset_max(language_kind,$2); }
          | RULE UNSIGNED      { hset_max(rule_kind,$2); }
@@ -8174,7 +8588,8 @@
          | STREAMDEF UNSIGNED { hset_max(stream_kind,$2); }
          | PAGE UNSIGNED      { hset_max(page_kind,$2); }
          | RANGE UNSIGNED     { hset_max(range_kind,$2); }
-         | LABEL UNSIGNED     { hset_max(label_kind,$2); };
+         | LABEL UNSIGNED     { hset_max(label_kind,$2); }
+         | COLOR UNSIGNED     { hset_max(color_kind,$2); };
 
 @
 
@@ -8227,10 +8642,11 @@
     { @<cases of getting special maximum values@>@;
       default:
         if (max_fixed[k]>max_default[k]) 
-          QUIT("Maximum value for kind %s not supported",definition_name[k]);   
-        RNG("Maximum number",n,max_default[k],MAX_REF(k));
-        max_ref[k]=n;
-        DBG(DBGDEF,"max(%s) = %d\n",definition_name[k],max_ref[k]);
+          MESSAGE("Maximum value for kind %s not supported\n",definition_name[k]);        else
+        { RNG("Maximum number",n,max_default[k],MAX_REF(k));
+          max_ref[k]=n;
+          DBG(DBGDEF,"max(%s) = %d\n",definition_name[k],max_ref[k]);
+	}
         break;
     }
     @<read and check the end byte |z|@>@;
@@ -8360,6 +8776,7 @@
 definition_bits[0][page_kind]=(1<<(MAX_PAGE_DEFAULT+1))-1;
 definition_bits[0][stream_kind]=(1<<(MAX_STREAM_DEFAULT+1))-1;
 definition_bits[0][range_kind]=(1<<(MAX_RANGE_DEFAULT+1))-1;
+definition_bits[0][color_kind]=(1<<(MAX_COLOR_DEFAULT+1))-1;
 @
 
 \goodbreak
@@ -8433,6 +8850,13 @@
         else
         { char *n; HGET_STRING(n);@+ hwrite_string(n); }
         break;
+      case color_kind:
+        switch (INFO(a))
+        { @<cases to get definitions for |color_kind|@>@;
+	  default:
+	    QUIT("Undefined tag %d for color_kind definition at 0x%x",INFO(a),node_pos);
+        }
+        break;
       default:
         hget_content(a); @+break;
     }
@@ -9152,7 +9576,7 @@
 @
 @<define |label_defaults|@>=
 max_default[label_kind]=MAX_LABEL_DEFAULT;
-printf("Label label_defaults[MAX_LABEL_DEFAULT+1]="@|"{{0,LABEL_TOP,true,0,0,0}};\n\n");
+printf("Label label_defaults[MAX_LABEL_DEFAULT+1]="@|"{{0,0,LABEL_TOP,true,0,0}};\n\n");
 @
 
 
@@ -9218,8 +9642,47 @@
 max_fixed[param_kind]=empty_list_no;
 @
 
+\subsection{Colors}\label{colordefault}
+@<default names@>=
+typedef enum {@+
+zero_color_no=0, link_color_no=1 at +
+} Color_no;
+#define MAX_COLOR_DEFAULT link_color_no
+@
 
+The default colors for day mode are
+black on white, red on white, and green on white;
+the links in day mode are blue.
+In night mode the background becomes black, the normal text white
+and the other colors become slightly lighter.
 
+We store the default color set using an byte array in RGBA format for colors;
+we combine a pair of colors for foreground and background in an array;
+we combine three pairs for normal, mark, and focus text in an array;
+and we define a color set as two such pairs, one for day and one for night mode
+to define the default colors.
+
+
+@<define |color_defaults|@>=
+max_default[color_kind]=MAX_COLOR_DEFAULT;
+max_fixed[color_kind]=-1;
+printf("ColorSet  color_defaults[MAX_COLOR_DEFAULT+1]=\n"@|
+       "{{0x000000FF, 0xFFFFFF00,\n" /* black on white */@|
+       "  0xEE0000FF, 0xFFFFFF00,\n" /* dark red */
+       "  0x00EE00FF, 0xFFFFFF00,\n" /* dark green */@|
+       "  0xFFFFFFFF, 0x00000000," /* white on black */
+       "  0xFF1111FF, 0x00000000,\n" /* light red */
+       "  0x11FF11FF, 0x00000000},\n" /* light green*/@| 
+       " {0x0000EEFF, 0xFFFFFF00,\n" /* dark blue on white */
+       "  0xEE0000FF, 0xFFFFFF00,\n" /* dark red on white */
+       "  0x00EE00FF, 0xFFFFFF00,\n" /* dark green on white */@| 
+       "  0x1111FFFF, 0x00000000,\n" /* light blue on black */
+       "  0xFF1111FF, 0x00000000,\n" /* light red on black */
+       "  0x11FF11FF, 0x00000000\n" /* light green on black */
+       "}};\n\n");
+@
+
+
 \section{Content Section}
 The content section\index{content section} is just a list of nodes. 
 Within the \.{shrink} program,
@@ -10065,15 +10528,19 @@
 @
 
 \subsection{Links}\index{link}
-Links contain either a 2 byte or a 1 byte reference.
+Links contain either a 2 byte or a 1 byte reference and possibly a color reference.
 @<initialize the  |hnode_size| array@>=
 hnode_size[TAG(link_kind,b000)] = NODE_SIZE(1,0);
 hnode_size[TAG(link_kind,b001)] = NODE_SIZE(2,0);
 hnode_size[TAG(link_kind,b010)] = NODE_SIZE(1,0);
 hnode_size[TAG(link_kind,b011)] = NODE_SIZE(2,0);
+hnode_size[TAG(link_kind,b100)] = NODE_SIZE(2,0);
+hnode_size[TAG(link_kind,b101)] = NODE_SIZE(3,0);
+hnode_size[TAG(link_kind,b110)] = NODE_SIZE(2,0);
+hnode_size[TAG(link_kind,b111)] = NODE_SIZE(3,0);
 @
 
-\subsection{Stream Nodes}\index{stream}
+\subsection{Streams}\index{stream}
 After the stream reference follows a parameter list, either as reference
 or as a list, and then a content list.
 @<initialize the  |hnode_size| array@>=
@@ -10082,6 +10549,10 @@
 hnode_size[TAG(stream_kind,b100)] = NODE_SIZE(1,0);
 @
 
+\subsection{Colors}\index{color}
+@<initialize the  |hnode_size| array@>=
+hnode_size[TAG(color_kind,b000)] = NODE_SIZE(1,0);
+@
 
 \section{Reading Short Format Files Backwards}
 This section is not really part of the file format definition, but it
@@ -10592,7 +11063,7 @@
 \noindent
 @<skip macros@>=
 #define @[HTEG_LINK(I)@] @/\
-{ uint16_t n; if (I&b001) HTEG16(n);@+ else n=HTEG8; @+}
+{ uint16_t n;  if (I&b100) n=HTEG8; if (I&b001) HTEG16(n);@+ else n=HTEG8; @+}
 @
 
 @<cases to skip content@>=
@@ -10600,8 +11071,18 @@
 case TAG(link_kind,b001): @+ HTEG_LINK(b001); @+break;
 case TAG(link_kind,b010): @+ HTEG_LINK(b010); @+break;
 case TAG(link_kind,b011): @+ HTEG_LINK(b011); @+break;
+case TAG(link_kind,b100): @+ HTEG_LINK(b100); @+break;
+case TAG(link_kind,b101): @+ HTEG_LINK(b101); @+break;
+case TAG(link_kind,b110): @+ HTEG_LINK(b110); @+break;
+case TAG(link_kind,b111): @+ HTEG_LINK(b111); @+break;
 @
 
+\subsection{Colors}
+\noindent
+@<cases to skip content@>=
+ at t\1\kern1em@>
+case TAG(color_kind,b000): @+ (void)HTEG8; @+break;
+@
 
 \subsection{Plain Lists, Texts, and Parameter Lists}\index{list}
 
@@ -10802,7 +11283,7 @@
 #error  @=float64 type must have size 8@>
 #endif
 #define HINT_VERSION 2
-#define HINT_MINOR_VERSION 0
+#define HINT_MINOR_VERSION 1
 #define AS_STR(X) #X
 #define VERSION_AS_STR(X,Y) AS_STR(X) "." AS_STR(Y)
 #define HINT_VERSION_STRING VERSION_AS_STR(HINT_VERSION, HINT_MINOR_VERSION)
@@ -10833,6 +11314,7 @@
 extern Glue glue_defaults[MAX_GLUE_DEFAULT+1];
 extern Baseline baseline_defaults[MAX_BASELINE_DEFAULT+1];
 extern Label label_defaults[MAX_LABEL_DEFAULT+1];
+extern ColorSet color_defaults[MAX_COLOR_DEFAULT+1];
 extern signed char hnode_size[0x100];
 extern uint8_t content_known[32];
 
@@ -10881,6 +11363,7 @@
   @<define stream defaults@>@;
   @<define range defaults@>@;
   @<define |label_defaults|@>@;
+  @<define |color_defaults|@>@;  
   @<print defaults@>@;
  
   @<initialize the  |hnode_size| array@>@;
@@ -10943,6 +11426,7 @@
 extern void hget_directory(void);
 extern void hclear_dir(void);
 extern bool hcheck_banner(char *magic);
+extern int max_range;
 
 extern void hget_max_definitions(void);
 extern uint32_t hget_utf8(void);
@@ -11008,6 +11492,7 @@
 extern uint8_t *hpos, *hstart, *hend, *hpos0;
 extern int next_range;
 extern RangePos *range_pos;
+extern int next_range, max_range;
 extern int *page_on; 
 extern Label *labels;
 extern int first_label;
@@ -11026,7 +11511,7 @@
 extern void hput_content_end(void);
 
 extern void hset_label(int n,int w);
-extern Tag hput_link(int n, int on);
+extern Tag hput_link(int n, int c, int on);
 extern void hset_outline(int m, int r, int d, uint32_t p);
 extern void hput_label_defs(void);
 
@@ -11054,6 +11539,10 @@
 extern Info hput_span_count(uint32_t n);
 extern void hextract_image_dimens(int n, double *a, Dimen *w, Dimen *h);
 extern Info hput_image_spec(uint32_t n, float32_t a, uint32_t wr, Xdimen *w, uint32_t hr, Xdimen *h);
+extern int colors_i;
+extern ColorSet colors_0, colors_n;
+extern void color_init(void);
+extern void hput_color_def(uint32_t pos, int n);
 extern void hput_string(char *str);
 extern void hput_range(uint8_t pg, bool on);
 extern void hput_max_definitions(void);

Modified: trunk/Build/source/texk/web2c/hitexdir/hilexer.c
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/hilexer.c	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/hilexer.c	2024-11-11 13:34:37 UTC (rev 72815)
@@ -450,8 +450,8 @@
 /* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\
 	(yy_c_buf_p) = yy_cp;
 /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
-#define YY_NUM_RULES 129
-#define YY_END_OF_BUFFER 130
+#define YY_NUM_RULES 130
+#define YY_END_OF_BUFFER 131
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -459,50 +459,50 @@
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static const flex_int16_t yy_accept[388] =
+static const flex_int16_t yy_accept[390] =
     {   0,
-        0,    0,    0,    0,    0,    0,  130,  128,    6,    6,
-       43,   47,   10,  128,  117,  128,    4,    4,    1,    2,
-       41,  127,  127,  127,  127,  127,  127,  127,   31,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-       32,  127,  127,   40,   14,   15,   13,   11,   74,   74,
-       58,   72,   48,   73,   49,   50,   74,  129,  129,  129,
-      129,    0,    0,    0,    0,    0,    0,    0,    7,    5,
-        5,    9,    9,    0,    0,    0,    4,  127,  127,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,  127,  127,  127,   29,  127,  127,  127,  127,
+        0,    0,    0,    0,    0,    0,  131,  129,    6,    6,
+       43,   47,   10,  129,  118,  129,    4,    4,    1,    2,
+       41,  128,  128,  128,  128,  128,  128,  128,   31,  128,
+      128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+       32,  128,  128,   40,   14,   15,   13,   11,   74,   74,
+       58,   72,   48,   73,   49,   50,   74,  130,  130,  130,
+      130,    0,    0,    0,    0,    0,    0,    0,    7,    5,
+        5,    9,    9,    0,    0,    0,    4,  128,  128,  128,
+      128,  128,  128,  128,  128,  128,  128,  128,  128,  128,
+      128,  128,  128,  128,  128,   29,  128,  128,  128,  128,
 
-      127,  127,  127,   28,  127,   97,  127,  127,  127,  127,
-       27,  127,  127,  127,  127,  127,  127,  127,   86,  127,
-      127,  127,  127,  127,  127,   12,    0,   58,   58,    0,
+      128,  128,  128,   28,  128,   97,  128,  128,  128,  128,
+       27,  128,  128,  128,  128,  128,  128,  128,   86,  128,
+      128,  128,  128,  128,  128,   12,    0,   58,   58,    0,
        59,   55,   52,   56,   60,   53,   54,   57,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,   51,   71,
        75,    0,    0,   20,   20,   16,    0,    0,    0,    5,
-        0,    9,   24,    8,   85,  127,  127,  127,  108,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,   33,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,   37,  127,
-      127,  127,  127,  127,  127,  127,  127,  127,  123,  109,
+        0,    9,   24,    8,   85,  128,  128,  128,  108,  128,
+      128,  128,  128,  128,  128,  128,  128,  128,   33,  128,
+      128,  128,  128,  128,  128,  128,  128,  128,   37,  128,
+      128,  128,  128,  128,  128,  128,  128,  128,  124,  109,
 
-      127,   98,  127,  127,   95,  127,  127,  127,  102,  127,
-      127,  127,  127,  127,  116,  127,  127,  127,  127,  127,
-      127,   59,    0,    0,    0,    0,    0,    0,    0,    0,
+      128,   98,  128,  128,   95,  128,  128,  128,  102,  128,
+      128,  128,  128,  128,  117,  128,  128,  128,  128,  128,
+      128,   59,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,   76,    0,   18,   17,   21,    0,    0,    0,
-        0,    0,  127,  127,  127,  127,  127,  127,  127,  127,
-      127,  127,   94,  127,   34,  127,  125,   44,  127,   78,
-      127,  127,   82,  127,  101,   42,  127,  127,  115,  127,
-      127,  110,   96,  127,  127,  118,  127,  127,   45,  127,
-       39,  127,  127,  127,  127,  127,   79,  127,   84,  127,
-      127,   70,   65,   61,   66,   69,   63,   64,   62,   68,
+        0,    0,  128,  128,  128,  128,  128,  128,  128,  128,
+      128,  128,  128,   94,  128,   34,  128,  126,   44,  128,
+       78,  128,  128,   82,  128,  101,   42,  128,  128,  116,
+      128,  128,  110,   96,  128,  128,  119,  128,  128,   45,
+      128,   39,  128,  128,  128,  128,  128,   79,  128,   84,
+      128,  128,   70,   65,   61,   66,   69,   63,   64,   62,
 
-       67,   77,   19,   22,    0,    0,   24,   25,  127,   89,
-      127,  127,  127,  127,  127,   87,   26,  127,  127,   35,
-      114,    3,  127,   81,  104,  107,  127,  127,  127,   46,
-      127,  124,  127,  119,  127,  127,  127,  100,  127,   83,
-      105,  127,   23,    0,   99,  127,   90,  103,  127,  127,
-      127,   91,  106,  127,  127,  127,  127,  127,  127,  127,
-      113,  127,   30,    0,   25,  127,  126,  127,  127,  127,
-       88,  127,  111,   36,  121,   80,  112,   92,  127,  127,
-       38,   93,  127,  120,  127,  122,    0
+       68,   67,   77,   19,   22,    0,    0,   24,   25,  128,
+       89,  128,  128,  112,  128,  128,  128,   87,   26,  128,
+      128,   35,  115,    3,  128,   81,  104,  107,  128,  128,
+      128,   46,  128,  125,  128,  120,  128,  128,  128,  100,
+      128,   83,  105,  128,   23,    0,   99,  128,   90,  103,
+      128,  128,  128,   91,  106,  128,  128,  128,  128,  128,
+      128,  128,  114,  128,   30,    0,   25,  128,  127,  128,
+      128,  128,   88,  128,  111,   36,  122,   80,  113,   92,
+      128,  128,   38,   93,  128,  121,  128,  123,    0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -548,103 +548,103 @@
         4,    1,    1,    1,    4
     } ;
 
-static const flex_int16_t yy_base[393] =
+static const flex_int16_t yy_base[395] =
     {   0,
-        0,    0,   65,  130,  194,  258,  644,  645,  645,  645,
-      645,  645,   74,   68,   64,   68,   77,   72,  645,  645,
-      645,   53,   61,   58,   59,  585,   57,  596,   65,   65,
-        0,  602,   81,   74,  100,  106,  107,   69,  108,  592,
-      108,  596,  600,  645,  645,  645,  645,  628,  645,  144,
-      148,  161,  645,  645,  645,  645,  322,  645,  575,  574,
-      573,  624,  623,  622,  569,  568,  567,  111,  645,  645,
-      151,  157,  161,  164,  168,  187,  172,    0,  121,  584,
-      573,  571,  576,   24,  166,  170,  573,  172,  574,  143,
-      572,  577,  584,  579,  582,  562,  576,  562,  183,  578,
+        0,    0,   65,  130,  194,  258,  646,  647,  647,  647,
+      647,  647,   74,   68,   64,   68,   77,   72,  647,  647,
+      647,   53,   61,   58,   59,  587,   57,  598,   65,   65,
+        0,  604,   81,   74,  100,  106,  107,   69,  108,  594,
+      108,  598,  602,  647,  647,  647,  647,  630,  647,  144,
+      148,  161,  647,  647,  647,  647,  322,  647,  577,  576,
+      575,  626,  625,  624,  571,  570,  569,  111,  647,  647,
+      151,  157,  161,  164,  168,  187,  172,    0,  121,  586,
+      575,  573,  578,   24,  166,  170,  575,  172,  576,  143,
+      574,  579,  586,  581,  584,  564,  578,  564,  183,  580,
 
-      159,  167,  182,    0,  572,    0,  557,  185,  562,  554,
-        0,  560,  550,  560,  568,  561,  551,  566,  551,  555,
-      550,  563,  558,  558,  552,  645,  230,  236,  240,  244,
-      246,  264,  645,  645,  645,  645,  645,  645,  236,  257,
-      263,  266,  269,  272,  276,  279,  282,  285,  645,  645,
-      645,  533,  532,  645,  583,  582,  581,  528,  527,  288,
-      291,  315,  353,  357,    0,  532,  545,  546,    0,  530,
-      528,  528,  538,  526,  540,  539,  540,  541,  529,  521,
-      519,  533,  521,  512,  528,  531,  513,  525,    0,  518,
-      516,  524,  521,  507,  522,  524,  513,  515,    0,    0,
+      159,  167,  182,    0,  574,    0,  559,  185,  564,  556,
+        0,  562,  552,  562,  570,  563,  553,  568,  553,  557,
+      552,  565,  560,  560,  554,  647,  230,  236,  240,  244,
+      246,  264,  647,  647,  647,  647,  647,  647,  236,  257,
+      263,  266,  269,  272,  276,  279,  282,  285,  647,  647,
+      647,  535,  534,  647,  585,  584,  583,  530,  529,  288,
+      291,  315,  353,  357,    0,  534,  547,  548,    0,  532,
+      179,  531,  541,  529,  543,  542,  543,  544,  532,  524,
+      522,  536,  524,  515,  531,  534,  516,  528,    0,  521,
+      519,  527,  524,  510,  525,  527,  516,  518,    0,    0,
 
-      501,    0,  509,  515,  518,  517,  498,  509,    0,  510,
-      494,  507,  507,  499,    0,  496,  485,  505,  487,  486,
-      492,  266,  360,  367,  370,  373,  378,  381,  391,  399,
-      402,  405,  645,  477,  645,  528,  645,  527,  474,  424,
-      412,  434,  481,  485,  486,  492,  483,  490,  480,  485,
-      478,  488,    0,  476,  477,  468,    0,    0,  477,    0,
-      459,  455,    0,  457,    0,    0,  449,  439,    0,  454,
-      434,    0,    0,  434,  443,    0,  431,  431,    0,  437,
-        0,  429,  411,  429,  424,  406,    0,  409,    0,  411,
-      406,  645,  645,  645,  645,  645,  645,  645,  645,  645,
+      504,    0,  512,  518,  521,  520,  501,  512,    0,  513,
+      497,  510,  510,  502,    0,  499,  488,  508,  490,  489,
+      495,  266,  360,  367,  370,  373,  378,  381,  391,  399,
+      402,  405,  647,  480,  647,  531,  647,  530,  477,  424,
+      412,  434,  484,  488,  489,  495,  481,  485,  492,  482,
+      487,  480,  490,    0,  478,  479,  470,    0,    0,  481,
+        0,  480,  474,    0,  462,    0,    0,  454,  441,    0,
+      456,  440,    0,    0,  440,  445,    0,  440,  440,    0,
+      439,    0,  434,  422,  437,  426,  415,    0,  418,    0,
+      413,  415,  647,  647,  647,  647,  647,  647,  647,  647,
 
-      645,  645,  645,  645,  435,  294,  645,  444,  389,    0,
-      394,  384,  386,  385,  388,    0,    0,  373,  375,    0,
-        0,    0,  358,    0,    0,    0,  375,  353,  349,    0,
-      354,    0,  347,    0,  307,  305,  293,    0,  280,    0,
-        0,  287,  645,  457,    0,  286,    0,    0,  274,  272,
-      269,    0,    0,  276,  223,  218,  225,  203,  202,  206,
-        0,  192,    0,  467,  481,  195,    0,  186,  176,  132,
-        0,  131,    0,    0,    0,    0,    0,    0,  105,   66,
-        0,    0,   57,    0,   50,    0,  645,  506,  510,  514,
-      517,   70
+      647,  647,  647,  647,  647,  444,  294,  647,  444,  391,
+        0,  401,  391,    0,  389,  388,  391,    0,    0,  379,
+      393,    0,    0,    0,  373,    0,    0,    0,  378,  360,
+      355,    0,  357,    0,  350,    0,  353,  362,  309,    0,
+      287,    0,    0,  292,  647,  457,    0,  289,    0,    0,
+      281,  280,  279,    0,    0,  285,  265,  265,  237,  211,
+      216,  224,    0,  202,    0,  467,  481,  205,    0,  197,
+      177,  132,    0,  131,    0,    0,    0,    0,    0,    0,
+      105,   66,    0,    0,   57,    0,   50,    0,  647,  506,
+      510,  514,  517,   70
 
     } ;
 
-static const flex_int16_t yy_def[393] =
+static const flex_int16_t yy_def[395] =
     {   0,
-      387,    1,  388,  388,  389,  389,  387,  387,  387,  387,
-      387,  387,  390,  391,  387,  387,  387,  387,  387,  387,
-      387,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  391,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
+      389,    1,  390,  390,  391,  391,  389,  389,  389,  389,
+      389,  389,  392,  393,  389,  389,  389,  389,  389,  389,
+      389,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  393,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
 
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
 
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  387,  387,  387,  387,  387,  387,  387,  387,  387,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  389,  389,  389,  389,  389,  389,  389,  389,
 
-      387,  387,  387,  387,  387,  387,  387,  387,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  387,  387,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  387,  387,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,
-      392,  392,  392,  392,  392,  392,    0,  387,  387,  387,
-      387,  387
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  389,  389,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  389,  389,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,  394,  394,
+      394,  394,  394,  394,  394,  394,  394,  394,    0,  389,
+      389,  389,  389,  389
 
     } ;
 
-static const flex_int16_t yy_nxt[711] =
+static const flex_int16_t yy_nxt[713] =
     {   0,
         8,    9,   10,    9,    9,   11,   12,    8,   13,   14,
         8,   15,   16,   16,    8,   17,   18,   18,   19,   20,
@@ -657,76 +657,77 @@
        71,   71,   64,   72,   73,   73,   74,   77,   77,   77,
        79,   74,   75,   75,   75,   81,   83,   85,   80,   88,
 
-       91,   86,  386,   92,  385,   89,   84,  115,  102,   82,
+       91,   86,  388,   92,  387,   89,   84,  115,  102,   82,
       116,   95,   96,   69,   93,   99,  103,   94,   97,  100,
-      104,   69,  117,  101,  384,   45,   45,   45,   45,   45,
+      104,   69,  117,  101,  386,   45,   45,   45,   45,   45,
        45,   45,   46,   45,   76,   65,   66,   67,   48,  105,
       108,  112,  118,  121,  109,  127,  128,  106,  127,  129,
-      128,  110,  129,  383,  107,  113,  119,  122,  165,  111,
-      123,  114,  127,  128,  166,  127,  160,  160,  160,  382,
-      381,   74,   75,   75,   75,   74,  162,  162,  162,  163,
+      128,  110,  129,  385,  107,  113,  119,  122,  165,  111,
+      123,  114,  127,  128,  166,  127,  160,  160,  160,  384,
+      383,   74,   75,   75,   75,   74,  162,  162,  162,  163,
       163,  163,   74,   75,   75,   75,   74,   77,   77,   77,
        45,   45,   45,   45,   45,   50,   51,  182,   52,  196,
 
        53,  183,  164,  164,  164,  173,  197,   54,  164,  164,
       164,  164,   55,   56,  161,  174,  175,  179,  192,  200,
-      198,  176,  177,  180,  199,  204,   57,  380,  379,  201,
-      193,  127,  128,  378,  127,  194,  205,  129,  128,  377,
-      129,  129,  128,  376,  129,  130,  131,  222,  130,  375,
+      198,  176,  177,  180,  199,  204,   57,  247,  382,  201,
+      193,  127,  128,  248,  127,  194,  205,  129,  128,  381,
+      129,  129,  128,  380,  129,  130,  131,  222,  130,  379,
       222,  223,  223,  223,   58,   59,   60,   61,   58,   50,
-       51,  374,   52,  373,   53,  130,  131,  222,  130,  372,
-      222,   54,  224,  224,  224,  371,   55,   56,  225,  225,
+       51,  378,   52,  377,   53,  130,  131,  222,  130,  376,
+      222,   54,  224,  224,  224,  375,   55,   56,  225,  225,
       225,  226,  226,  226,  227,  227,  227,  228,  228,  228,
        57,  229,  229,  229,  230,  230,  230,  231,  231,  231,
 
-      232,  232,  232,  160,  160,  160,  240,  240,  240,  307,
-      307,  307,  240,  240,  240,  240,  370,  369,   58,   59,
-       60,   61,   58,  130,  131,  368,  132,  367,  133,   74,
-      162,  162,  162,  366,  363,  134,  362,  135,  135,  361,
-      136,  137,  138,  360,  139,  140,  141,  142,  143,  144,
-      145,  146,  147,  148,  149,  359,  150,  150,  150,  150,
+      232,  232,  232,  160,  160,  160,  240,  240,  240,  308,
+      308,  308,  240,  240,  240,  240,  374,  373,   58,   59,
+       60,   61,   58,  130,  131,  372,  132,  371,  133,   74,
+      162,  162,  162,  370,  369,  134,  368,  135,  135,  365,
+      136,  137,  138,  364,  139,  140,  141,  142,  143,  144,
+      145,  146,  147,  148,  149,  363,  150,  150,  150,  150,
       150,  150,  150,  150,  150,  150,  150,  150,  163,  163,
       163,  242,  164,  164,  164,  223,  223,  223,  164,  164,
       164,  164,  224,  224,  224,  225,  225,  225,  226,  226,
-      226,  241,  292,  227,  227,  227,  228,  228,  228,  293,
+      226,  241,  293,  227,  227,  227,  228,  228,  228,  294,
 
-      358,  357,  294,  356,  355,  295,  229,  229,  229,  354,
-      296,  353,  352,  297,  230,  230,  230,  231,  231,  231,
-      232,  232,  232,  298,  306,  306,  351,  307,  307,  307,
-      350,  299,  349,  348,  300,  347,  346,  301,  242,  240,
-      240,  240,  345,  343,  342,  240,  240,  240,  240,  308,
-      308,  308,  341,  340,  339,  308,  308,  308,  308,  308,
-      308,  308,  338,  337,  336,  308,  308,  308,  308,  364,
-      364,  335,  365,  365,  365,  334,  333,  332,  365,  365,
-      365,  365,  365,  365,  365,  331,  330,  329,  365,  365,
-      365,  365,  328,  327,  326,  325,  365,  365,  365,  324,
+      362,  361,  295,  360,  359,  296,  229,  229,  229,  358,
+      297,  357,  356,  298,  230,  230,  230,  231,  231,  231,
+      232,  232,  232,  299,  307,  307,  355,  308,  308,  308,
+      354,  300,  353,  352,  301,  351,  350,  302,  242,  240,
+      240,  240,  349,  348,  347,  240,  240,  240,  240,  309,
+      309,  309,  345,  344,  343,  309,  309,  309,  309,  309,
+      309,  309,  342,  341,  340,  309,  309,  309,  309,  366,
+      366,  339,  367,  367,  367,  338,  337,  336,  367,  367,
+      367,  367,  367,  367,  367,  335,  334,  333,  367,  367,
+      367,  367,  332,  331,  330,  329,  367,  367,  367,  328,
 
-      323,  344,  365,  365,  365,  365,   47,   47,   47,   47,
-       49,   49,   49,   49,   63,   63,   63,   68,  322,   68,
-       68,  321,  320,  319,  318,  317,  316,  315,  314,  313,
-      312,  311,  310,  309,  305,  304,  303,  302,  291,  290,
-      289,  288,  287,  286,  285,  284,  283,  282,  281,  280,
-      279,  278,  277,  276,  275,  274,  273,  272,  271,  270,
-      269,  268,  267,  266,  265,  264,  263,  262,  261,  260,
-      259,  258,  257,  256,  255,  254,  253,  252,  251,  250,
-      249,  248,  247,  246,  245,  244,  243,  239,  238,  237,
-      236,  235,  234,  233,  221,  220,  219,  218,  217,  216,
+      327,  346,  367,  367,  367,  367,   47,   47,   47,   47,
+       49,   49,   49,   49,   63,   63,   63,   68,  326,   68,
+       68,  325,  324,  323,  322,  321,  320,  319,  318,  317,
+      316,  315,  314,  313,  312,  311,  310,  306,  305,  304,
+      303,  292,  291,  290,  289,  288,  287,  286,  285,  284,
+      283,  282,  281,  280,  279,  278,  277,  276,  275,  274,
+      273,  272,  271,  270,  269,  268,  267,  266,  265,  264,
+      263,  262,  261,  260,  259,  258,  257,  256,  255,  254,
+      253,  252,  251,  250,  249,  246,  245,  244,  243,  239,
+      238,  237,  236,  235,  234,  233,  221,  220,  219,  218,
 
-      215,  214,  213,  212,  211,  210,  209,  208,  207,  206,
-      203,  202,  195,  191,  190,  189,  188,  187,  186,  185,
-      184,  181,  178,  170,  169,  168,  167,  159,  158,  157,
-      156,  155,  154,  153,  152,  151,  126,  125,  124,  120,
-       98,   90,   87,  387,    7,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
+      217,  216,  215,  214,  213,  212,  211,  210,  209,  208,
+      207,  206,  203,  202,  195,  191,  190,  189,  188,  187,
+      186,  185,  184,  181,  178,  170,  169,  168,  167,  159,
+      158,  157,  156,  155,  154,  153,  152,  151,  126,  125,
+      124,  120,   98,   90,   87,  389,    7,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
 
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389
     } ;
 
-static const flex_int16_t yy_chk[711] =
+static const flex_int16_t yy_chk[713] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -735,81 +736,82 @@
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    3,    3,    3,    3,   84,
-       14,   84,  392,    3,   13,   13,   13,   13,   14,   15,
+       14,   84,  394,    3,   13,   13,   13,   13,   14,   15,
        15,   15,   13,   16,   16,   16,   18,   18,   18,   18,
        22,   17,   17,   17,   17,   23,   24,   25,   22,   27,
 
-       29,   25,  385,   29,  383,   27,   24,   38,   34,   23,
+       29,   25,  387,   29,  385,   27,   24,   38,   34,   23,
        38,   30,   30,   68,   29,   33,   34,   29,   30,   33,
-       34,   68,   38,   33,  380,    3,    3,    3,    3,    3,
+       34,   68,   38,   33,  382,    3,    3,    3,    3,    3,
         4,    4,    4,    4,   17,   13,   13,   13,    4,   35,
        36,   37,   39,   41,   36,   50,   50,   35,   50,   51,
-       51,   36,   51,  379,   35,   37,   39,   41,   79,   36,
-       41,   37,   52,   52,   79,   52,   71,   71,   71,  372,
-      370,   72,   72,   72,   72,   73,   73,   73,   73,   74,
+       51,   36,   51,  381,   35,   37,   39,   41,   79,   36,
+       41,   37,   52,   52,   79,   52,   71,   71,   71,  374,
+      372,   72,   72,   72,   72,   73,   73,   73,   73,   74,
        74,   74,   75,   75,   75,   75,   77,   77,   77,   77,
         4,    4,    4,    4,    4,    5,    5,   90,    5,  101,
 
         5,   90,   76,   76,   76,   85,  101,    5,   76,   76,
        76,   76,    5,    5,   72,   85,   86,   88,   99,  103,
-      102,   86,   86,   88,  102,  108,    5,  369,  368,  103,
-       99,  127,  127,  366,  127,   99,  108,  128,  128,  362,
-      128,  129,  129,  360,  129,  130,  130,  131,  130,  359,
+      102,   86,   86,   88,  102,  108,    5,  171,  371,  103,
+       99,  127,  127,  171,  127,   99,  108,  128,  128,  370,
+      128,  129,  129,  368,  129,  130,  130,  131,  130,  364,
       131,  139,  139,  139,    5,    5,    5,    5,    5,    6,
-        6,  358,    6,  357,    6,  132,  132,  222,  132,  356,
-      222,    6,  140,  140,  140,  355,    6,    6,  141,  141,
+        6,  362,    6,  361,    6,  132,  132,  222,  132,  360,
+      222,    6,  140,  140,  140,  359,    6,    6,  141,  141,
       141,  142,  142,  142,  143,  143,  143,  144,  144,  144,
         6,  145,  145,  145,  146,  146,  146,  147,  147,  147,
 
-      148,  148,  148,  160,  160,  160,  161,  161,  161,  306,
-      306,  306,  161,  161,  161,  161,  354,  351,    6,    6,
-        6,    6,    6,   57,   57,  350,   57,  349,   57,  162,
-      162,  162,  162,  346,  342,   57,  339,   57,   57,  337,
-       57,   57,   57,  336,   57,   57,   57,   57,   57,   57,
-       57,   57,   57,   57,   57,  335,   57,   57,   57,   57,
+      148,  148,  148,  160,  160,  160,  161,  161,  161,  307,
+      307,  307,  161,  161,  161,  161,  358,  357,    6,    6,
+        6,    6,    6,   57,   57,  356,   57,  353,   57,  162,
+      162,  162,  162,  352,  351,   57,  348,   57,   57,  344,
+       57,   57,   57,  341,   57,   57,   57,   57,   57,   57,
+       57,   57,   57,   57,   57,  339,   57,   57,   57,   57,
        57,   57,   57,   57,   57,   57,   57,   57,  163,  163,
       163,  164,  164,  164,  164,  223,  223,  223,  164,  164,
       164,  164,  224,  224,  224,  225,  225,  225,  226,  226,
       226,  163,  223,  227,  227,  227,  228,  228,  228,  224,
 
-      333,  331,  225,  329,  328,  226,  229,  229,  229,  327,
-      227,  323,  319,  228,  230,  230,  230,  231,  231,  231,
-      232,  232,  232,  229,  241,  241,  318,  241,  241,  241,
-      315,  230,  314,  313,  231,  312,  311,  232,  240,  240,
-      240,  240,  309,  305,  291,  240,  240,  240,  240,  242,
-      242,  242,  290,  288,  286,  242,  242,  242,  242,  308,
-      308,  308,  285,  284,  283,  308,  308,  308,  308,  344,
-      344,  282,  344,  344,  344,  280,  278,  277,  344,  344,
-      344,  344,  364,  364,  364,  275,  274,  271,  364,  364,
-      364,  364,  270,  268,  267,  264,  365,  365,  365,  262,
+      338,  337,  225,  335,  333,  226,  229,  229,  229,  331,
+      227,  330,  329,  228,  230,  230,  230,  231,  231,  231,
+      232,  232,  232,  229,  241,  241,  325,  241,  241,  241,
+      321,  230,  320,  317,  231,  316,  315,  232,  240,  240,
+      240,  240,  313,  312,  310,  240,  240,  240,  240,  242,
+      242,  242,  306,  292,  291,  242,  242,  242,  242,  309,
+      309,  309,  289,  287,  286,  309,  309,  309,  309,  346,
+      346,  285,  346,  346,  346,  284,  283,  281,  346,  346,
+      346,  346,  366,  366,  366,  279,  278,  276,  366,  366,
+      366,  366,  275,  272,  271,  269,  367,  367,  367,  268,
 
-      261,  308,  365,  365,  365,  365,  388,  388,  388,  388,
-      389,  389,  389,  389,  390,  390,  390,  391,  259,  391,
-      391,  256,  255,  254,  252,  251,  250,  249,  248,  247,
-      246,  245,  244,  243,  239,  238,  236,  234,  221,  220,
-      219,  218,  217,  216,  214,  213,  212,  211,  210,  208,
-      207,  206,  205,  204,  203,  201,  198,  197,  196,  195,
-      194,  193,  192,  191,  190,  188,  187,  186,  185,  184,
-      183,  182,  181,  180,  179,  178,  177,  176,  175,  174,
-      173,  172,  171,  170,  168,  167,  166,  159,  158,  157,
-      156,  155,  153,  152,  125,  124,  123,  122,  121,  120,
+      265,  309,  367,  367,  367,  367,  390,  390,  390,  390,
+      391,  391,  391,  391,  392,  392,  392,  393,  263,  393,
+      393,  262,  260,  257,  256,  255,  253,  252,  251,  250,
+      249,  248,  247,  246,  245,  244,  243,  239,  238,  236,
+      234,  221,  220,  219,  218,  217,  216,  214,  213,  212,
+      211,  210,  208,  207,  206,  205,  204,  203,  201,  198,
+      197,  196,  195,  194,  193,  192,  191,  190,  188,  187,
+      186,  185,  184,  183,  182,  181,  180,  179,  178,  177,
+      176,  175,  174,  173,  172,  170,  168,  167,  166,  159,
+      158,  157,  156,  155,  153,  152,  125,  124,  123,  122,
 
-      119,  118,  117,  116,  115,  114,  113,  112,  110,  109,
-      107,  105,  100,   98,   97,   96,   95,   94,   93,   92,
-       91,   89,   87,   83,   82,   81,   80,   67,   66,   65,
-       64,   63,   62,   61,   60,   59,   48,   43,   42,   40,
-       32,   28,   26,    7,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387,
+      121,  120,  119,  118,  117,  116,  115,  114,  113,  112,
+      110,  109,  107,  105,  100,   98,   97,   96,   95,   94,
+       93,   92,   91,   89,   87,   83,   82,   81,   80,   67,
+       66,   65,   64,   63,   62,   61,   60,   59,   48,   43,
+       42,   40,   32,   28,   26,    7,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
 
-      387,  387,  387,  387,  387,  387,  387,  387,  387,  387
+      389,  389,  389,  389,  389,  389,  389,  389,  389,  389,
+      389,  389
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static const flex_int32_t yy_rule_can_match_eol[130] =
+static const flex_int32_t yy_rule_can_match_eol[131] =
     {   0,
 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
     1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
@@ -817,7 +819,7 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     };
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     };
 
 static yy_state_type yy_last_accepting_state;
 static char *yy_last_accepting_cpos;
@@ -825,7 +827,7 @@
 extern int yy_flex_debug;
 int yy_flex_debug = 1;
 
-static const flex_int16_t yy_rule_linenum[129] =
+static const flex_int16_t yy_rule_linenum[130] =
     {   0,
       171,  172,  173,  174,  175,  176,  177,  179,  181,  183,
       185,  186,  187,  188,  189,  194,  195,  196,  197,  198,
@@ -839,8 +841,8 @@
       295,  297,  299,  301,  303,  305,  307,  308,  310,  312,
 
       313,  314,  315,  317,  318,  319,  321,  322,  323,  325,
-      327,  329,  331,  332,  333,  334,  335,  337,  339,  341,
-      342,  344,  346,  348,  350,  352,  354,  355
+      327,  329,  331,  333,  334,  335,  336,  337,  339,  341,
+      343,  344,  346,  348,  350,  352,  354,  356,  357
     } ;
 
 /* The intent behind this definition is that it'll catch
@@ -853,8 +855,8 @@
 char *yytext;
 #line 1 "lexer.l"
 #line 2 "lexer.l"
-	/*533:*/
-	#line 11098 "format.w"
+	/*552:*/
+	#line 11587 "format.w"
 	
 #include "hibasetypes.h"
 #include "hierror.h"
@@ -861,7 +863,7 @@
 #include "hiformat.h"
 #include "hiput.h"
 
-	/*445:*/
+	/*462:*/
 #ifdef DEBUG
 #define  YYDEBUG 1
 extern int yydebug;
@@ -868,7 +870,7 @@
 #else
 #define YYDEBUG 0
 #endif
-	/*:445*/
+	/*:462*/
 #include "hiparser.h"
 
 	/*23:*/
@@ -910,7 +912,7 @@
 
 float64_t xtof(char*x)
 {
-	#line 1385 "format.w"
+	#line 1387 "format.w"
 	int sign,digits,exp;
 	uint64_t mantissa= 0;
 	DBG(DBGFLOAT,"converting %s:\n",x);
@@ -990,13 +992,13 @@
 	}
 	/*:62*/
 int yywrap(void){
-	#line 11109 "format.w"
+	#line 11598 "format.w"
 	return 1;}
 #ifdef _MSC_VER
 #pragma  warning( disable : 4267)
 #endif
 
-#line 1000 "lexer.c"
+#line 1002 "lexer.c"
 #define YY_NO_UNISTD_H 1
 #define YY_NO_INPUT 1
 #line 152 "lexer.l"
@@ -1010,7 +1012,7 @@
 	/*:46*/	/*150:*/
 
 	/*:150*/
-#line 1014 "lexer.c"
+#line 1016 "lexer.c"
 
 #define INITIAL 0
 #define STR 1
@@ -1302,7 +1304,7 @@
 
 
 	/*3:*/
-#line 1306 "lexer.c"
+#line 1308 "lexer.c"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1331,13 +1333,13 @@
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 388 )
+				if ( yy_current_state >= 390 )
 					yy_c = yy_meta[yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
 			++yy_cp;
 			}
-		while ( yy_current_state != 387 );
+		while ( yy_current_state != 389 );
 		yy_cp = (yy_last_accepting_cpos);
 		yy_current_state = (yy_last_accepting_state);
 
@@ -1366,13 +1368,13 @@
 			{
 			if ( yy_act == 0 )
 				fprintf( stderr, "--scanner backing up\n" );
-			else if ( yy_act < 129 )
+			else if ( yy_act < 130 )
 				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
 				         (long)yy_rule_linenum[yy_act], yytext );
-			else if ( yy_act == 129 )
+			else if ( yy_act == 130 )
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				         yytext );
-			else if ( yy_act == 130 )
+			else if ( yy_act == 131 )
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 			else
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1984,108 +1986,114 @@
 #line 327 "lexer.l"
 return OUTLINE;
 	YY_BREAK
-/*:279*/	/*286:*/
+/*:279*/	/*288:*/
 case 112:
 YY_RULE_SETUP
 #line 329 "lexer.l"
-return UNKNOWN;
+return COLOR;
 	YY_BREAK
-/*:286*/	/*295:*/
+/*:288*/	/*301:*/
 case 113:
 YY_RULE_SETUP
 #line 331 "lexer.l"
-if(section_no==1)return STREAMDEF;else return STREAM;
+return UNKNOWN;
 	YY_BREAK
+/*:301*/	/*310:*/
 case 114:
 YY_RULE_SETUP
-#line 332 "lexer.l"
-return FIRST;
+#line 333 "lexer.l"
+if(section_no==1)return STREAMDEF;else return STREAM;
 	YY_BREAK
 case 115:
 YY_RULE_SETUP
-#line 333 "lexer.l"
-return LAST;
+#line 334 "lexer.l"
+return FIRST;
 	YY_BREAK
 case 116:
 YY_RULE_SETUP
-#line 334 "lexer.l"
-return TOP;
+#line 335 "lexer.l"
+return LAST;
 	YY_BREAK
 case 117:
 YY_RULE_SETUP
-#line 335 "lexer.l"
-return NOREFERENCE;
+#line 336 "lexer.l"
+return TOP;
 	YY_BREAK
-/*:295*/	/*305:*/
 case 118:
 YY_RULE_SETUP
 #line 337 "lexer.l"
-return PAGE;
+return NOREFERENCE;
 	YY_BREAK
-/*:305*/	/*313:*/
+/*:310*/	/*320:*/
 case 119:
 YY_RULE_SETUP
 #line 339 "lexer.l"
-return RANGE;
+return PAGE;
 	YY_BREAK
-/*:313*/	/*340:*/
+/*:320*/	/*328:*/
 case 120:
 YY_RULE_SETUP
 #line 341 "lexer.l"
-return DIRECTORY;
+return RANGE;
 	YY_BREAK
+/*:328*/	/*355:*/
 case 121:
 YY_RULE_SETUP
-#line 342 "lexer.l"
-return SECTION;
+#line 343 "lexer.l"
+return DIRECTORY;
 	YY_BREAK
-/*:340*/	/*361:*/
 case 122:
 YY_RULE_SETUP
 #line 344 "lexer.l"
-return DEFINITIONS;
+return SECTION;
 	YY_BREAK
-/*:361*/	/*369:*/
+/*:355*/	/*376:*/
 case 123:
 YY_RULE_SETUP
 #line 346 "lexer.l"
-return MAX;
+return DEFINITIONS;
 	YY_BREAK
-/*:369*/	/*384:*/
+/*:376*/	/*384:*/
 case 124:
 YY_RULE_SETUP
 #line 348 "lexer.l"
-return PARAM;
+return MAX;
 	YY_BREAK
-/*:384*/	/*393:*/
+/*:384*/	/*399:*/
 case 125:
 YY_RULE_SETUP
 #line 350 "lexer.l"
-return FONT;
+return PARAM;
 	YY_BREAK
-/*:393*/	/*424:*/
+/*:399*/	/*408:*/
 case 126:
 YY_RULE_SETUP
 #line 352 "lexer.l"
-return CONTENT;
+return FONT;
 	YY_BREAK
-/*:424*/
+/*:408*/	/*441:*/
 case 127:
 YY_RULE_SETUP
 #line 354 "lexer.l"
-QUIT("Unexpected keyword '%s' in line %d",yytext,yylineno);
+return CONTENT;
 	YY_BREAK
+/*:441*/
 case 128:
 YY_RULE_SETUP
-#line 355 "lexer.l"
-QUIT("Unexpected character '%c' (0x%02X) in line %d",yytext[0]>' '?yytext[0]:' ',yytext[0],yylineno);
+#line 356 "lexer.l"
+QUIT("Unexpected keyword '%s' in line %d",yytext,yylineno);
 	YY_BREAK
 case 129:
 YY_RULE_SETUP
 #line 357 "lexer.l"
+QUIT("Unexpected character '%c' (0x%02X) in line %d",yytext[0]>' '?yytext[0]:' ',yytext[0],yylineno);
+	YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 359 "lexer.l"
 ECHO;
 	YY_BREAK
-#line 2089 "lexer.c"
+#line 2097 "lexer.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(STR):
 case YY_STATE_EOF(TXT):
@@ -2408,7 +2416,7 @@
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 388 )
+			if ( yy_current_state >= 390 )
 				yy_c = yy_meta[yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2441,11 +2449,11 @@
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 388 )
+		if ( yy_current_state >= 390 )
 			yy_c = yy_meta[yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-	yy_is_jam = (yy_current_state == 387);
+	yy_is_jam = (yy_current_state == 389);
 
 		return yy_is_jam ? 0 : yy_current_state;
 }
@@ -3250,7 +3258,7 @@
 
 /* %ok-for-header */
 
-#line 357 "lexer.l"
+#line 359 "lexer.l"
 
-	/*:533*/
+	/*:552*/
 

Modified: trunk/Build/source/texk/web2c/hitexdir/hiparser.c
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/hiparser.c	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/hiparser.c	2024-11-11 13:34:37 UTC (rev 72815)
@@ -69,7 +69,7 @@
 /* First part of user prologue.  */
 #line 2 "parser.y"
 
-	#line 11139 "format.w"
+	#line 11628 "format.w"
 	
 #include "hibasetypes.h"
 #include <string.h>
@@ -79,9 +79,9 @@
 #include "hiput.h"
 extern char**hfont_name;
 
-	/*375:*/
+	/*390:*/
 uint32_t definition_bits[0x100/32][32]= {
-	#line 8341 "format.w"
+	#line 8757 "format.w"
 	{0}};
 
 #define SET_DBIT(N,K) ((N)>0xFF?1:(definition_bits[N/32][K]	|= (1<<((N)&(32-1)))))
@@ -91,16 +91,16 @@
  RNG("Definition",(D).n,max_fixed[(D).k]+1,max_ref[(D).k]);
 #define REF(K,N) REF_RNG(K,N);if(!GET_DBIT(N,K)) \
  QUIT("Reference %d to %s before definition",(N),definition_name[K])
-	/*:375*/	/*379:*/
+	/*:390*/	/*394:*/
 #define DEF_REF(D,K,M,N)  DEF(D,K,M);\
 if ((int)(M)>max_default[K]) QUIT("Defining non default reference %d for %s",M,definition_name[K]); \
 if ((int)(N)>max_fixed[K]) QUIT("Defining reference %d for %s by non fixed reference %d",M,definition_name[K],N);
-	/*:379*/
+	/*:394*/
 
 extern void hset_entry(Entry*e,uint16_t i,uint32_t size,
 uint32_t xsize,char*file_name);
 
-	/*445:*/
+	/*462:*/
 #ifdef DEBUG
 #define  YYDEBUG 1
 extern int yydebug;
@@ -107,36 +107,36 @@
 #else
 #define YYDEBUG 0
 #endif
-	/*:445*/
+	/*:462*/
 extern int yylex(void);
 
-	/*371:*/
+	/*386:*/
 void hset_max(Kind k,int n)
 {
-	#line 8183 "format.w"
+	#line 8598 "format.w"
 	DBG(DBGDEF,"Setting max %s to %d\n",definition_name[k],n);
 	RNG("Maximum",n,max_fixed[k]+1,MAX_REF(k));
 	if(n>max_ref[k])
 	max_ref[k]= n;
 	}
-	/*:371*/	/*382:*/
+	/*:386*/	/*397:*/
 void check_param_def(Ref*df)
 {
-	#line 8494 "format.w"
+	#line 8918 "format.w"
 	if(df->k!=int_kind&&df->k!=dimen_kind&&df->k!=glue_kind)
 	QUIT("Kind %s not allowed in parameter list",definition_name[df->k]);
 	if(df->n<=max_fixed[df->k]||max_default[df->k]<df->n)
 	QUIT("Parameter %d for %s not allowed in parameter list",df->n,definition_name[df->k]);
 	}
-	/*:382*/	/*444:*/
+	/*:397*/	/*461:*/
 extern int yylineno;
 int yyerror(const char*msg)
 {
-	#line 9634 "format.w"
+	#line 10097 "format.w"
 	QUIT(" in line %d %s",yylineno,msg);
 	return 0;
 	}
-	/*:444*/
+	/*:461*/
 
 
 
@@ -241,136 +241,143 @@
   YYSYMBOL_MID = 70,                       /* "mid"  */
   YYSYMBOL_LINK = 71,                      /* "link"  */
   YYSYMBOL_OUTLINE = 72,                   /* "outline"  */
-  YYSYMBOL_UNKNOWN = 73,                   /* "unknown"  */
-  YYSYMBOL_STREAM = 74,                    /* "stream"  */
-  YYSYMBOL_STREAMDEF = 75,                 /* "stream (definition)"  */
-  YYSYMBOL_FIRST = 76,                     /* "first"  */
-  YYSYMBOL_LAST = 77,                      /* "last"  */
-  YYSYMBOL_TOP = 78,                       /* "top"  */
-  YYSYMBOL_NOREFERENCE = 79,               /* "*"  */
-  YYSYMBOL_PAGE = 80,                      /* "page"  */
-  YYSYMBOL_RANGE = 81,                     /* "range"  */
-  YYSYMBOL_DIRECTORY = 82,                 /* "directory"  */
-  YYSYMBOL_SECTION = 83,                   /* "entry"  */
-  YYSYMBOL_DEFINITIONS = 84,               /* "definitions"  */
-  YYSYMBOL_MAX = 85,                       /* "max"  */
-  YYSYMBOL_PARAM = 86,                     /* "param"  */
-  YYSYMBOL_FONT = 87,                      /* "font"  */
-  YYSYMBOL_CONTENT = 88,                   /* "content"  */
-  YYSYMBOL_YYACCEPT = 89,                  /* $accept  */
-  YYSYMBOL_glyph = 90,                     /* glyph  */
-  YYSYMBOL_content_node = 91,              /* content_node  */
-  YYSYMBOL_start = 92,                     /* start  */
-  YYSYMBOL_integer = 93,                   /* integer  */
-  YYSYMBOL_string = 94,                    /* string  */
-  YYSYMBOL_number = 95,                    /* number  */
-  YYSYMBOL_dimension = 96,                 /* dimension  */
-  YYSYMBOL_xdimen = 97,                    /* xdimen  */
-  YYSYMBOL_xdimen_node = 98,               /* xdimen_node  */
-  YYSYMBOL_order = 99,                     /* order  */
-  YYSYMBOL_stretch = 100,                  /* stretch  */
-  YYSYMBOL_penalty = 101,                  /* penalty  */
-  YYSYMBOL_rule_dimension = 102,           /* rule_dimension  */
-  YYSYMBOL_rule = 103,                     /* rule  */
-  YYSYMBOL_rule_node = 104,                /* rule_node  */
-  YYSYMBOL_explicit = 105,                 /* explicit  */
-  YYSYMBOL_kern = 106,                     /* kern  */
-  YYSYMBOL_plus = 107,                     /* plus  */
-  YYSYMBOL_minus = 108,                    /* minus  */
-  YYSYMBOL_glue = 109,                     /* glue  */
-  YYSYMBOL_glue_node = 110,                /* glue_node  */
-  YYSYMBOL_position = 111,                 /* position  */
-  YYSYMBOL_content_list = 112,             /* content_list  */
-  YYSYMBOL_estimate = 113,                 /* estimate  */
-  YYSYMBOL_list = 114,                     /* list  */
-  YYSYMBOL_115_1 = 115,                    /* $@1  */
-  YYSYMBOL_text = 116,                     /* text  */
-  YYSYMBOL_txt = 117,                      /* txt  */
-  YYSYMBOL_118_2 = 118,                    /* $@2  */
-  YYSYMBOL_box_dimen = 119,                /* box_dimen  */
-  YYSYMBOL_box_shift = 120,                /* box_shift  */
-  YYSYMBOL_box_glue_set = 121,             /* box_glue_set  */
-  YYSYMBOL_box = 122,                      /* box  */
-  YYSYMBOL_hbox_node = 123,                /* hbox_node  */
-  YYSYMBOL_vbox_node = 124,                /* vbox_node  */
-  YYSYMBOL_box_flex = 125,                 /* box_flex  */
-  YYSYMBOL_box_options = 126,              /* box_options  */
-  YYSYMBOL_hxbox_node = 127,               /* hxbox_node  */
-  YYSYMBOL_vbox_dimen = 128,               /* vbox_dimen  */
-  YYSYMBOL_vxbox_node = 129,               /* vxbox_node  */
-  YYSYMBOL_box_goal = 130,                 /* box_goal  */
-  YYSYMBOL_hpack = 131,                    /* hpack  */
-  YYSYMBOL_max_depth = 132,                /* max_depth  */
-  YYSYMBOL_vpack = 133,                    /* vpack  */
-  YYSYMBOL_134_3 = 134,                    /* $@3  */
-  YYSYMBOL_135_4 = 135,                    /* $@4  */
-  YYSYMBOL_ltype = 136,                    /* ltype  */
-  YYSYMBOL_leaders = 137,                  /* leaders  */
-  YYSYMBOL_baseline = 138,                 /* baseline  */
-  YYSYMBOL_139_5 = 139,                    /* $@5  */
-  YYSYMBOL_cc_list = 140,                  /* cc_list  */
-  YYSYMBOL_lig_cc = 141,                   /* lig_cc  */
-  YYSYMBOL_ref = 142,                      /* ref  */
-  YYSYMBOL_ligature = 143,                 /* ligature  */
-  YYSYMBOL_144_6 = 144,                    /* $@6  */
-  YYSYMBOL_replace_count = 145,            /* replace_count  */
-  YYSYMBOL_disc = 146,                     /* disc  */
-  YYSYMBOL_disc_node = 147,                /* disc_node  */
-  YYSYMBOL_par_dimen = 148,                /* par_dimen  */
-  YYSYMBOL_par = 149,                      /* par  */
-  YYSYMBOL_150_7 = 150,                    /* $@7  */
-  YYSYMBOL_math = 151,                     /* math  */
-  YYSYMBOL_on_off = 152,                   /* on_off  */
-  YYSYMBOL_span_count = 153,               /* span_count  */
-  YYSYMBOL_table = 154,                    /* table  */
-  YYSYMBOL_image_aspect = 155,             /* image_aspect  */
-  YYSYMBOL_image_width = 156,              /* image_width  */
-  YYSYMBOL_image_height = 157,             /* image_height  */
-  YYSYMBOL_image_spec = 158,               /* image_spec  */
-  YYSYMBOL_image = 159,                    /* image  */
-  YYSYMBOL_max_value = 160,                /* max_value  */
-  YYSYMBOL_placement = 161,                /* placement  */
-  YYSYMBOL_def_node = 162,                 /* def_node  */
-  YYSYMBOL_unknown_bytes = 163,            /* unknown_bytes  */
-  YYSYMBOL_unknown_node = 164,             /* unknown_node  */
-  YYSYMBOL_unknown_nodes = 165,            /* unknown_nodes  */
-  YYSYMBOL_stream_link = 166,              /* stream_link  */
-  YYSYMBOL_stream_split = 167,             /* stream_split  */
-  YYSYMBOL_stream_info = 168,              /* stream_info  */
+  YYSYMBOL_COLOR = 73,                     /* "color"  */
+  YYSYMBOL_UNKNOWN = 74,                   /* "unknown"  */
+  YYSYMBOL_STREAM = 75,                    /* "stream"  */
+  YYSYMBOL_STREAMDEF = 76,                 /* "stream (definition)"  */
+  YYSYMBOL_FIRST = 77,                     /* "first"  */
+  YYSYMBOL_LAST = 78,                      /* "last"  */
+  YYSYMBOL_TOP = 79,                       /* "top"  */
+  YYSYMBOL_NOREFERENCE = 80,               /* "*"  */
+  YYSYMBOL_PAGE = 81,                      /* "page"  */
+  YYSYMBOL_RANGE = 82,                     /* "range"  */
+  YYSYMBOL_DIRECTORY = 83,                 /* "directory"  */
+  YYSYMBOL_SECTION = 84,                   /* "entry"  */
+  YYSYMBOL_DEFINITIONS = 85,               /* "definitions"  */
+  YYSYMBOL_MAX = 86,                       /* "max"  */
+  YYSYMBOL_PARAM = 87,                     /* "param"  */
+  YYSYMBOL_FONT = 88,                      /* "font"  */
+  YYSYMBOL_CONTENT = 89,                   /* "content"  */
+  YYSYMBOL_YYACCEPT = 90,                  /* $accept  */
+  YYSYMBOL_glyph = 91,                     /* glyph  */
+  YYSYMBOL_content_node = 92,              /* content_node  */
+  YYSYMBOL_start = 93,                     /* start  */
+  YYSYMBOL_integer = 94,                   /* integer  */
+  YYSYMBOL_string = 95,                    /* string  */
+  YYSYMBOL_number = 96,                    /* number  */
+  YYSYMBOL_dimension = 97,                 /* dimension  */
+  YYSYMBOL_xdimen = 98,                    /* xdimen  */
+  YYSYMBOL_xdimen_node = 99,               /* xdimen_node  */
+  YYSYMBOL_order = 100,                    /* order  */
+  YYSYMBOL_stretch = 101,                  /* stretch  */
+  YYSYMBOL_penalty = 102,                  /* penalty  */
+  YYSYMBOL_rule_dimension = 103,           /* rule_dimension  */
+  YYSYMBOL_rule = 104,                     /* rule  */
+  YYSYMBOL_rule_node = 105,                /* rule_node  */
+  YYSYMBOL_explicit = 106,                 /* explicit  */
+  YYSYMBOL_kern = 107,                     /* kern  */
+  YYSYMBOL_plus = 108,                     /* plus  */
+  YYSYMBOL_minus = 109,                    /* minus  */
+  YYSYMBOL_glue = 110,                     /* glue  */
+  YYSYMBOL_glue_node = 111,                /* glue_node  */
+  YYSYMBOL_position = 112,                 /* position  */
+  YYSYMBOL_content_list = 113,             /* content_list  */
+  YYSYMBOL_estimate = 114,                 /* estimate  */
+  YYSYMBOL_list = 115,                     /* list  */
+  YYSYMBOL_116_1 = 116,                    /* $@1  */
+  YYSYMBOL_text = 117,                     /* text  */
+  YYSYMBOL_txt = 118,                      /* txt  */
+  YYSYMBOL_119_2 = 119,                    /* $@2  */
+  YYSYMBOL_box_dimen = 120,                /* box_dimen  */
+  YYSYMBOL_box_shift = 121,                /* box_shift  */
+  YYSYMBOL_box_glue_set = 122,             /* box_glue_set  */
+  YYSYMBOL_box = 123,                      /* box  */
+  YYSYMBOL_hbox_node = 124,                /* hbox_node  */
+  YYSYMBOL_vbox_node = 125,                /* vbox_node  */
+  YYSYMBOL_box_flex = 126,                 /* box_flex  */
+  YYSYMBOL_box_options = 127,              /* box_options  */
+  YYSYMBOL_hxbox_node = 128,               /* hxbox_node  */
+  YYSYMBOL_vbox_dimen = 129,               /* vbox_dimen  */
+  YYSYMBOL_vxbox_node = 130,               /* vxbox_node  */
+  YYSYMBOL_box_goal = 131,                 /* box_goal  */
+  YYSYMBOL_hpack = 132,                    /* hpack  */
+  YYSYMBOL_max_depth = 133,                /* max_depth  */
+  YYSYMBOL_vpack = 134,                    /* vpack  */
+  YYSYMBOL_135_3 = 135,                    /* $@3  */
+  YYSYMBOL_136_4 = 136,                    /* $@4  */
+  YYSYMBOL_ltype = 137,                    /* ltype  */
+  YYSYMBOL_leaders = 138,                  /* leaders  */
+  YYSYMBOL_baseline = 139,                 /* baseline  */
+  YYSYMBOL_140_5 = 140,                    /* $@5  */
+  YYSYMBOL_cc_list = 141,                  /* cc_list  */
+  YYSYMBOL_lig_cc = 142,                   /* lig_cc  */
+  YYSYMBOL_ref = 143,                      /* ref  */
+  YYSYMBOL_ligature = 144,                 /* ligature  */
+  YYSYMBOL_145_6 = 145,                    /* $@6  */
+  YYSYMBOL_replace_count = 146,            /* replace_count  */
+  YYSYMBOL_disc = 147,                     /* disc  */
+  YYSYMBOL_disc_node = 148,                /* disc_node  */
+  YYSYMBOL_par_dimen = 149,                /* par_dimen  */
+  YYSYMBOL_par = 150,                      /* par  */
+  YYSYMBOL_151_7 = 151,                    /* $@7  */
+  YYSYMBOL_math = 152,                     /* math  */
+  YYSYMBOL_on_off = 153,                   /* on_off  */
+  YYSYMBOL_span_count = 154,               /* span_count  */
+  YYSYMBOL_table = 155,                    /* table  */
+  YYSYMBOL_image_aspect = 156,             /* image_aspect  */
+  YYSYMBOL_image_width = 157,              /* image_width  */
+  YYSYMBOL_image_height = 158,             /* image_height  */
+  YYSYMBOL_image_spec = 159,               /* image_spec  */
+  YYSYMBOL_image = 160,                    /* image  */
+  YYSYMBOL_max_value = 161,                /* max_value  */
+  YYSYMBOL_placement = 162,                /* placement  */
+  YYSYMBOL_def_node = 163,                 /* def_node  */
+  YYSYMBOL_color = 164,                    /* color  */
+  YYSYMBOL_color_pair = 165,               /* color_pair  */
+  YYSYMBOL_color_unset = 166,              /* color_unset  */
+  YYSYMBOL_color_tripple = 167,            /* color_tripple  */
+  YYSYMBOL_color_set = 168,                /* color_set  */
   YYSYMBOL_169_8 = 169,                    /* $@8  */
-  YYSYMBOL_stream_type = 170,              /* stream_type  */
-  YYSYMBOL_stream_def_node = 171,          /* stream_def_node  */
-  YYSYMBOL_stream_ins_node = 172,          /* stream_ins_node  */
-  YYSYMBOL_stream = 173,                   /* stream  */
-  YYSYMBOL_page_priority = 174,            /* page_priority  */
-  YYSYMBOL_stream_def_list = 175,          /* stream_def_list  */
-  YYSYMBOL_page = 176,                     /* page  */
-  YYSYMBOL_177_9 = 177,                    /* $@9  */
-  YYSYMBOL_178_10 = 178,                   /* $@10  */
-  YYSYMBOL_hint = 179,                     /* hint  */
-  YYSYMBOL_directory_section = 180,        /* directory_section  */
-  YYSYMBOL_181_11 = 181,                   /* $@11  */
-  YYSYMBOL_entry_list = 182,               /* entry_list  */
-  YYSYMBOL_entry = 183,                    /* entry  */
-  YYSYMBOL_definition_section = 184,       /* definition_section  */
-  YYSYMBOL_185_12 = 185,                   /* $@12  */
-  YYSYMBOL_definition_list = 186,          /* definition_list  */
-  YYSYMBOL_max_definitions = 187,          /* max_definitions  */
-  YYSYMBOL_max_list = 188,                 /* max_list  */
-  YYSYMBOL_def_list = 189,                 /* def_list  */
-  YYSYMBOL_parameters = 190,               /* parameters  */
-  YYSYMBOL_named_param_list = 191,         /* named_param_list  */
-  YYSYMBOL_param_list = 192,               /* param_list  */
-  YYSYMBOL_font = 193,                     /* font  */
-  YYSYMBOL_font_head = 194,                /* font_head  */
-  YYSYMBOL_font_param_list = 195,          /* font_param_list  */
-  YYSYMBOL_font_param = 196,               /* font_param  */
-  YYSYMBOL_fref = 197,                     /* fref  */
-  YYSYMBOL_xdimen_ref = 198,               /* xdimen_ref  */
-  YYSYMBOL_param_ref = 199,                /* param_ref  */
-  YYSYMBOL_stream_ref = 200,               /* stream_ref  */
-  YYSYMBOL_content_section = 201,          /* content_section  */
-  YYSYMBOL_202_13 = 202                    /* $@13  */
+  YYSYMBOL_unknown_bytes = 170,            /* unknown_bytes  */
+  YYSYMBOL_unknown_node = 171,             /* unknown_node  */
+  YYSYMBOL_unknown_nodes = 172,            /* unknown_nodes  */
+  YYSYMBOL_stream_link = 173,              /* stream_link  */
+  YYSYMBOL_stream_split = 174,             /* stream_split  */
+  YYSYMBOL_stream_info = 175,              /* stream_info  */
+  YYSYMBOL_176_9 = 176,                    /* $@9  */
+  YYSYMBOL_stream_type = 177,              /* stream_type  */
+  YYSYMBOL_stream_def_node = 178,          /* stream_def_node  */
+  YYSYMBOL_stream_ins_node = 179,          /* stream_ins_node  */
+  YYSYMBOL_stream = 180,                   /* stream  */
+  YYSYMBOL_page_priority = 181,            /* page_priority  */
+  YYSYMBOL_stream_def_list = 182,          /* stream_def_list  */
+  YYSYMBOL_page = 183,                     /* page  */
+  YYSYMBOL_184_10 = 184,                   /* $@10  */
+  YYSYMBOL_185_11 = 185,                   /* $@11  */
+  YYSYMBOL_hint = 186,                     /* hint  */
+  YYSYMBOL_directory_section = 187,        /* directory_section  */
+  YYSYMBOL_188_12 = 188,                   /* $@12  */
+  YYSYMBOL_entry_list = 189,               /* entry_list  */
+  YYSYMBOL_entry = 190,                    /* entry  */
+  YYSYMBOL_definition_section = 191,       /* definition_section  */
+  YYSYMBOL_192_13 = 192,                   /* $@13  */
+  YYSYMBOL_definition_list = 193,          /* definition_list  */
+  YYSYMBOL_max_definitions = 194,          /* max_definitions  */
+  YYSYMBOL_max_list = 195,                 /* max_list  */
+  YYSYMBOL_def_list = 196,                 /* def_list  */
+  YYSYMBOL_parameters = 197,               /* parameters  */
+  YYSYMBOL_named_param_list = 198,         /* named_param_list  */
+  YYSYMBOL_param_list = 199,               /* param_list  */
+  YYSYMBOL_font = 200,                     /* font  */
+  YYSYMBOL_font_head = 201,                /* font_head  */
+  YYSYMBOL_font_param_list = 202,          /* font_param_list  */
+  YYSYMBOL_font_param = 203,               /* font_param  */
+  YYSYMBOL_fref = 204,                     /* fref  */
+  YYSYMBOL_xdimen_ref = 205,               /* xdimen_ref  */
+  YYSYMBOL_param_ref = 206,                /* param_ref  */
+  YYSYMBOL_stream_ref = 207,               /* stream_ref  */
+  YYSYMBOL_content_section = 208,          /* content_section  */
+  YYSYMBOL_209_14 = 209                    /* $@14  */
 };
 typedef enum yysymbol_kind_t yysymbol_kind_t;
 
@@ -698,19 +705,19 @@
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  5
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   720
+#define YYLAST   761
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  89
+#define YYNTOKENS  90
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  114
+#define YYNNTS  120
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  285
+#define YYNRULES  302
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  596
+#define YYNSTATES  638
 
 /* YYMAXUTOK -- Last valid token kind.  */
-#define YYMAXUTOK   343
+#define YYMAXUTOK   344
 
 
 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
@@ -758,7 +765,7 @@
       55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
       65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
       75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,    86,    87,    88
+      85,    86,    87,    88,    89
 };
 
 #if YYDEBUG
@@ -765,35 +772,37 @@
 /* YYRLINE[YYN] -- Source line where rule number YYN was defined.  */
 static const yytype_int16 yyrline[] =
 {
-       0,   274,   274,   277,   280,   284,   284,   288,   292,   292,
-     298,   300,   302,   304,   307,   310,   314,   317,   320,   323,
-     327,   332,   334,   336,   338,   342,   346,   349,   353,   353,
-     356,   362,   365,   367,   369,   372,   375,   379,   381,   384,
-     386,   389,   392,   396,   402,   405,   406,   407,   410,   413,
-     420,   419,   428,   428,   430,   433,   436,   439,   442,   445,
-     448,   451,   451,   456,   460,   463,   467,   470,   473,   478,
-     482,   485,   488,   488,   490,   494,   497,   501,   505,   506,
-     511,   515,   518,   521,   524,   528,   532,   536,   538,   542,
-     542,   547,   547,   553,   557,   557,   559,   561,   563,   565,
-     568,   571,   574,   577,   581,   581,   590,   595,   595,   598,
-     601,   604,   607,   607,   614,   618,   621,   625,   629,   632,
-     637,   642,   644,   647,   650,   653,   653,   658,   662,   666,
-     669,   672,   675,   678,   681,   685,   689,   691,   694,   698,
-     702,   705,   708,   711,   715,   718,   722,   726,   728,   731,
-     734,   737,   740,   744,   748,   752,   756,   761,   765,   769,
-     776,   778,   780,   782,   785,   790,   795,   805,   808,   812,
-     815,   817,   820,   820,   820,   820,   821,   823,   827,   829,
-     832,   835,   835,   839,   841,   843,   845,   849,   855,   860,
-     860,   862,   865,   868,   873,   876,   880,   880,   882,   884,
-     882,   891,   894,   898,   900,   900,   903,   903,   904,   909,
-     909,   916,   916,   918,   945,   945,   947,   950,   953,   956,
-     959,   962,   965,   968,   971,   974,   977,   980,   983,   986,
-     989,   992,   995,  1001,  1004,  1007,  1010,  1013,  1016,  1019,
-    1022,  1025,  1028,  1031,  1034,  1037,  1040,  1045,  1048,  1051,
-    1055,  1056,  1059,  1063,  1067,  1067,  1073,  1075,  1080,  1080,
-    1083,  1086,  1089,  1092,  1095,  1098,  1101,  1104,  1108,  1112,
-    1115,  1118,  1124,  1127,  1131,  1135,  1138,  1141,  1144,  1147,
-    1150,  1153,  1156,  1160,  1167,  1167
+       0,   276,   276,   279,   282,   286,   286,   290,   294,   294,
+     300,   302,   304,   306,   309,   312,   316,   319,   322,   325,
+     329,   334,   336,   338,   340,   344,   348,   351,   355,   355,
+     358,   364,   367,   369,   371,   374,   377,   381,   383,   386,
+     388,   391,   394,   398,   404,   407,   408,   409,   412,   415,
+     422,   421,   430,   430,   432,   435,   438,   441,   444,   447,
+     450,   453,   453,   458,   462,   465,   469,   472,   475,   480,
+     484,   487,   490,   490,   492,   496,   499,   503,   507,   508,
+     513,   517,   520,   523,   526,   530,   534,   538,   540,   544,
+     544,   549,   549,   555,   559,   559,   561,   563,   565,   567,
+     570,   573,   576,   579,   583,   583,   592,   597,   597,   600,
+     603,   606,   609,   609,   616,   620,   623,   627,   631,   634,
+     639,   644,   646,   649,   652,   655,   655,   660,   664,   668,
+     671,   674,   677,   680,   683,   687,   691,   693,   696,   700,
+     704,   707,   710,   713,   717,   720,   724,   728,   730,   733,
+     736,   739,   742,   746,   750,   754,   758,   763,   767,   771,
+     778,   780,   782,   784,   787,   792,   796,   801,   811,   818,
+     825,   829,   830,   833,   837,   838,   839,   842,   843,   845,
+     845,   852,   856,   861,   864,   868,   871,   873,   876,   876,
+     876,   876,   877,   879,   883,   885,   888,   891,   891,   895,
+     897,   899,   901,   905,   911,   916,   916,   918,   921,   924,
+     929,   932,   936,   936,   938,   940,   938,   947,   950,   954,
+     956,   956,   959,   959,   960,   965,   965,   972,   972,   974,
+    1007,  1007,  1009,  1012,  1015,  1018,  1021,  1024,  1027,  1030,
+    1033,  1036,  1039,  1042,  1045,  1048,  1051,  1054,  1057,  1060,
+    1066,  1069,  1072,  1075,  1078,  1081,  1084,  1087,  1090,  1093,
+    1096,  1099,  1102,  1105,  1110,  1113,  1116,  1120,  1121,  1124,
+    1128,  1132,  1132,  1138,  1140,  1145,  1145,  1148,  1151,  1154,
+    1157,  1160,  1163,  1166,  1169,  1173,  1177,  1180,  1183,  1189,
+    1192,  1196,  1200,  1203,  1206,  1209,  1212,  1215,  1218,  1221,
+    1225,  1232,  1232
 };
 #endif
 
@@ -822,9 +831,9 @@
   "\"center\"", "\"expand\"", "\"baseline\"", "\"ligature\"", "\"disc\"",
   "\"par\"", "\"math\"", "\"on\"", "\"off\"", "\"adjust\"", "\"table\"",
   "\"item\"", "\"image\"", "\"width\"", "\"height\"", "\"label\"",
-  "\"bot\"", "\"mid\"", "\"link\"", "\"outline\"", "\"unknown\"",
-  "\"stream\"", "\"stream (definition)\"", "\"first\"", "\"last\"",
-  "\"top\"", "\"*\"", "\"page\"", "\"range\"", "\"directory\"",
+  "\"bot\"", "\"mid\"", "\"link\"", "\"outline\"", "\"color\"",
+  "\"unknown\"", "\"stream\"", "\"stream (definition)\"", "\"first\"",
+  "\"last\"", "\"top\"", "\"*\"", "\"page\"", "\"range\"", "\"directory\"",
   "\"entry\"", "\"definitions\"", "\"max\"", "\"param\"", "\"font\"",
   "\"content\"", "$accept", "glyph", "content_node", "start", "integer",
   "string", "number", "dimension", "xdimen", "xdimen_node", "order",
@@ -838,15 +847,16 @@
   "replace_count", "disc", "disc_node", "par_dimen", "par", "$@7", "math",
   "on_off", "span_count", "table", "image_aspect", "image_width",
   "image_height", "image_spec", "image", "max_value", "placement",
-  "def_node", "unknown_bytes", "unknown_node", "unknown_nodes",
-  "stream_link", "stream_split", "stream_info", "$@8", "stream_type",
+  "def_node", "color", "color_pair", "color_unset", "color_tripple",
+  "color_set", "$@8", "unknown_bytes", "unknown_node", "unknown_nodes",
+  "stream_link", "stream_split", "stream_info", "$@9", "stream_type",
   "stream_def_node", "stream_ins_node", "stream", "page_priority",
-  "stream_def_list", "page", "$@9", "$@10", "hint", "directory_section",
-  "$@11", "entry_list", "entry", "definition_section", "$@12",
+  "stream_def_list", "page", "$@10", "$@11", "hint", "directory_section",
+  "$@12", "entry_list", "entry", "definition_section", "$@13",
   "definition_list", "max_definitions", "max_list", "def_list",
   "parameters", "named_param_list", "param_list", "font", "font_head",
   "font_param_list", "font_param", "fref", "xdimen_ref", "param_ref",
-  "stream_ref", "content_section", "$@13", YY_NULLPTR
+  "stream_ref", "content_section", "$@14", YY_NULLPTR
 };
 
 static const char *
@@ -856,7 +866,7 @@
 }
 #endif
 
-#define YYPACT_NINF (-275)
+#define YYPACT_NINF (-408)
 
 #define yypact_value_is_default(Yyn) \
   ((Yyn) == YYPACT_NINF)
@@ -870,66 +880,70 @@
    STATE-NUM.  */
 static const yytype_int16 yypact[] =
 {
-     101,    25,   127,   133,   163,  -275,    94,   139,  -275,  -275,
-      93,  -275,  -275,   214,  -275,    47,   151,  -275,  -275,   165,
-    -275,  -275,  -275,   114,  -275,   159,   249,   259,   178,  -275,
-     174,  -275,     9,  -275,  -275,   645,  -275,  -275,  -275,  -275,
-    -275,  -275,  -275,  -275,   271,   320,  -275,   252,   269,   269,
-     269,   269,   269,   269,   269,   269,   269,   269,   269,   260,
-     269,   269,   269,   275,   282,   103,   198,   287,   108,   250,
-     213,   261,   261,   268,   261,    59,    57,   219,   213,   269,
-      60,   213,    90,    78,   270,    63,   295,   316,   325,   269,
-     269,  -275,  -275,   336,   352,   353,   354,   355,   356,   358,
-     359,   360,   364,   366,   368,   372,   373,   374,   376,   377,
-     378,   384,   338,   183,  -275,   213,   261,   198,   271,   153,
-     213,   394,   261,   269,   250,   392,   393,   271,   396,   271,
-     131,   244,   398,   401,   399,  -275,  -275,  -275,   412,   413,
-     414,  -275,  -275,  -275,  -275,   220,  -275,   153,   415,   416,
-    -275,   177,   420,   261,   397,   422,   424,   261,   268,   427,
-     428,   261,   267,   430,   268,   351,   389,  -275,   434,   261,
-    -275,   268,  -275,   411,   192,   437,   438,  -275,   439,   440,
-     441,   442,   443,   444,    78,   446,   269,  -275,   394,   447,
-     219,  -275,  -275,    34,  -275,   448,  -275,  -275,    78,    78,
-    -275,   396,   452,   267,   267,   455,  -275,   456,   590,   457,
-     459,   261,   462,    78,   463,   265,  -275,  -275,   219,    70,
-    -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-    -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-    -275,   465,   466,   467,   468,   470,   471,   472,   473,   474,
-     475,   476,  -275,   478,   479,   480,   210,  -275,   481,  -275,
-    -275,   482,   261,   485,   394,  -275,  -275,  -275,   487,   488,
-     489,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-     153,  -275,  -275,   269,  -275,   490,  -275,   329,   261,   432,
-    -275,  -275,   261,   304,  -275,  -275,  -275,   219,   219,    78,
-    -275,   397,   491,  -275,   261,   268,  -275,   261,   492,   213,
-    -275,  -275,  -275,   394,  -275,  -275,   394,  -275,  -275,  -275,
-     217,  -275,  -275,  -275,    78,  -275,  -275,    78,  -275,    78,
-      78,   396,   493,  -275,    58,   394,    78,   394,    78,  -275,
-    -275,  -275,    78,    78,  -275,  -275,  -275,   494,  -275,   381,
-    -275,  -275,  -275,   496,   495,   499,    78,    78,  -275,  -275,
-    -275,  -275,   497,   500,  -275,    78,    78,  -275,  -275,  -275,
-    -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-    -275,  -275,   501,   502,  -275,  -275,   504,  -275,   503,  -275,
-     394,   394,  -275,  -275,  -275,  -275,   506,  -275,   261,  -275,
-     136,  -275,   261,  -275,  -275,   261,   261,    78,  -275,  -275,
-    -275,  -275,  -275,   432,   219,  -275,   268,  -275,   267,   261,
-    -275,   507,   510,    61,  -275,  -275,  -275,   394,  -275,  -275,
-     483,  -275,    78,  -275,  -275,  -275,   513,  -275,   477,  -275,
-    -275,  -275,  -275,  -275,   334,    78,    78,  -275,   302,   453,
-    -275,  -275,    97,  -275,  -275,  -275,   261,  -275,   394,   515,
-    -275,  -275,   394,  -275,   516,   464,  -275,   186,  -275,  -275,
-     505,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-    -275,    78,    78,   267,    78,  -275,  -275,  -275,   153,  -275,
-    -275,  -275,  -275,  -275,   317,  -275,  -275,  -275,   458,  -275,
-     313,  -275,  -275,  -275,   535,  -275,  -275,  -275,  -275,   522,
-      64,   394,  -275,   261,  -275,   250,   269,   269,   269,   269,
-     269,   269,   269,   269,  -275,  -275,  -275,    78,  -275,   120,
-    -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,   459,
-     322,  -275,  -275,  -275,  -275,  -275,  -275,    64,  -275,    78,
-    -275,  -275,   183,   271,   153,   250,   261,   269,   250,   392,
-    -275,  -275,  -275,  -275,  -275,   521,   394,   394,   524,   525,
-     527,   261,   528,   529,   530,   531,   532,  -275,   533,   394,
-    -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,    78,
-    -275,   394,   486,  -275,   269,    45
+      86,    -5,   111,   141,   144,  -408,    72,   196,  -408,  -408,
+     117,  -408,  -408,   207,  -408,   121,   132,  -408,  -408,   145,
+    -408,  -408,  -408,   185,  -408,   220,   241,   253,   181,  -408,
+     203,  -408,    50,  -408,  -408,   685,  -408,  -408,  -408,  -408,
+    -408,  -408,  -408,  -408,   261,   396,  -408,   287,   299,   299,
+     299,   299,   299,   299,   299,   299,   299,   299,   299,   299,
+     310,   299,   299,   299,   314,   331,   103,   227,   334,   186,
+     319,   244,   166,   166,   324,   166,    54,    80,   146,   244,
+     299,    75,   244,    78,    55,   282,    96,   272,   346,    66,
+     372,   299,   299,  -408,  -408,   375,   376,   379,   380,   381,
+     382,   383,   384,   385,   386,   388,   389,   391,   392,   393,
+     394,   395,   397,   400,   401,   398,   157,  -408,   244,   166,
+     227,   261,   205,   244,   406,   166,   299,   319,   404,  -408,
+     405,   261,   407,   261,    38,   303,   408,   409,   410,  -408,
+    -408,  -408,   418,   419,   420,  -408,  -408,  -408,  -408,   337,
+    -408,   205,   422,   423,  -408,   214,   424,   166,   403,   426,
+     431,   166,   324,   432,   433,   166,   316,   434,   324,   354,
+     402,  -408,   437,   166,  -408,   324,  -408,   413,   291,   440,
+     441,  -408,   442,   444,   451,   452,   453,   456,    55,   458,
+     299,  -408,   406,   459,   146,  -408,  -408,    47,  -408,   461,
+    -408,  -408,    55,    55,  -408,   407,   462,   316,   316,   463,
+    -408,   467,   630,   471,   454,   166,   475,    55,   476,   308,
+     477,   481,  -408,  -408,   146,    58,  -408,  -408,  -408,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,   486,   487,
+     488,   490,   491,   493,   494,   495,   496,   498,   499,  -408,
+     501,   502,   503,   506,   240,  -408,   507,  -408,  -408,   508,
+     166,   509,   406,  -408,  -408,  -408,   510,   511,   512,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,   205,  -408,
+    -408,   299,  -408,   513,  -408,   353,   166,   479,  -408,  -408,
+     166,   342,  -408,  -408,  -408,   146,   146,    55,  -408,   403,
+     514,  -408,   166,   324,  -408,   166,   516,   244,  -408,  -408,
+    -408,   406,  -408,  -408,   406,  -408,  -408,  -408,   190,  -408,
+    -408,  -408,    55,  -408,  -408,    55,  -408,    55,    55,   407,
+     517,  -408,    65,   406,    55,   406,    55,  -408,  -408,  -408,
+      55,    55,  -408,  -408,  -408,   518,  -408,   457,  -408,  -408,
+    -408,   210,  -408,  -408,   519,   520,    55,    55,  -408,  -408,
+    -408,  -408,   515,   521,  -408,    55,    55,  -408,  -408,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,
+    -408,   525,   506,   528,  -408,   529,   523,  -408,  -408,   531,
+    -408,   532,  -408,   406,   406,  -408,  -408,  -408,  -408,   533,
+    -408,   166,  -408,   147,  -408,   166,  -408,  -408,   166,   166,
+      55,  -408,  -408,  -408,  -408,  -408,   479,   146,  -408,   324,
+    -408,   316,   166,  -408,   535,   536,    79,  -408,  -408,  -408,
+     406,  -408,  -408,   522,  -408,    55,  -408,  -408,  -408,   537,
+    -408,   504,  -408,  -408,  -408,  -408,  -408,   371,    55,    55,
+    -408,   258,   468,  -408,   539,  -408,    94,  -408,  -408,  -408,
+     166,  -408,   406,   542,   236,   525,  -408,  -408,  -408,  -408,
+    -408,   406,  -408,   543,   500,  -408,   216,  -408,  -408,   534,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,
+      55,    55,   316,    55,  -408,  -408,  -408,   205,  -408,  -408,
+    -408,  -408,  -408,   292,  -408,  -408,  -408,   483,  -408,   296,
+    -408,  -408,  -408,  -408,   575,  -408,  -408,  -408,  -408,   547,
+      43,   406,  -408,   549,  -408,   330,   525,  -408,  -408,   166,
+    -408,   319,   299,   299,   299,   299,   299,   299,   299,   299,
+    -408,  -408,  -408,    55,  -408,   112,  -408,  -408,  -408,  -408,
+    -408,  -408,  -408,  -408,  -408,   454,   307,  -408,  -408,  -408,
+    -408,  -408,  -408,    43,  -408,    55,   550,  -408,   554,   555,
+     556,   557,  -408,  -408,  -408,   157,   261,   205,   319,   166,
+     299,   319,   404,  -408,  -408,  -408,  -408,  -408,   558,   406,
+     559,  -408,  -408,  -408,  -408,   406,   562,   563,   564,   166,
+     565,   566,   567,   568,   569,  -408,   570,   283,   406,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,   571,
+      55,  -408,  -408,   406,   530,  -408,   299,    64
 };
 
 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -937,100 +951,104 @@
    means the default is an error.  */
 static const yytype_int16 yydefact[] =
 {
-       0,     0,     0,     0,     0,     1,     0,     0,   204,   209,
-       0,   203,   206,     0,   284,     0,     0,   211,    44,     0,
-     205,   207,   214,     0,    45,     0,     0,     0,     4,   210,
-       0,   212,     4,   285,    46,     0,    32,    72,    73,    95,
-      94,   121,   189,   190,     0,     0,   213,     0,     0,     0,
+       0,     0,     0,     0,     0,     1,     0,     0,   220,   225,
+       0,   219,   222,     0,   301,     0,     0,   227,    44,     0,
+     221,   223,   230,     0,    45,     0,     0,     0,     4,   226,
+       0,   228,     4,   302,    46,     0,    32,    72,    73,    95,
+      94,   121,   205,   206,     0,     0,   229,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    33,
-       0,     0,     0,    64,     0,    87,     0,     0,     0,     0,
-      33,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     8,     9,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   111,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    33,     0,     0,     0,    47,     0,
-     163,     0,     0,     0,     0,     6,     5,    26,     0,     0,
-       0,    10,    11,    12,    29,     0,    28,     0,     0,     0,
-      34,     0,     0,    19,    37,     0,     0,     0,    64,     0,
-       0,     0,     0,     0,    64,    87,     0,    89,     0,     0,
-      78,    64,     4,     0,    96,     0,     0,   104,     0,     0,
-     112,     0,   115,     0,   119,     0,   122,   269,     0,     0,
-       0,   136,   137,    47,   270,     0,   138,   254,     0,     0,
-      44,    47,     0,     0,     0,     0,   140,     0,    47,     0,
-       0,   148,     0,     0,     0,     0,   170,   271,     0,     0,
-     208,   218,   227,   217,   222,   223,   221,   225,   226,   219,
-     220,   224,   232,   159,   229,   230,   231,   228,   216,   215,
-      44,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   112,     0,     0,     0,     0,   198,     0,    48,
-      44,     0,     0,     0,     0,   161,   162,   160,     0,     0,
-       0,     2,     7,     3,    27,   272,   282,    13,    15,    14,
-       0,    31,   278,     0,    35,     0,    36,     0,     0,    39,
-      42,   275,     0,    66,    70,    71,    65,     0,     0,     0,
-      86,    37,     0,    91,     0,    64,    93,     0,     0,     0,
-      97,    98,    99,     0,   103,   280,     0,   106,   281,   276,
-       0,   114,   116,   277,   118,   120,   125,     0,   128,     0,
-       0,    47,     0,   135,    47,   132,     0,   129,     0,    50,
-      44,   139,     0,     0,   146,   141,   143,     0,   147,   150,
-     279,   157,   158,     0,   176,     0,     0,     0,   188,   184,
-     185,   186,     0,     0,   183,     0,     0,   235,   248,   238,
-     234,   247,   236,   239,   237,   249,   240,   241,   242,   243,
-     244,   167,     0,   194,   246,   250,   252,   245,     0,   233,
-       0,   256,   164,   201,   202,    30,     0,   273,    17,    18,
-       0,    38,     0,    41,    63,     0,     0,     0,    84,    82,
-      83,    81,    85,    39,     0,    77,    64,    88,     0,     0,
-      80,     0,     0,     0,   100,   101,   102,     0,   109,   110,
-       0,   117,     0,   127,   124,   123,     0,   255,     0,   133,
-     134,   130,   131,    44,     0,     0,     0,   142,     0,   152,
-     165,   171,     0,   193,   191,   192,     0,   181,     0,     0,
-     168,   195,     0,   251,     0,     0,   258,     0,   259,   274,
-       0,    21,    22,    23,    24,    25,    40,    67,    68,    69,
-      74,     0,     0,     0,     0,    79,    43,   283,     0,   105,
-     107,   126,   253,    52,    61,    49,   144,   145,   152,   149,
-       0,   153,   169,   172,    47,   173,   174,   177,   175,     0,
-       0,     0,   166,     0,   257,    33,     0,     0,     0,     0,
-       0,     0,     0,     0,    16,    76,    75,     0,    90,     0,
-      51,    60,    58,    59,    55,    57,    56,    54,    53,     0,
-       0,   154,   155,   151,    20,   179,   178,     0,   182,     0,
-     199,   268,     0,     0,     0,    33,     0,     0,    33,     0,
-      92,   113,   108,    62,   156,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   180,     0,     0,
-     260,   265,   266,   261,   264,   262,   263,   267,   187,     0,
-     196,   200,     0,   197,     0,     0
+      33,     0,     0,     0,    64,     0,    87,     0,     0,     0,
+       0,    33,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     8,     9,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   111,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    33,     0,   179,
+       0,     0,    47,     0,   163,     0,     0,     0,     0,     6,
+       5,    26,     0,     0,     0,    10,    11,    12,    29,     0,
+      28,     0,     0,     0,    34,     0,     0,    19,    37,     0,
+       0,     0,    64,     0,     0,     0,     0,     0,    64,    87,
+       0,    89,     0,     0,    78,    64,     4,     0,    96,     0,
+       0,   104,     0,     0,   112,     0,   115,     0,   119,     0,
+     122,   286,     0,     0,     0,   136,   137,    47,   287,     0,
+     138,   271,     0,     0,    44,    47,     0,     0,     0,     0,
+     140,     0,    47,     0,     0,   148,     0,     0,     0,     0,
+       0,     0,   186,   288,     0,     0,   224,   234,   243,   233,
+     238,   239,   237,   241,   242,   235,   236,   240,   248,   159,
+     249,   245,   246,   247,   244,   232,   231,    44,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   112,
+       0,     0,     0,     0,     0,   214,     0,    48,    44,     0,
+       0,     0,     0,   161,   162,   160,     0,     0,     0,     2,
+       7,     3,    27,   289,   299,    13,    15,    14,     0,    31,
+     295,     0,    35,     0,    36,     0,     0,    39,    42,   292,
+       0,    66,    70,    71,    65,     0,     0,     0,    86,    37,
+       0,    91,     0,    64,    93,     0,     0,     0,    97,    98,
+      99,     0,   103,   297,     0,   106,   298,   293,     0,   114,
+     116,   294,   118,   120,   125,     0,   128,     0,     0,    47,
+       0,   135,    47,   132,     0,   129,     0,    50,    44,   139,
+       0,     0,   146,   141,   143,     0,   147,   150,   296,   157,
+     158,     0,   182,   181,   192,     0,     0,     0,   204,   200,
+     201,   202,     0,     0,   199,     0,     0,   252,   265,   255,
+     251,   264,   253,   256,   254,   266,   257,   258,   259,   260,
+     261,     0,   173,     0,   183,     0,   210,   263,   267,   269,
+     262,     0,   250,     0,   273,   164,   217,   218,    30,     0,
+     290,    17,    18,     0,    38,     0,    41,    63,     0,     0,
+       0,    84,    82,    83,    81,    85,    39,     0,    77,    64,
+      88,     0,     0,    80,     0,     0,     0,   100,   101,   102,
+       0,   109,   110,     0,   117,     0,   127,   124,   123,     0,
+     272,     0,   133,   134,   130,   131,    44,     0,     0,     0,
+     142,     0,   152,   165,     0,   187,     0,   209,   207,   208,
+       0,   197,     0,     0,     0,   173,   173,   177,   180,   184,
+     211,     0,   268,     0,     0,   275,     0,   276,   291,     0,
+      21,    22,    23,    24,    25,    40,    67,    68,    69,    74,
+       0,     0,     0,     0,    79,    43,   300,     0,   105,   107,
+     126,   270,    52,    61,    49,   144,   145,   152,   149,     0,
+     153,   166,   185,   188,    47,   189,   190,   193,   191,     0,
+       0,     0,   167,     0,   170,     0,   173,   173,   173,     0,
+     274,    33,     0,     0,     0,     0,     0,     0,     0,     0,
+      16,    76,    75,     0,    90,     0,    51,    60,    58,    59,
+      55,    57,    56,    54,    53,     0,     0,   154,   155,   151,
+      20,   195,   194,     0,   198,     0,     0,   172,     0,     0,
+       0,     0,   178,   215,   285,     0,     0,     0,    33,     0,
+       0,    33,     0,    92,   113,   108,    62,   156,     0,     0,
+       0,   171,   176,   175,   174,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   196,     0,     0,     0,   277,
+     282,   283,   278,   281,   279,   280,   284,   203,   169,     0,
+       0,   168,   212,   216,     0,   213,     0,     0
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -275,  -275,   -58,   -23,   115,   -98,  -106,    11,   -67,  -240,
-    -275,  -274,   -14,  -109,   -97,   226,   -68,   -13,   245,   132,
-    -102,  -225,  -148,   207,   -82,   -59,  -275,  -275,  -275,  -275,
-     182,   -20,  -275,   498,  -143,   235,  -275,   379,  -275,  -275,
-    -275,  -161,  -275,   387,  -275,  -275,  -275,  -275,   433,   431,
-    -275,  -275,  -275,   -45,  -104,  -275,  -275,  -100,   168,  -275,
-    -275,  -275,  -275,   340,  -275,  -275,  -275,  -275,    65,  -275,
-     -95,  -275,  -275,   180,  -275,  -275,  -275,    20,  -275,  -275,
-    -275,  -275,   -22,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-    -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,  -275,
-    -275,  -165,   119,   -94,  -275,  -275,  -275,  -275,  -108,  -237,
-    -110,  -275,  -275,  -275
+    -408,  -408,   -83,   -23,    88,  -100,  -123,    -3,   -65,  -263,
+    -408,  -233,   -32,  -104,   -99,   242,   -69,   -26,   268,   152,
+    -119,  -245,  -163,   231,  -102,   -27,  -408,  -408,  -408,  -408,
+     260,   -52,  -408,   538,  -138,   262,  -408,   411,  -408,  -408,
+    -408,  -156,  -408,   416,  -408,  -408,  -408,  -408,   464,   465,
+    -408,  -408,  -408,   -43,  -101,  -408,  -408,   -98,   184,  -408,
+    -408,  -408,  -408,   370,  -408,  -408,  -408,  -408,    77,  -408,
+     -96,  -408,  -408,   193,    61,  -407,  -382,   206,  -408,  -408,
+    -408,  -408,  -408,    28,  -408,  -408,  -408,  -408,   -28,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,  -408,
+    -408,  -408,  -408,  -408,  -408,  -408,  -408,  -152,   142,   -78,
+    -408,  -408,  -408,  -408,  -187,  -249,   -94,  -408,  -408,  -408
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-       0,   134,    34,   201,   137,    93,   145,   153,   154,   363,
-     475,   401,   138,   147,   148,    36,   182,   152,   289,   403,
-     155,   174,    24,    25,   340,   202,   443,   494,   538,   539,
-     158,   301,   407,   159,    37,    38,   414,   302,    39,   171,
-      40,   299,   163,   167,   168,   305,   416,   313,   175,   178,
-     316,   529,   430,   551,   181,   320,   184,   185,    41,   188,
-     189,   432,   195,   196,   210,   205,   349,   449,   501,   213,
-     214,   112,   268,    31,   354,   507,   452,   547,   548,   364,
-     510,   365,    42,    43,   355,   462,   591,   258,   383,   567,
-       2,     3,    12,    15,    21,     7,    13,    23,    17,    27,
-     386,   261,   197,   198,   263,   264,   391,   468,   552,   190,
-     199,   218,    11,    18
+       0,   138,    34,   205,   141,    95,   149,   157,   158,   373,
+     494,   414,   142,   151,   152,    36,   186,   156,   297,   416,
+     159,   178,    24,    25,   348,   206,   456,   513,   564,   565,
+     162,   309,   420,   163,    37,    38,   427,   310,    39,   175,
+      40,   307,   167,   171,   172,   313,   429,   321,   179,   182,
+     324,   555,   443,   584,   185,   328,   188,   189,    41,   192,
+     193,   445,   199,   200,   214,   209,   357,   462,   520,   217,
+     218,   115,   276,    31,   535,   475,   476,   392,   393,   263,
+     364,   527,   466,   573,   574,   374,   530,   375,    42,    43,
+     365,   481,   633,   266,   396,   605,     2,     3,    12,    15,
+      21,     7,    13,    23,    17,    27,   399,   269,   201,   202,
+     271,   272,   404,   487,   585,   194,   203,   224,    11,    18
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -1038,156 +1056,164 @@
    number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_int16 yytable[] =
 {
-      30,   151,    35,   115,   116,   117,   118,   119,   120,   121,
-     122,   123,   124,   125,   186,   127,   128,   129,   248,   253,
-     246,   139,   247,   149,   254,   156,   209,   207,   332,   257,
-     255,   262,   176,   179,   180,   183,   187,   194,   280,   390,
-     259,   212,   342,   343,   217,   219,   260,   287,   172,   243,
-      19,    20,   339,   162,   173,   336,   338,   408,   410,   193,
-     409,   411,   208,   141,   259,   142,    32,   114,   143,   206,
-     242,   114,   245,   172,   358,   249,   326,    63,   252,   146,
-     330,   172,   157,   157,   284,   157,   488,   157,   150,   177,
-      64,   427,   366,   172,   327,   200,   329,   114,   173,    71,
-      32,   502,    71,    72,     1,   348,   285,     4,   357,   132,
-     200,   260,   385,   133,   141,   114,   142,    28,    29,   143,
-     331,   359,   360,   361,   356,   324,   241,     5,   476,   200,
-     146,   477,   478,   177,   144,   169,     6,   165,   293,   335,
-     337,   194,    10,   545,   166,   194,   359,   360,   361,   471,
-     191,   192,   347,   561,   351,   472,   473,   474,   146,   141,
-     562,   142,    32,    33,   143,   193,   436,   193,   292,     8,
-     425,   395,   296,   194,   481,   334,   334,   482,     9,   144,
-     307,    14,   400,   141,   114,   142,    48,    35,   143,   135,
-      49,   136,   439,   283,   441,   193,   362,    50,    51,    52,
-     265,   266,   489,    53,   135,   114,   136,   421,   516,   267,
-     517,   518,   505,   519,   381,   520,   382,    16,   511,   141,
-     114,   142,   172,   428,   143,    54,   114,   429,   240,    55,
-      56,    57,   244,   277,   278,   279,    22,   513,   396,    58,
-     412,   173,   521,   522,   310,   311,   312,    59,    26,   260,
-      47,   523,   187,   187,    60,    44,   164,   484,   170,   113,
-      61,    62,    45,    46,   422,   431,   126,   141,   433,   142,
-     434,   435,   143,   388,   362,   362,   114,   440,   150,   442,
-      91,    92,   130,   445,   446,   418,   549,   203,   204,   131,
-     423,   146,   470,   173,   140,   493,   400,   454,   455,   400,
-     400,   211,   114,   404,   269,   270,   458,   459,   141,   498,
-     142,   161,   438,   143,   438,   417,   297,   298,   419,   141,
-     542,   142,   527,   215,   143,   191,   192,   579,   141,   564,
-     142,   216,    94,   143,   405,   406,    95,    32,   495,   589,
-     220,   578,   239,    96,    97,    98,   398,   399,   479,    99,
-     530,   531,   532,   533,   534,   535,   536,   537,   221,   222,
-     223,   224,   225,    30,   226,   227,   228,   465,   467,   187,
-     229,   100,   230,   491,   231,   101,   102,   103,   232,   233,
-     234,   499,   235,   236,   237,   104,   496,   497,   105,   509,
-     238,   362,   106,   506,   503,   107,   483,   172,   211,   256,
-     108,   109,   259,   273,   173,   271,   110,   111,   272,   553,
-     554,   555,   556,   557,   558,   559,   274,   275,   276,   281,
-     282,    35,   525,   526,   286,   528,   290,   288,   291,   504,
-     485,   294,   295,   543,   300,   362,   166,   304,   306,   173,
-     309,   314,   315,   317,   318,   319,   321,   448,   323,   322,
-     325,   328,   333,   574,   573,   569,   341,   570,   575,   344,
-     345,   346,    32,   402,   576,   546,   350,   352,   560,   367,
-     368,   369,   370,   543,   371,   372,   373,   374,   375,   376,
-     377,   563,   378,   379,   380,   384,   387,   571,   173,   389,
-     566,   392,   393,   394,   397,   415,   420,   437,   447,   146,
-     450,   451,   546,   453,   284,   460,   457,    28,   461,   464,
-     469,   486,   252,   456,   487,   490,    35,   492,    71,   512,
-     500,   515,   514,   524,   550,   540,   544,   577,   580,   581,
-     590,   582,   583,   584,   585,   586,   587,   588,   568,   424,
-      65,   259,   572,   173,   362,   480,   413,   444,   426,   595,
-     308,   456,   303,   251,   250,   353,   362,    66,   466,    67,
-      68,   594,    69,   541,    70,   146,   463,   565,   592,   593,
-     160,   508,   362,     0,     0,     0,    71,    72,     0,    73,
-      74,    75,    76,     0,     0,     0,    77,     0,     0,     0,
-      78,    79,    80,    81,    82,    65,   259,    83,    84,    85,
-      86,     0,     0,     0,     0,     0,    87,     0,    88,    89,
-      90,     0,    66,     0,    67,    68,     0,    69,     0,    70,
-       0,   331,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    71,    72,     0,    73,    74,    75,    76,     0,     0,
-       0,    77,     0,     0,     0,    78,    79,    80,    81,    82,
-      65,     0,    83,    84,    85,    86,     0,     0,     0,     0,
-       0,    87,     0,    88,    89,    90,     0,    66,     0,    67,
-      68,     0,    69,     0,    70,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    71,    72,     0,    73,
-      74,    75,    76,     0,     0,     0,    77,     0,     0,     0,
-      78,    79,    80,    81,    82,     0,     0,    83,    84,    85,
-      86,     0,     0,     0,     0,     0,    87,     0,    88,    89,
-      90
+      30,   155,    35,   211,   255,   118,   119,   120,   121,   122,
+     123,   124,   125,   126,   127,   128,   129,   190,   131,   132,
+     133,   253,   166,   254,   143,   260,   153,   403,   160,   261,
+     268,   265,   262,   270,   295,   180,   183,   184,   187,   191,
+     198,   347,   421,   423,   216,   340,   221,   288,   223,   225,
+     117,   350,   351,   267,   250,   177,   422,   424,   176,   213,
+     197,   176,   368,   212,   344,   346,   150,   176,   536,   161,
+     161,   267,   161,   117,   161,   249,   181,   252,     4,   440,
+     256,   176,   117,   259,   376,   117,   145,   204,   146,     1,
+     292,   147,   356,   537,   538,   268,   334,    32,   522,    32,
+     338,   177,   210,   154,   507,   398,    72,   273,   274,   136,
+     301,     5,   293,   137,   335,   248,   337,   275,    64,   150,
+      72,    73,   181,   571,    19,    20,   204,   220,   204,   579,
+     367,   355,    65,   169,   339,   369,   370,   371,   195,   196,
+     170,   369,   370,   371,     6,   594,   366,   198,   150,   176,
+       8,   198,   595,   117,   580,   581,   582,     9,   300,   173,
+     490,   332,   304,   139,   500,   140,   491,   492,   493,   197,
+     315,   197,   145,   413,   146,   343,   345,   147,   501,   342,
+     342,   198,   495,   438,   408,   496,   497,   449,    28,    29,
+     359,    35,   145,   117,   146,   508,   441,   147,   434,    10,
+     442,   197,   372,   525,   247,   452,    14,   454,   251,   531,
+      16,   145,   148,   146,   463,    48,   147,   464,    22,    49,
+     145,   117,   146,    32,    33,   147,    50,    51,    52,    26,
+     291,   148,    53,   139,   117,   140,   539,   268,   542,   533,
+     543,   544,   534,   545,   394,   546,   395,    44,   409,   177,
+     145,   117,   146,    47,    54,   147,    45,    46,    55,    56,
+      57,   431,   191,   191,   145,   517,   146,   401,    58,   147,
+      93,    94,   547,   548,   435,   503,    59,    60,   215,   117,
+     425,   549,   372,   372,    61,   150,   575,   628,   489,   629,
+      62,    63,   413,   512,   116,   413,   413,   417,   436,   207,
+     208,   177,   145,   568,   146,   444,   117,   147,   446,   430,
+     447,   448,   432,   145,   597,   146,   130,   453,   147,   455,
+     451,   134,   451,   458,   459,   556,   557,   558,   559,   560,
+     561,   562,   563,   533,   577,   168,   534,   174,   135,   468,
+     469,   144,   618,   318,   319,   320,   553,   154,   472,   473,
+     285,   286,   287,   219,   616,   630,   586,   587,   588,   589,
+     590,   591,   592,   277,   278,   305,   306,   165,   195,   196,
+     411,   412,   418,   419,    32,   514,    30,   502,   222,   226,
+     484,   486,   227,   523,   191,   228,   229,   230,   231,   232,
+     233,   234,   235,   498,   236,   237,   518,   238,   239,   240,
+     241,   242,   246,   243,   372,   529,   244,   245,    96,   176,
+     215,   264,    97,   267,   281,   279,   280,   177,   510,    98,
+      99,   100,   282,   283,   284,   101,   289,   290,   294,   504,
+     298,   515,   516,   296,    35,   299,   302,   303,   308,   526,
+     170,   314,   317,   524,   322,   323,   325,   102,   326,   372,
+     312,   103,   104,   105,   569,   327,   329,    32,   177,   330,
+     331,   106,   333,   336,   107,   341,   349,   352,   108,   109,
+     611,   353,   110,   551,   552,   354,   554,   111,   112,   358,
+     360,   362,   596,   113,   114,   363,   607,   572,   608,   612,
+     377,   378,   379,   613,   380,   381,   614,   382,   383,   384,
+     385,   569,   386,   387,   150,   388,   389,   390,   177,   391,
+     415,   397,   400,   402,   405,   406,   407,   410,   428,   609,
+     433,   450,   460,   461,   467,   465,   593,   471,   474,   480,
+     572,   470,   478,   479,    28,   519,   583,   488,   483,   505,
+     506,   511,    35,   521,   292,    72,   532,   259,   599,   540,
+     566,   570,   550,   606,   509,   576,   600,   541,   601,   602,
+     603,   604,   610,   437,   615,   617,   619,   620,   621,   622,
+     623,   624,   625,   626,   627,   631,   177,   426,   499,   457,
+      66,   267,   372,   439,   150,   311,   316,   485,   257,   361,
+     258,   470,   482,   637,   567,   372,   578,    67,   477,    68,
+      69,   598,    70,   632,    71,   635,   636,     0,   528,     0,
+     634,   164,     0,     0,   372,     0,    72,    73,     0,    74,
+      75,    76,    77,     0,     0,     0,    78,     0,     0,     0,
+      79,    80,    81,    82,    83,    66,   267,    84,    85,    86,
+      87,     0,     0,     0,     0,     0,    88,     0,    89,    90,
+      91,    92,    67,     0,    68,    69,     0,    70,     0,    71,
+       0,     0,   339,     0,     0,     0,     0,     0,     0,     0,
+       0,    72,    73,     0,    74,    75,    76,    77,     0,     0,
+       0,    78,     0,     0,     0,    79,    80,    81,    82,    83,
+      66,     0,    84,    85,    86,    87,     0,     0,     0,     0,
+       0,    88,     0,    89,    90,    91,    92,    67,     0,    68,
+      69,     0,    70,     0,    71,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    72,    73,     0,    74,
+      75,    76,    77,     0,     0,     0,    78,     0,     0,     0,
+      79,    80,    81,    82,    83,     0,     0,    84,    85,    86,
+      87,     0,     0,     0,     0,     0,    88,     0,    89,    90,
+      91,    92
 };
 
 static const yytype_int16 yycheck[] =
 {
-      23,    69,    25,    48,    49,    50,    51,    52,    53,    54,
-      55,    56,    57,    58,    81,    60,    61,    62,   120,   123,
-     118,    66,   119,    68,   124,    70,    85,    85,   193,   127,
-     125,   129,    77,    78,    79,    80,    81,    82,   147,   264,
-       6,    86,   203,   204,    89,    90,   128,   153,     3,   116,
-       3,     4,   200,    73,    77,   198,   199,   297,   298,    82,
-     297,   298,    85,     6,     6,     8,     3,     7,    11,     6,
-     115,     7,   117,     3,     4,   120,   186,    68,   123,    68,
-     190,     3,    71,    72,   151,    74,    25,    76,    28,    78,
-      81,   316,   240,     3,   188,    32,   190,     7,   121,    41,
-       3,     4,    41,    42,     3,   211,   151,    82,   218,     6,
-      32,   193,   260,    10,     6,     7,     8,     3,     4,    11,
-      86,    76,    77,    78,   218,   184,   115,     0,   402,    32,
-     119,   405,   406,   122,    26,    78,     3,    78,   158,   198,
-     199,   186,     3,    79,    85,   190,    76,    77,    78,    13,
-      60,    61,   210,    33,   213,    19,    20,    21,   147,     6,
-      40,     8,     3,     4,    11,   188,   331,   190,   157,     6,
-     313,   280,   161,   218,   414,   198,   199,   414,    84,    26,
-     169,    88,   288,     6,     7,     8,    12,   210,    11,     6,
-      16,     8,   335,    16,   337,   218,   219,    23,    24,    25,
-      69,    70,   427,    29,     6,     7,     8,   309,    22,    78,
-      24,    25,   452,    27,     4,    29,     6,     3,   458,     6,
-       7,     8,     3,     6,    11,    51,     7,    10,   113,    55,
-      56,    57,   117,    13,    14,    15,    85,   462,   283,    65,
-     299,   264,    56,    57,    52,    53,    54,    73,    83,   331,
-      72,    65,   297,   298,    80,     6,    74,   418,    76,     7,
-      86,    87,     3,     4,   309,   324,     6,     6,   327,     8,
-     329,   330,    11,   262,   297,   298,     7,   336,    28,   338,
-       9,    10,     7,   342,   343,   305,   511,    17,    18,     7,
-     313,   280,   398,   316,     7,   443,   402,   356,   357,   405,
-     406,     6,     7,   292,    60,    61,   365,   366,     6,     7,
-       8,    43,   335,    11,   337,   304,    49,    50,   307,     6,
-       7,     8,   483,     7,    11,    60,    61,   567,     6,     7,
-       8,     6,    12,    11,    30,    31,    16,     3,     4,   579,
-       4,   566,     4,    23,    24,    25,    17,    18,   407,    29,
-      33,    34,    35,    36,    37,    38,    39,    40,     6,     6,
-       6,     6,     6,   386,     6,     6,     6,   390,   391,   414,
-       6,    51,     6,   432,     6,    55,    56,    57,     6,     6,
-       6,   448,     6,     6,     6,    65,   445,   446,    68,   456,
-       6,   414,    72,   452,   452,    75,   416,     3,     6,     6,
-      80,    81,     6,     4,   427,     7,    86,    87,     7,   517,
-     518,   519,   520,   521,   522,   523,     4,     4,     4,     4,
-       4,   444,   481,   482,     4,   484,     4,    30,     4,   452,
-     419,     4,     4,   500,     4,   458,    85,    48,     4,   462,
-      29,     4,     4,     4,     4,     4,     4,    66,     4,     6,
-       4,     4,     4,   557,   556,   553,     4,   554,   558,     4,
-       4,     4,     3,    31,   559,   510,     4,     4,   527,     4,
-       4,     4,     4,   540,     4,     4,     4,     4,     4,     4,
-       4,   539,     4,     4,     4,     4,     4,   555,   511,     4,
-     549,     4,     4,     4,     4,     4,     4,     4,     4,   488,
-       4,     6,   547,     4,   571,     4,     6,     3,     6,     6,
-       4,     4,   557,    16,     4,    32,   539,     4,    41,     4,
-      67,    57,     6,    18,   513,    67,     4,     6,     4,     4,
-     589,     4,     4,     4,     4,     4,     4,     4,   552,   313,
-       5,     6,   555,   566,   567,   413,   301,   340,   313,   594,
-     171,    16,   165,   122,   121,   215,   579,    22,   390,    24,
-      25,    75,    27,   498,    29,   554,   386,   547,   591,   591,
-      72,   452,   595,    -1,    -1,    -1,    41,    42,    -1,    44,
+      23,    70,    25,    86,   123,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    57,    58,    59,    82,    61,    62,
+      63,   121,    74,   122,    67,   126,    69,   272,    71,   127,
+     132,   131,   128,   133,   157,    78,    79,    80,    81,    82,
+      83,   204,   305,   306,    87,   197,    89,   151,    91,    92,
+       7,   207,   208,     6,   119,    78,   305,   306,     3,    86,
+      83,     3,     4,    86,   202,   203,    69,     3,   475,    72,
+      73,     6,    75,     7,    77,   118,    79,   120,    83,   324,
+     123,     3,     7,   126,   247,     7,     6,    32,     8,     3,
+     155,    11,   215,   475,   476,   197,   190,     3,     4,     3,
+     194,   124,     6,    28,    25,   268,    41,    69,    70,     6,
+     162,     0,   155,    10,   192,   118,   194,    79,    68,   122,
+      41,    42,   125,    80,     3,     4,    32,    61,    32,   536,
+     224,   214,    82,    79,    87,    77,    78,    79,    60,    61,
+      86,    77,    78,    79,     3,    33,   224,   190,   151,     3,
+       6,   194,    40,     7,   536,   537,   538,    85,   161,    79,
+      13,   188,   165,     6,   427,     8,    19,    20,    21,   192,
+     173,   194,     6,   296,     8,   202,   203,    11,   427,   202,
+     203,   224,   415,   321,   288,   418,   419,   339,     3,     4,
+     217,   214,     6,     7,     8,   440,     6,    11,   317,     3,
+      10,   224,   225,   466,   116,   343,    89,   345,   120,   472,
+       3,     6,    26,     8,     4,    12,    11,     7,    86,    16,
+       6,     7,     8,     3,     4,    11,    23,    24,    25,    84,
+      16,    26,    29,     6,     7,     8,   481,   339,    22,     3,
+      24,    25,     6,    27,     4,    29,     6,     6,   291,   272,
+       6,     7,     8,    72,    51,    11,     3,     4,    55,    56,
+      57,   313,   305,   306,     6,     7,     8,   270,    65,    11,
+       9,    10,    56,    57,   317,   431,    73,    74,     6,     7,
+     307,    65,   305,   306,    81,   288,   531,     4,   411,     6,
+      87,    88,   415,   456,     7,   418,   419,   300,   321,    17,
+      18,   324,     6,     7,     8,   332,     7,    11,   335,   312,
+     337,   338,   315,     6,     7,     8,     6,   344,    11,   346,
+     343,     7,   345,   350,   351,    33,    34,    35,    36,    37,
+      38,    39,    40,     3,     4,    75,     6,    77,     7,   366,
+     367,     7,   605,    52,    53,    54,   502,    28,   375,   376,
+      13,    14,    15,     7,   599,   618,   543,   544,   545,   546,
+     547,   548,   549,    60,    61,    49,    50,    43,    60,    61,
+      17,    18,    30,    31,     3,     4,   399,   429,     6,     4,
+     403,   404,     6,   466,   427,     6,     6,     6,     6,     6,
+       6,     6,     6,   420,     6,     6,   461,     6,     6,     6,
+       6,     6,     4,     6,   427,   470,     6,     6,    12,     3,
+       6,     6,    16,     6,     4,     7,     7,   440,   445,    23,
+      24,    25,     4,     4,     4,    29,     4,     4,     4,   432,
+       4,   458,   459,    30,   457,     4,     4,     4,     4,   466,
+      86,     4,    29,   466,     4,     4,     4,    51,     4,   472,
+      48,    55,    56,    57,   519,     4,     4,     3,   481,     6,
+       4,    65,     4,     4,    68,     4,     4,     4,    72,    73,
+     589,     4,    76,   500,   501,     4,   503,    81,    82,     4,
+       4,     4,   565,    87,    88,     4,   586,   530,   587,   590,
+       4,     4,     4,   591,     4,     4,   592,     4,     4,     4,
+       4,   566,     4,     4,   507,     4,     4,     4,   531,     3,
+      31,     4,     4,     4,     4,     4,     4,     4,     4,   588,
+       4,     4,     4,    66,     4,     6,   553,     6,     3,     6,
+     573,    16,     4,     4,     3,    67,   539,     4,     6,     4,
+       4,     4,   565,     4,   609,    41,     4,   590,   575,     6,
+      67,     4,    18,   585,    32,     6,     6,    57,     4,     4,
+       4,     4,   588,   321,     6,     6,     4,     4,     4,     4,
+       4,     4,     4,     4,     4,     4,   599,   309,   426,   348,
+       5,     6,   605,   321,   587,   169,   175,   403,   124,   219,
+     125,    16,   399,   636,   517,   618,   535,    22,   392,    24,
+      25,   573,    27,   630,    29,   633,    76,    -1,   466,    -1,
+     633,    73,    -1,    -1,   637,    -1,    41,    42,    -1,    44,
       45,    46,    47,    -1,    -1,    -1,    51,    -1,    -1,    -1,
       55,    56,    57,    58,    59,     5,     6,    62,    63,    64,
       65,    -1,    -1,    -1,    -1,    -1,    71,    -1,    73,    74,
-      75,    -1,    22,    -1,    24,    25,    -1,    27,    -1,    29,
-      -1,    86,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      75,    76,    22,    -1,    24,    25,    -1,    27,    -1,    29,
+      -1,    -1,    87,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    41,    42,    -1,    44,    45,    46,    47,    -1,    -1,
       -1,    51,    -1,    -1,    -1,    55,    56,    57,    58,    59,
        5,    -1,    62,    63,    64,    65,    -1,    -1,    -1,    -1,
-      -1,    71,    -1,    73,    74,    75,    -1,    22,    -1,    24,
+      -1,    71,    -1,    73,    74,    75,    76,    22,    -1,    24,
       25,    -1,    27,    -1,    29,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    41,    42,    -1,    44,
       45,    46,    47,    -1,    -1,    -1,    51,    -1,    -1,    -1,
       55,    56,    57,    58,    59,    -1,    -1,    62,    63,    64,
       65,    -1,    -1,    -1,    -1,    -1,    71,    -1,    73,    74,
-      75
+      75,    76
 };
 
 /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
@@ -1194,100 +1220,106 @@
    state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,   179,   180,    82,     0,     3,   184,     6,    84,
-       3,   201,   181,   185,    88,   182,     3,   187,   202,     3,
-       4,   183,    85,   186,   111,   112,    83,   188,     3,     4,
-      92,   162,     3,     4,    91,    92,   104,   123,   124,   127,
-     129,   147,   171,   172,     6,     3,     4,    72,    12,    16,
+       0,     3,   186,   187,    83,     0,     3,   191,     6,    85,
+       3,   208,   188,   192,    89,   189,     3,   194,   209,     3,
+       4,   190,    86,   193,   112,   113,    84,   195,     3,     4,
+      93,   163,     3,     4,    92,    93,   105,   124,   125,   128,
+     130,   148,   178,   179,     6,     3,     4,    72,    12,    16,
       23,    24,    25,    29,    51,    55,    56,    57,    65,    73,
-      80,    86,    87,    68,    81,     5,    22,    24,    25,    27,
-      29,    41,    42,    44,    45,    46,    47,    51,    55,    56,
-      57,    58,    59,    62,    63,    64,    65,    71,    73,    74,
-      75,     9,    10,    94,    12,    16,    23,    24,    25,    29,
-      51,    55,    56,    57,    65,    68,    72,    75,    80,    81,
-      86,    87,   160,     7,     7,   142,   142,   142,   142,   142,
-     142,   142,   142,   142,   142,   142,     6,   142,   142,   142,
-       7,     7,     6,    10,    90,     6,     8,    93,   101,   142,
-       7,     6,     8,    11,    26,    95,    96,   102,   103,   142,
-      28,   105,   106,    96,    97,   109,   142,    96,   119,   122,
-     122,    43,   120,   131,   119,    78,    85,   132,   133,    78,
-     119,   128,     3,    92,   110,   137,   142,    96,   138,   142,
-     142,   143,   105,   142,   145,   146,    97,   142,   148,   149,
-     198,    60,    61,    92,   142,   151,   152,   191,   192,   199,
-      32,    92,   114,    17,    18,   154,     6,    91,    92,   114,
-     153,     6,   142,   158,   159,     7,     6,   142,   200,   142,
-       4,     6,     6,     6,     6,     6,     6,     6,     6,     6,
-       6,     6,     6,     6,     6,     6,     6,     6,     6,     4,
-      93,    96,   142,    97,    93,   142,    94,   103,   109,   142,
-     137,   138,   142,   143,   146,   159,     6,    94,   176,     6,
-     113,   190,    94,   193,   194,    69,    70,    78,   161,    60,
-      61,     7,     7,     4,     4,     4,     4,    13,    14,    15,
-     102,     4,     4,    16,    97,   142,     4,    95,    30,   107,
-       4,     4,    96,   120,     4,     4,    96,    49,    50,   130,
-       4,   120,   126,   132,    48,   134,     4,    96,   126,    29,
-      52,    53,    54,   136,     4,     4,   139,     4,     4,     4,
-     144,     4,     6,     4,   114,     4,   199,   192,     4,   192,
-     199,    86,   190,     4,    92,   114,   123,   114,   123,   111,
-     113,     4,   130,   130,     4,     4,     4,    91,    95,   155,
-       4,   114,     4,   152,   163,   173,   192,   199,     4,    76,
-      77,    78,    92,    98,   168,   170,   111,     4,     4,     4,
+      74,    81,    87,    88,    68,    82,     5,    22,    24,    25,
+      27,    29,    41,    42,    44,    45,    46,    47,    51,    55,
+      56,    57,    58,    59,    62,    63,    64,    65,    71,    73,
+      74,    75,    76,     9,    10,    95,    12,    16,    23,    24,
+      25,    29,    51,    55,    56,    57,    65,    68,    72,    73,
+      76,    81,    82,    87,    88,   161,     7,     7,   143,   143,
+     143,   143,   143,   143,   143,   143,   143,   143,   143,   143,
+       6,   143,   143,   143,     7,     7,     6,    10,    91,     6,
+       8,    94,   102,   143,     7,     6,     8,    11,    26,    96,
+      97,   103,   104,   143,    28,   106,   107,    97,    98,   110,
+     143,    97,   120,   123,   123,    43,   121,   132,   120,    79,
+      86,   133,   134,    79,   120,   129,     3,    93,   111,   138,
+     143,    97,   139,   143,   143,   144,   106,   143,   146,   147,
+      98,   143,   149,   150,   205,    60,    61,    93,   143,   152,
+     153,   198,   199,   206,    32,    93,   115,    17,    18,   155,
+       6,    92,    93,   115,   154,     6,   143,   159,   160,     7,
+      61,   143,     6,   143,   207,   143,     4,     6,     6,     6,
+       6,     6,     6,     6,     6,     6,     6,     6,     6,     6,
+       6,     6,     6,     6,     6,     6,     4,    94,    97,   143,
+      98,    94,   143,    95,   104,   110,   143,   138,   139,   143,
+     144,   147,   160,   169,     6,    95,   183,     6,   114,   197,
+      95,   200,   201,    69,    70,    79,   162,    60,    61,     7,
+       7,     4,     4,     4,     4,    13,    14,    15,   103,     4,
+       4,    16,    98,   143,     4,    96,    30,   108,     4,     4,
+      97,   121,     4,     4,    97,    49,    50,   131,     4,   121,
+     127,   133,    48,   135,     4,    97,   127,    29,    52,    53,
+      54,   137,     4,     4,   140,     4,     4,     4,   145,     4,
+       6,     4,   115,     4,   206,   199,     4,   199,   206,    87,
+     197,     4,    93,   115,   124,   115,   124,   112,   114,     4,
+     131,   131,     4,     4,     4,    92,    96,   156,     4,   115,
+       4,   153,     4,     4,   170,   180,   199,   206,     4,    77,
+      78,    79,    93,    99,   175,   177,   112,     4,     4,     4,
        4,     4,     4,     4,     4,     4,     4,     4,     4,     4,
-       4,     4,     6,   177,     4,   111,   189,     4,    96,     4,
-     110,   195,     4,     4,     4,   102,   142,     4,    17,    18,
-      95,   100,    31,   108,    96,    30,    31,   121,    98,   198,
-      98,   198,   114,   107,   125,     4,   135,    96,   120,    96,
-       4,   109,   142,    92,   104,   123,   124,   110,     6,    10,
-     141,   114,   150,   114,   114,   114,   190,     4,    92,   123,
-     114,   123,   114,   115,   112,   114,   114,     4,    66,   156,
-       4,     6,   165,     4,   114,   114,    16,     6,   114,   114,
-       4,     6,   174,   162,     6,    92,   147,    92,   196,     4,
-      95,    13,    19,    20,    21,    99,   100,   100,   100,   114,
-     108,    98,   198,   120,   130,    96,     4,     4,    25,   110,
-      32,   114,     4,   111,   116,     4,   114,   114,     7,    97,
-      67,   157,     4,    91,    92,    98,   114,   164,   191,    97,
-     169,    98,     4,   110,     6,    57,    22,    24,    25,    27,
-      29,    56,    57,    65,    18,   114,   114,   130,   114,   140,
-      33,    34,    35,    36,    37,    38,    39,    40,   117,   118,
-      67,   157,     7,    97,     4,    79,   142,   166,   167,   110,
-      96,   142,   197,   197,   197,   197,   197,   197,   197,   197,
-     114,    33,    40,    91,     7,   166,   114,   178,   101,    94,
-     103,   105,   106,   109,   143,   146,   159,     6,   110,    98,
-       4,     4,     4,     4,     4,     4,     4,     4,     4,    98,
-     114,   175,    92,   171,    75,   142
+       4,     3,   167,   168,     4,     6,   184,     4,   112,   196,
+       4,    97,     4,   111,   202,     4,     4,     4,   103,   143,
+       4,    17,    18,    96,   101,    31,   109,    97,    30,    31,
+     122,    99,   205,    99,   205,   115,   108,   126,     4,   136,
+      97,   121,    97,     4,   110,   143,    93,   105,   124,   125,
+     111,     6,    10,   142,   115,   151,   115,   115,   115,   197,
+       4,    93,   124,   115,   124,   115,   116,   113,   115,   115,
+       4,    66,   157,     4,     7,     6,   172,     4,   115,   115,
+      16,     6,   115,   115,     3,   165,   166,   167,     4,     4,
+       6,   181,   163,     6,    93,   148,    93,   203,     4,    96,
+      13,    19,    20,    21,   100,   101,   101,   101,   115,   109,
+      99,   205,   121,   131,    97,     4,     4,    25,   111,    32,
+     115,     4,   112,   117,     4,   115,   115,     7,    98,    67,
+     158,     4,     4,    92,    93,    99,   115,   171,   198,    98,
+     176,    99,     4,     3,     6,   164,   165,   166,   166,   111,
+       6,    57,    22,    24,    25,    27,    29,    56,    57,    65,
+      18,   115,   115,   131,   115,   141,    33,    34,    35,    36,
+      37,    38,    39,    40,   118,   119,    67,   158,     7,    98,
+       4,    80,   143,   173,   174,   111,     6,     4,   164,   165,
+     166,   166,   166,    97,   143,   204,   204,   204,   204,   204,
+     204,   204,   204,   115,    33,    40,    92,     7,   173,   115,
+       6,     4,     4,     4,     4,   185,   102,    95,   104,   106,
+     107,   110,   144,   147,   160,     6,   111,     6,    99,     4,
+       4,     4,     4,     4,     4,     4,     4,     4,     4,     6,
+      99,     4,   115,   182,    93,   178,    76,   143
 };
 
 /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    89,    90,    91,    92,    93,    93,    90,    94,    94,
-      95,    95,    95,    96,    96,    96,    97,    97,    97,    97,
-      98,    99,    99,    99,    99,   100,   101,    91,   102,   102,
-     103,   104,    91,   105,   105,   106,    91,   107,   107,   108,
-     108,   109,    91,   110,   111,   112,   112,   113,   113,   114,
-     115,   114,   116,   116,   117,   117,   117,   117,   117,   117,
-     117,   118,   117,   119,   120,   120,   121,   121,   121,   122,
-     123,   124,    91,    91,   125,   126,   126,   127,   128,   128,
-     129,   130,   130,   130,   130,   131,   127,   132,   132,   134,
-     133,   135,   133,   129,    91,    91,   136,   136,   136,   136,
-     137,   137,   137,    91,   139,   138,    91,   140,   140,   141,
-     141,   142,   144,   143,    91,   145,   145,   146,   146,   146,
-     147,    91,   148,   149,   149,   150,   149,   149,    91,   151,
-     151,   151,   151,   151,   151,    91,   152,   152,   151,    91,
-     153,    91,    91,    91,   154,   154,    91,   155,   155,   156,
-     156,   157,   157,   158,   158,   158,   158,   159,    91,   160,
-     161,   161,   161,   161,    91,    91,   162,   162,   162,    91,
-     163,   163,   164,   164,   164,   164,   165,   165,   166,   166,
-     167,   169,   168,   170,   170,   170,   170,   171,   172,    91,
-      91,   173,   173,    91,   174,   174,   175,   175,   177,   178,
-     176,    91,    91,   179,   181,   180,   182,   182,   183,   185,
-     184,   186,   186,   187,   188,   188,   160,   160,   160,   160,
-     160,   160,   160,   160,   160,   160,   160,   160,   160,   160,
-     160,   160,   160,   162,   162,   162,   162,   162,   162,   162,
-     162,   162,   162,   162,   162,   162,   162,   162,   162,   162,
-     189,   189,   190,   191,   192,   192,   193,   194,   195,   195,
-     196,   196,   196,   196,   196,   196,   196,   196,   197,   198,
-     199,   200,    91,    91,    91,    91,    91,    91,    91,    91,
-      91,    91,    91,   110,   202,   201
+       0,    90,    91,    92,    93,    94,    94,    91,    95,    95,
+      96,    96,    96,    97,    97,    97,    98,    98,    98,    98,
+      99,   100,   100,   100,   100,   101,   102,    92,   103,   103,
+     104,   105,    92,   106,   106,   107,    92,   108,   108,   109,
+     109,   110,    92,   111,   112,   113,   113,   114,   114,   115,
+     116,   115,   117,   117,   118,   118,   118,   118,   118,   118,
+     118,   119,   118,   120,   121,   121,   122,   122,   122,   123,
+     124,   125,    92,    92,   126,   127,   127,   128,   129,   129,
+     130,   131,   131,   131,   131,   132,   128,   133,   133,   135,
+     134,   136,   134,   130,    92,    92,   137,   137,   137,   137,
+     138,   138,   138,    92,   140,   139,    92,   141,   141,   142,
+     142,   143,   145,   144,    92,   146,   146,   147,   147,   147,
+     148,    92,   149,   150,   150,   151,   150,   150,    92,   152,
+     152,   152,   152,   152,   152,    92,   153,   153,   152,    92,
+     154,    92,    92,    92,   155,   155,    92,   156,   156,   157,
+     157,   158,   158,   159,   159,   159,   159,   160,    92,   161,
+     162,   162,   162,   162,    92,    92,    92,   163,   164,   164,
+     164,   165,   165,   166,   167,   167,   167,   168,   168,   169,
+     163,    92,    92,   163,   163,    92,   170,   170,   171,   171,
+     171,   171,   172,   172,   173,   173,   174,   176,   175,   177,
+     177,   177,   177,   178,   179,    92,    92,   180,   180,    92,
+     181,   181,   182,   182,   184,   185,   183,    92,    92,   186,
+     188,   187,   189,   189,   190,   192,   191,   193,   193,   194,
+     195,   195,   161,   161,   161,   161,   161,   161,   161,   161,
+     161,   161,   161,   161,   161,   161,   161,   161,   161,   161,
+     163,   163,   163,   163,   163,   163,   163,   163,   163,   163,
+     163,   163,   163,   163,   163,   163,   163,   196,   196,   197,
+     198,   199,   199,   200,   201,   202,   202,   203,   203,   203,
+     203,   203,   203,   203,   203,   204,   205,   206,   207,    92,
+      92,    92,    92,    92,    92,    92,    92,    92,    92,    92,
+     111,   209,   208
 };
 
 /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.  */
@@ -1309,19 +1341,21 @@
        3,     3,     2,     3,     3,     4,     1,     1,     1,     4,
        1,     4,     5,     4,     4,     4,     4,     1,     0,     2,
        0,     2,     0,     4,     5,     5,     6,     2,     4,     2,
-       1,     1,     1,     0,     5,     5,     7,     5,     6,     6,
-       0,     2,     1,     1,     1,     1,     0,     2,     1,     1,
-       3,     0,     4,     1,     1,     1,     1,    10,     4,     1,
-       1,     2,     2,     5,     0,     1,     0,     2,     0,     0,
-      10,     5,     5,     3,     0,     6,     0,     2,     5,     0,
-       6,     0,     2,     4,     0,     4,     2,     2,     2,     2,
+       1,     1,     1,     0,     5,     5,     6,     7,     6,     5,
+       1,     4,     3,     0,     5,     5,     5,     2,     4,     0,
+       6,     4,     4,     5,     6,     6,     0,     2,     1,     1,
+       1,     1,     0,     2,     1,     1,     3,     0,     4,     1,
+       1,     1,     1,    10,     4,     1,     1,     2,     2,     5,
+       0,     1,     0,     2,     0,     0,    10,     5,     5,     3,
+       0,     6,     0,     2,     5,     0,     6,     0,     2,     4,
+       0,     4,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     5,     5,     5,     5,     5,     5,     5,
        5,     5,     5,     5,     5,     5,     5,     5,     5,     5,
-       1,     2,     2,     4,     1,     3,     2,     4,     2,     2,
-       5,     5,     5,     5,     5,     5,     5,     5,     1,     1,
-       1,     1,     4,     5,     6,     4,     4,     4,     4,     4,
-       4,     4,     4,     4,     0,     5
+       5,     5,     5,     5,     5,     5,     5,     1,     2,     2,
+       4,     1,     3,     2,     4,     2,     2,     5,     5,     5,
+       5,     5,     5,     5,     5,     1,     1,     1,     1,     4,
+       5,     6,     4,     4,     4,     4,     4,     4,     4,     4,
+       4,     0,     5
 };
 
 
@@ -2055,1202 +2089,1210 @@
   switch (yyn)
     {
   case 2: /* glyph: UNSIGNED REFERENCE  */
-#line 274 "parser.y"
+#line 276 "parser.y"
                         {
 	#line 421 "format.w"
 	(yyval.c).c= (yyvsp[-1].u);REF(font_kind,(yyvsp[0].u));(yyval.c).f= (yyvsp[0].u);}
-#line 2063 "parser.c"
+#line 2097 "parser.c"
     break;
 
   case 3: /* content_node: start "glyph" glyph ">"  */
-#line 277 "parser.y"
+#line 279 "parser.y"
                                   {
 	#line 422 "format.w"
 	hput_tags((yyvsp[-3].u),hput_glyph(&((yyvsp[-1].c))));}
-#line 2071 "parser.c"
+#line 2105 "parser.c"
     break;
 
   case 4: /* start: "<"  */
-#line 280 "parser.y"
+#line 282 "parser.y"
            {
 	#line 423 "format.w"
 	HPUTNODE;(yyval.u)= (uint32_t)(hpos++-hstart);}
-#line 2079 "parser.c"
+#line 2113 "parser.c"
     break;
 
   case 6: /* integer: UNSIGNED  */
-#line 284 "parser.y"
+#line 286 "parser.y"
                          {
-	#line 951 "format.w"
+	#line 953 "format.w"
 	RNG("number",(yyvsp[0].u),0,0x7FFFFFFF);}
-#line 2087 "parser.c"
+#line 2121 "parser.c"
     break;
 
   case 7: /* glyph: CHARCODE REFERENCE  */
-#line 288 "parser.y"
+#line 290 "parser.y"
                         {
-	#line 1093 "format.w"
+	#line 1095 "format.w"
 	(yyval.c).c= (yyvsp[-1].u);REF(font_kind,(yyvsp[0].u));(yyval.c).f= (yyvsp[0].u);}
-#line 2095 "parser.c"
+#line 2129 "parser.c"
     break;
 
   case 9: /* string: CHARCODE  */
-#line 292 "parser.y"
+#line 294 "parser.y"
                          {
-	#line 1198 "format.w"
+	#line 1200 "format.w"
 	static char s[2];
 	RNG("String element",(yyvsp[0].u),0x20,0x7E);
 	s[0]= (yyvsp[0].u);s[1]= 0;(yyval.s)= s;}
-#line 2105 "parser.c"
+#line 2139 "parser.c"
     break;
 
   case 10: /* number: UNSIGNED  */
-#line 298 "parser.y"
+#line 300 "parser.y"
                {
-	#line 1351 "format.w"
+	#line 1353 "format.w"
 	(yyval.f)= (float64_t)(yyvsp[0].u);}
-#line 2113 "parser.c"
+#line 2147 "parser.c"
     break;
 
   case 11: /* number: SIGNED  */
-#line 300 "parser.y"
+#line 302 "parser.y"
                                        {
-	#line 1351 "format.w"
+	#line 1353 "format.w"
 	(yyval.f)= (float64_t)(yyvsp[0].i);}
-#line 2121 "parser.c"
+#line 2155 "parser.c"
     break;
 
   case 13: /* dimension: number "pt"  */
-#line 304 "parser.y"
+#line 306 "parser.y"
                    {
-	#line 1705 "format.w"
+	#line 1707 "format.w"
 	(yyval.d)= ROUND((yyvsp[-1].f)*ONE);RNG("Dimension",(yyval.d),-MAX_DIMEN,MAX_DIMEN);}
-#line 2129 "parser.c"
+#line 2163 "parser.c"
     break;
 
   case 14: /* dimension: number "in"  */
-#line 307 "parser.y"
+#line 309 "parser.y"
                     {
-	#line 1706 "format.w"
+	#line 1708 "format.w"
 	(yyval.d)= ROUND((yyvsp[-1].f)*ONE*72.27);RNG("Dimension",(yyval.d),-MAX_DIMEN,MAX_DIMEN);}
-#line 2137 "parser.c"
+#line 2171 "parser.c"
     break;
 
   case 15: /* dimension: number "mm"  */
-#line 310 "parser.y"
+#line 312 "parser.y"
                   {
-	#line 1707 "format.w"
+	#line 1709 "format.w"
 	(yyval.d)= ROUND((yyvsp[-1].f)*ONE*(72.27/25.4));RNG("Dimension",(yyval.d),-MAX_DIMEN,MAX_DIMEN);}
-#line 2145 "parser.c"
+#line 2179 "parser.c"
     break;
 
   case 16: /* xdimen: dimension number "h" number "v"  */
-#line 314 "parser.y"
+#line 316 "parser.y"
                                   {
-	#line 1785 "format.w"
+	#line 1787 "format.w"
 	(yyval.xd).w= (yyvsp[-4].d);(yyval.xd).h= (yyvsp[-3].f);(yyval.xd).v= (yyvsp[-1].f);}
-#line 2153 "parser.c"
+#line 2187 "parser.c"
     break;
 
   case 17: /* xdimen: dimension number "h"  */
-#line 317 "parser.y"
+#line 319 "parser.y"
                            {
-	#line 1786 "format.w"
+	#line 1788 "format.w"
 	(yyval.xd).w= (yyvsp[-2].d);(yyval.xd).h= (yyvsp[-1].f);(yyval.xd).v= 0.0;}
-#line 2161 "parser.c"
+#line 2195 "parser.c"
     break;
 
   case 18: /* xdimen: dimension number "v"  */
-#line 320 "parser.y"
+#line 322 "parser.y"
                            {
-	#line 1787 "format.w"
+	#line 1789 "format.w"
 	(yyval.xd).w= (yyvsp[-2].d);(yyval.xd).h= 0.0;(yyval.xd).v= (yyvsp[-1].f);}
-#line 2169 "parser.c"
+#line 2203 "parser.c"
     break;
 
   case 19: /* xdimen: dimension  */
-#line 323 "parser.y"
+#line 325 "parser.y"
                   {
-	#line 1788 "format.w"
+	#line 1790 "format.w"
 	(yyval.xd).w= (yyvsp[0].d);(yyval.xd).h= 0.0;(yyval.xd).v= 0.0;}
-#line 2177 "parser.c"
+#line 2211 "parser.c"
     break;
 
   case 20: /* xdimen_node: start "xdimen" xdimen ">"  */
-#line 327 "parser.y"
+#line 329 "parser.y"
                                    {
-	#line 1790 "format.w"
+	#line 1792 "format.w"
 	hput_tags((yyvsp[-3].u),hput_xdimen(&((yyvsp[-1].xd))));}
-#line 2185 "parser.c"
+#line 2219 "parser.c"
     break;
 
   case 21: /* order: "pt"  */
-#line 332 "parser.y"
+#line 334 "parser.y"
         {
-	#line 1969 "format.w"
+	#line 1971 "format.w"
 	(yyval.o)= normal_o;}
-#line 2193 "parser.c"
+#line 2227 "parser.c"
     break;
 
   case 22: /* order: "fil"  */
-#line 334 "parser.y"
+#line 336 "parser.y"
                             {
-	#line 1969 "format.w"
+	#line 1971 "format.w"
 	(yyval.o)= fil_o;}
-#line 2201 "parser.c"
+#line 2235 "parser.c"
     break;
 
   case 23: /* order: "fill"  */
-#line 336 "parser.y"
+#line 338 "parser.y"
                              {
-	#line 1969 "format.w"
+	#line 1971 "format.w"
 	(yyval.o)= fill_o;}
-#line 2209 "parser.c"
+#line 2243 "parser.c"
     break;
 
   case 24: /* order: "filll"  */
-#line 338 "parser.y"
+#line 340 "parser.y"
                               {
-	#line 1969 "format.w"
+	#line 1971 "format.w"
 	(yyval.o)= filll_o;}
-#line 2217 "parser.c"
+#line 2251 "parser.c"
     break;
 
   case 25: /* stretch: number order  */
-#line 342 "parser.y"
+#line 344 "parser.y"
                     {
-	#line 1971 "format.w"
+	#line 1973 "format.w"
 	(yyval.st).f= (yyvsp[-1].f);(yyval.st).o= (yyvsp[0].o);}
-#line 2225 "parser.c"
+#line 2259 "parser.c"
     break;
 
   case 26: /* penalty: integer  */
-#line 346 "parser.y"
+#line 348 "parser.y"
                {
-	#line 2025 "format.w"
+	#line 2027 "format.w"
 	RNG("Penalty",(yyvsp[0].i),-20000,+20000);(yyval.i)= (yyvsp[0].i);}
-#line 2233 "parser.c"
+#line 2267 "parser.c"
     break;
 
   case 27: /* content_node: start "penalty" penalty ">"  */
-#line 349 "parser.y"
+#line 351 "parser.y"
                                       {
-	#line 2026 "format.w"
+	#line 2028 "format.w"
 	hput_tags((yyvsp[-3].u),hput_int((yyvsp[-1].i)));}
-#line 2241 "parser.c"
+#line 2275 "parser.c"
     break;
 
   case 29: /* rule_dimension: "|"  */
-#line 353 "parser.y"
+#line 355 "parser.y"
                                         {
-	#line 2203 "format.w"
+	#line 2205 "format.w"
 	(yyval.d)= RUNNING_DIMEN;}
-#line 2249 "parser.c"
+#line 2283 "parser.c"
     break;
 
   case 30: /* rule: rule_dimension rule_dimension rule_dimension  */
-#line 357 "parser.y"
+#line 359 "parser.y"
 {
-	#line 2205 "format.w"
+	#line 2207 "format.w"
 	(yyval.r).h= (yyvsp[-2].d);(yyval.r).d= (yyvsp[-1].d);(yyval.r).w= (yyvsp[0].d);
 	if((yyvsp[0].d)==RUNNING_DIMEN&&((yyvsp[-2].d)==RUNNING_DIMEN||(yyvsp[-1].d)==RUNNING_DIMEN))
 	QUIT("Incompatible running dimensions 0x%x 0x%x 0x%x",(yyvsp[-2].d),(yyvsp[-1].d),(yyvsp[0].d));}
-#line 2259 "parser.c"
+#line 2293 "parser.c"
     break;
 
   case 31: /* rule_node: start "rule" rule ">"  */
-#line 362 "parser.y"
+#line 364 "parser.y"
                              {
-	#line 2208 "format.w"
+	#line 2210 "format.w"
 	hput_tags((yyvsp[-3].u),hput_rule(&((yyvsp[-1].r))));}
-#line 2267 "parser.c"
+#line 2301 "parser.c"
     break;
 
   case 33: /* explicit: %empty  */
-#line 367 "parser.y"
+#line 369 "parser.y"
          {
-	#line 2316 "format.w"
+	#line 2318 "format.w"
 	(yyval.b)= false;}
-#line 2275 "parser.c"
+#line 2309 "parser.c"
     break;
 
   case 34: /* explicit: "!"  */
-#line 369 "parser.y"
+#line 371 "parser.y"
                                  {
-	#line 2316 "format.w"
+	#line 2318 "format.w"
 	(yyval.b)= true;}
-#line 2283 "parser.c"
+#line 2317 "parser.c"
     break;
 
   case 35: /* kern: explicit xdimen  */
-#line 372 "parser.y"
+#line 374 "parser.y"
                     {
-	#line 2317 "format.w"
+	#line 2319 "format.w"
 	(yyval.kt).x= (yyvsp[-1].b);(yyval.kt).d= (yyvsp[0].xd);}
-#line 2291 "parser.c"
+#line 2325 "parser.c"
     break;
 
   case 36: /* content_node: start "kern" kern ">"  */
-#line 375 "parser.y"
+#line 377 "parser.y"
                                 {
-	#line 2318 "format.w"
+	#line 2320 "format.w"
 	hput_tags((yyvsp[-3].u),hput_kern(&((yyvsp[-1].kt))));}
-#line 2299 "parser.c"
+#line 2333 "parser.c"
     break;
 
   case 37: /* plus: %empty  */
-#line 379 "parser.y"
+#line 381 "parser.y"
      {
-	#line 2528 "format.w"
+	#line 2530 "format.w"
 	(yyval.st).f= 0.0;(yyval.st).o= 0;}
-#line 2307 "parser.c"
+#line 2341 "parser.c"
     break;
 
   case 38: /* plus: "plus" stretch  */
-#line 381 "parser.y"
+#line 383 "parser.y"
                                              {
-	#line 2528 "format.w"
+	#line 2530 "format.w"
 	(yyval.st)= (yyvsp[0].st);}
-#line 2315 "parser.c"
+#line 2349 "parser.c"
     break;
 
   case 39: /* minus: %empty  */
-#line 384 "parser.y"
+#line 386 "parser.y"
       {
-	#line 2529 "format.w"
+	#line 2531 "format.w"
 	(yyval.st).f= 0.0;(yyval.st).o= 0;}
-#line 2323 "parser.c"
+#line 2357 "parser.c"
     break;
 
   case 40: /* minus: "minus" stretch  */
-#line 386 "parser.y"
+#line 388 "parser.y"
                                               {
-	#line 2529 "format.w"
+	#line 2531 "format.w"
 	(yyval.st)= (yyvsp[0].st);}
-#line 2331 "parser.c"
+#line 2365 "parser.c"
     break;
 
   case 41: /* glue: xdimen plus minus  */
-#line 389 "parser.y"
+#line 391 "parser.y"
                       {
-	#line 2530 "format.w"
+	#line 2532 "format.w"
 	(yyval.g).w= (yyvsp[-2].xd);(yyval.g).p= (yyvsp[-1].st);(yyval.g).m= (yyvsp[0].st);}
-#line 2339 "parser.c"
+#line 2373 "parser.c"
     break;
 
   case 42: /* content_node: start "glue" glue ">"  */
-#line 392 "parser.y"
+#line 394 "parser.y"
                                 {
-	#line 2531 "format.w"
+	#line 2533 "format.w"
 	if(ZERO_GLUE((yyvsp[-1].g))){HPUT8(zero_skip_no);
 	hput_tags((yyvsp[-3].u),TAG(glue_kind,0));}else hput_tags((yyvsp[-3].u),hput_glue(&((yyvsp[-1].g))));}
-#line 2348 "parser.c"
+#line 2382 "parser.c"
     break;
 
   case 43: /* glue_node: start "glue" glue ">"  */
-#line 397 "parser.y"
+#line 399 "parser.y"
 {
-	#line 2534 "format.w"
+	#line 2536 "format.w"
 	if(ZERO_GLUE((yyvsp[-1].g))){hpos--;(yyval.b)= false;}
 	else{hput_tags((yyvsp[-3].u),hput_glue(&((yyvsp[-1].g))));(yyval.b)= true;}}
-#line 2357 "parser.c"
+#line 2391 "parser.c"
     break;
 
   case 44: /* position: %empty  */
-#line 402 "parser.y"
+#line 404 "parser.y"
          {
-	#line 2809 "format.w"
+	#line 2811 "format.w"
 	(yyval.u)= hpos-hstart;}
-#line 2365 "parser.c"
+#line 2399 "parser.c"
     break;
 
   case 47: /* estimate: %empty  */
-#line 407 "parser.y"
+#line 409 "parser.y"
          {
-	#line 2812 "format.w"
+	#line 2814 "format.w"
 	hpos+= 2;}
-#line 2373 "parser.c"
+#line 2407 "parser.c"
     break;
 
   case 48: /* estimate: UNSIGNED  */
-#line 410 "parser.y"
+#line 412 "parser.y"
                  {
-	#line 2813 "format.w"
+	#line 2815 "format.w"
 	hpos+= hsize_bytes((yyvsp[0].u))+1;}
-#line 2381 "parser.c"
+#line 2415 "parser.c"
     break;
 
   case 49: /* list: start estimate content_list ">"  */
-#line 414 "parser.y"
+#line 416 "parser.y"
 {
-	#line 2815 "format.w"
+	#line 2817 "format.w"
 	(yyval.l).t= TAG(list_kind,b010);(yyval.l).p= (yyvsp[-1].u);(yyval.l).s= (hpos-hstart)-(yyvsp[-1].u);
 	hput_tags((yyvsp[-3].u),hput_list((yyvsp[-3].u)+1,&((yyval.l))));}
-#line 2390 "parser.c"
+#line 2424 "parser.c"
     break;
 
   case 50: /* $@1: %empty  */
-#line 420 "parser.y"
+#line 422 "parser.y"
 {
-	#line 3229 "format.w"
+	#line 3231 "format.w"
 	hpos+= 4;}
-#line 2398 "parser.c"
+#line 2432 "parser.c"
     break;
 
   case 51: /* list: TXT_START position $@1 text TXT_END  */
-#line 424 "parser.y"
+#line 426 "parser.y"
 {
-	#line 3231 "format.w"
+	#line 3233 "format.w"
 	(yyval.l).t= TAG(list_kind,b110);(yyval.l).p= (yyvsp[-1].u);(yyval.l).s= (hpos-hstart)-(yyvsp[-1].u);
 	hput_tags((yyvsp[-3].u),hput_list((yyvsp[-3].u)+1,&((yyval.l))));}
-#line 2407 "parser.c"
+#line 2441 "parser.c"
     break;
 
   case 54: /* txt: TXT_CC  */
-#line 430 "parser.y"
+#line 432 "parser.y"
           {
-	#line 3235 "format.w"
+	#line 3237 "format.w"
 	hput_txt_cc((yyvsp[0].u));}
-#line 2415 "parser.c"
+#line 2449 "parser.c"
     break;
 
   case 55: /* txt: TXT_FONT  */
-#line 433 "parser.y"
+#line 435 "parser.y"
                  {
-	#line 3236 "format.w"
+	#line 3238 "format.w"
 	REF(font_kind,(yyvsp[0].u));hput_txt_font((yyvsp[0].u));}
-#line 2423 "parser.c"
+#line 2457 "parser.c"
     break;
 
   case 56: /* txt: TXT_GLOBAL  */
-#line 436 "parser.y"
+#line 438 "parser.y"
                    {
-	#line 3237 "format.w"
+	#line 3239 "format.w"
 	REF((yyvsp[0].rf).k,(yyvsp[0].rf).n);hput_txt_global(&((yyvsp[0].rf)));}
-#line 2431 "parser.c"
+#line 2465 "parser.c"
     break;
 
   case 57: /* txt: TXT_LOCAL  */
-#line 439 "parser.y"
+#line 441 "parser.y"
                   {
-	#line 3238 "format.w"
+	#line 3240 "format.w"
 	RNG("Font parameter",(yyvsp[0].u),0,11);hput_txt_local((yyvsp[0].u));}
-#line 2439 "parser.c"
+#line 2473 "parser.c"
     break;
 
   case 58: /* txt: TXT_FONT_GLUE  */
-#line 442 "parser.y"
+#line 444 "parser.y"
                       {
-	#line 3239 "format.w"
+	#line 3241 "format.w"
 	HPUTX(1);HPUT8(txt_glue);}
-#line 2447 "parser.c"
+#line 2481 "parser.c"
     break;
 
   case 59: /* txt: TXT_FONT_HYPHEN  */
-#line 445 "parser.y"
+#line 447 "parser.y"
                         {
-	#line 3240 "format.w"
+	#line 3242 "format.w"
 	HPUTX(1);HPUT8(txt_hyphen);}
-#line 2455 "parser.c"
+#line 2489 "parser.c"
     break;
 
   case 60: /* txt: TXT_IGNORE  */
-#line 448 "parser.y"
+#line 450 "parser.y"
                    {
-	#line 3241 "format.w"
+	#line 3243 "format.w"
 	HPUTX(1);HPUT8(txt_ignore);}
-#line 2463 "parser.c"
+#line 2497 "parser.c"
     break;
 
   case 61: /* $@2: %empty  */
-#line 451 "parser.y"
+#line 453 "parser.y"
          {
-	#line 3242 "format.w"
+	#line 3244 "format.w"
 	HPUTX(1);HPUT8(txt_node);}
-#line 2471 "parser.c"
+#line 2505 "parser.c"
     break;
 
   case 63: /* box_dimen: dimension dimension dimension  */
-#line 457 "parser.y"
+#line 459 "parser.y"
 {
-	#line 3498 "format.w"
+	#line 3500 "format.w"
 	(yyval.info)= hput_box_dimen((yyvsp[-2].d),(yyvsp[-1].d),(yyvsp[0].d));}
-#line 2479 "parser.c"
+#line 2513 "parser.c"
     break;
 
   case 64: /* box_shift: %empty  */
-#line 460 "parser.y"
+#line 462 "parser.y"
           {
-	#line 3499 "format.w"
+	#line 3501 "format.w"
 	(yyval.info)= b000;}
-#line 2487 "parser.c"
+#line 2521 "parser.c"
     break;
 
   case 65: /* box_shift: "shifted" dimension  */
-#line 463 "parser.y"
+#line 465 "parser.y"
                           {
-	#line 3500 "format.w"
+	#line 3502 "format.w"
 	(yyval.info)= hput_box_shift((yyvsp[0].d));}
-#line 2495 "parser.c"
+#line 2529 "parser.c"
     break;
 
   case 66: /* box_glue_set: %empty  */
-#line 467 "parser.y"
+#line 469 "parser.y"
              {
-	#line 3502 "format.w"
+	#line 3504 "format.w"
 	(yyval.info)= b000;}
-#line 2503 "parser.c"
+#line 2537 "parser.c"
     break;
 
   case 67: /* box_glue_set: "plus" stretch  */
-#line 470 "parser.y"
+#line 472 "parser.y"
                      {
-	#line 3503 "format.w"
+	#line 3505 "format.w"
 	(yyval.info)= hput_box_glue_set(+1,(yyvsp[0].st).f,(yyvsp[0].st).o);}
-#line 2511 "parser.c"
+#line 2545 "parser.c"
     break;
 
   case 68: /* box_glue_set: "minus" stretch  */
-#line 473 "parser.y"
+#line 475 "parser.y"
                       {
-	#line 3504 "format.w"
+	#line 3506 "format.w"
 	(yyval.info)= hput_box_glue_set(-1,(yyvsp[0].st).f,(yyvsp[0].st).o);}
-#line 2519 "parser.c"
+#line 2553 "parser.c"
     break;
 
   case 69: /* box: box_dimen box_shift box_glue_set list  */
-#line 478 "parser.y"
+#line 480 "parser.y"
                                          {
-	#line 3507 "format.w"
+	#line 3509 "format.w"
 	(yyval.info)= (yyvsp[-3].info)	|(yyvsp[-2].info)	|(yyvsp[-1].info);}
-#line 2527 "parser.c"
+#line 2561 "parser.c"
     break;
 
   case 70: /* hbox_node: start "hbox" box ">"  */
-#line 482 "parser.y"
+#line 484 "parser.y"
                             {
-	#line 3509 "format.w"
+	#line 3511 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(hbox_kind,(yyvsp[-1].info)));}
-#line 2535 "parser.c"
+#line 2569 "parser.c"
     break;
 
   case 71: /* vbox_node: start "vbox" box ">"  */
-#line 485 "parser.y"
+#line 487 "parser.y"
                             {
-	#line 3510 "format.w"
+	#line 3512 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(vbox_kind,(yyvsp[-1].info)));}
-#line 2543 "parser.c"
+#line 2577 "parser.c"
     break;
 
   case 74: /* box_flex: plus minus  */
-#line 490 "parser.y"
+#line 492 "parser.y"
                    {
-	#line 3706 "format.w"
+	#line 3708 "format.w"
 	hput_stretch(&((yyvsp[-1].st)));hput_stretch(&((yyvsp[0].st)));}
-#line 2551 "parser.c"
+#line 2585 "parser.c"
     break;
 
   case 75: /* box_options: box_shift box_flex xdimen_ref list  */
-#line 494 "parser.y"
+#line 496 "parser.y"
                                               {
-	#line 3708 "format.w"
+	#line 3710 "format.w"
 	(yyval.info)= (yyvsp[-3].info);}
-#line 2559 "parser.c"
+#line 2593 "parser.c"
     break;
 
   case 76: /* box_options: box_shift box_flex xdimen_node list  */
-#line 497 "parser.y"
+#line 499 "parser.y"
                                             {
-	#line 3709 "format.w"
+	#line 3711 "format.w"
 	(yyval.info)= (yyvsp[-3].info)	|b100;}
-#line 2567 "parser.c"
+#line 2601 "parser.c"
     break;
 
   case 77: /* hxbox_node: start "hset" box_dimen box_options ">"  */
-#line 501 "parser.y"
+#line 503 "parser.y"
                                                {
-	#line 3711 "format.w"
+	#line 3713 "format.w"
 	hput_tags((yyvsp[-4].u),TAG(hset_kind,(yyvsp[-2].info)	|(yyvsp[-1].info)));}
-#line 2575 "parser.c"
+#line 2609 "parser.c"
     break;
 
   case 79: /* vbox_dimen: "top" dimension dimension dimension  */
-#line 507 "parser.y"
+#line 509 "parser.y"
 {
-	#line 3715 "format.w"
+	#line 3717 "format.w"
 	(yyval.info)= hput_box_dimen((yyvsp[-2].d),(yyvsp[-1].d)^0x40000000,(yyvsp[0].d));}
-#line 2583 "parser.c"
+#line 2617 "parser.c"
     break;
 
   case 80: /* vxbox_node: start "vset" vbox_dimen box_options ">"  */
-#line 511 "parser.y"
+#line 513 "parser.y"
                                                 {
-	#line 3717 "format.w"
+	#line 3719 "format.w"
 	hput_tags((yyvsp[-4].u),TAG(vset_kind,(yyvsp[-2].info)	|(yyvsp[-1].info)));}
-#line 2591 "parser.c"
+#line 2625 "parser.c"
     break;
 
   case 81: /* box_goal: "to" xdimen_ref  */
-#line 515 "parser.y"
+#line 517 "parser.y"
                       {
-	#line 3719 "format.w"
+	#line 3721 "format.w"
 	(yyval.info)= b000;}
-#line 2599 "parser.c"
+#line 2633 "parser.c"
     break;
 
   case 82: /* box_goal: "add" xdimen_ref  */
-#line 518 "parser.y"
+#line 520 "parser.y"
                        {
-	#line 3720 "format.w"
+	#line 3722 "format.w"
 	(yyval.info)= b001;}
-#line 2607 "parser.c"
+#line 2641 "parser.c"
     break;
 
   case 83: /* box_goal: "to" xdimen_node  */
-#line 521 "parser.y"
+#line 523 "parser.y"
                        {
-	#line 3721 "format.w"
+	#line 3723 "format.w"
 	(yyval.info)= b100;}
-#line 2615 "parser.c"
+#line 2649 "parser.c"
     break;
 
   case 84: /* box_goal: "add" xdimen_node  */
-#line 524 "parser.y"
+#line 526 "parser.y"
                         {
-	#line 3722 "format.w"
+	#line 3724 "format.w"
 	(yyval.info)= b101;}
-#line 2623 "parser.c"
+#line 2657 "parser.c"
     break;
 
   case 85: /* hpack: box_shift box_goal list  */
-#line 528 "parser.y"
+#line 530 "parser.y"
                              {
-	#line 3724 "format.w"
+	#line 3726 "format.w"
 	(yyval.info)= (yyvsp[-1].info);}
-#line 2631 "parser.c"
+#line 2665 "parser.c"
     break;
 
   case 86: /* hxbox_node: start "hpack" hpack ">"  */
-#line 532 "parser.y"
+#line 534 "parser.y"
                                 {
-	#line 3726 "format.w"
+	#line 3728 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(hpack_kind,(yyvsp[-1].info)));}
-#line 2639 "parser.c"
+#line 2673 "parser.c"
     break;
 
   case 87: /* max_depth: %empty  */
-#line 536 "parser.y"
+#line 538 "parser.y"
           {
-	#line 3728 "format.w"
+	#line 3730 "format.w"
 	(yyval.d)= MAX_DIMEN;}
-#line 2647 "parser.c"
+#line 2681 "parser.c"
     break;
 
   case 88: /* max_depth: "max" "depth" dimension  */
-#line 538 "parser.y"
+#line 540 "parser.y"
                                             {
-	#line 3728 "format.w"
+	#line 3730 "format.w"
 	(yyval.d)= (yyvsp[0].d);}
-#line 2655 "parser.c"
+#line 2689 "parser.c"
     break;
 
   case 89: /* $@3: %empty  */
-#line 542 "parser.y"
+#line 544 "parser.y"
                {
-	#line 3730 "format.w"
+	#line 3732 "format.w"
 	HPUT32((yyvsp[0].d));}
-#line 2663 "parser.c"
+#line 2697 "parser.c"
     break;
 
   case 90: /* vpack: max_depth $@3 box_shift box_goal list  */
-#line 544 "parser.y"
+#line 546 "parser.y"
                                            {
-	#line 3730 "format.w"
+	#line 3732 "format.w"
 	(yyval.info)= (yyvsp[-2].info)	|(yyvsp[-1].info);}
-#line 2671 "parser.c"
+#line 2705 "parser.c"
     break;
 
   case 91: /* $@4: %empty  */
-#line 547 "parser.y"
+#line 549 "parser.y"
                       {
-	#line 3731 "format.w"
+	#line 3733 "format.w"
 	HPUT32((yyvsp[0].d)^0x40000000);}
-#line 2679 "parser.c"
+#line 2713 "parser.c"
     break;
 
   case 92: /* vpack: "top" max_depth $@4 box_shift box_goal list  */
-#line 549 "parser.y"
+#line 551 "parser.y"
                                                       {
-	#line 3731 "format.w"
+	#line 3733 "format.w"
 	(yyval.info)= (yyvsp[-2].info)	|(yyvsp[-1].info);}
-#line 2687 "parser.c"
+#line 2721 "parser.c"
     break;
 
   case 93: /* vxbox_node: start "vpack" vpack ">"  */
-#line 553 "parser.y"
+#line 555 "parser.y"
                                 {
-	#line 3733 "format.w"
+	#line 3735 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(vpack_kind,(yyvsp[-1].info)));}
-#line 2695 "parser.c"
+#line 2729 "parser.c"
     break;
 
   case 96: /* ltype: %empty  */
-#line 559 "parser.y"
+#line 561 "parser.y"
       {
-	#line 3847 "format.w"
+	#line 3849 "format.w"
 	(yyval.info)= 1;}
-#line 2703 "parser.c"
+#line 2737 "parser.c"
     break;
 
   case 97: /* ltype: "align"  */
-#line 561 "parser.y"
+#line 563 "parser.y"
                       {
-	#line 3847 "format.w"
+	#line 3849 "format.w"
 	(yyval.info)= 1;}
-#line 2711 "parser.c"
+#line 2745 "parser.c"
     break;
 
   case 98: /* ltype: "center"  */
-#line 563 "parser.y"
+#line 565 "parser.y"
                        {
-	#line 3847 "format.w"
+	#line 3849 "format.w"
 	(yyval.info)= 2;}
-#line 2719 "parser.c"
+#line 2753 "parser.c"
     break;
 
   case 99: /* ltype: "expand"  */
-#line 565 "parser.y"
+#line 567 "parser.y"
                        {
-	#line 3847 "format.w"
+	#line 3849 "format.w"
 	(yyval.info)= 3;}
-#line 2727 "parser.c"
+#line 2761 "parser.c"
     break;
 
   case 100: /* leaders: glue_node ltype rule_node  */
-#line 568 "parser.y"
+#line 570 "parser.y"
                                  {
-	#line 3848 "format.w"
+	#line 3850 "format.w"
 	if((yyvsp[-2].b))(yyval.info)= (yyvsp[-1].info)	|b100;else (yyval.info)= (yyvsp[-1].info);}
-#line 2735 "parser.c"
+#line 2769 "parser.c"
     break;
 
   case 101: /* leaders: glue_node ltype hbox_node  */
-#line 571 "parser.y"
+#line 573 "parser.y"
                                   {
-	#line 3849 "format.w"
+	#line 3851 "format.w"
 	if((yyvsp[-2].b))(yyval.info)= (yyvsp[-1].info)	|b100;else (yyval.info)= (yyvsp[-1].info);}
-#line 2743 "parser.c"
+#line 2777 "parser.c"
     break;
 
   case 102: /* leaders: glue_node ltype vbox_node  */
-#line 574 "parser.y"
+#line 576 "parser.y"
                                   {
-	#line 3850 "format.w"
+	#line 3852 "format.w"
 	if((yyvsp[-2].b))(yyval.info)= (yyvsp[-1].info)	|b100;else (yyval.info)= (yyvsp[-1].info);}
-#line 2751 "parser.c"
+#line 2785 "parser.c"
     break;
 
   case 103: /* content_node: start "leaders" leaders ">"  */
-#line 577 "parser.y"
+#line 579 "parser.y"
                                       {
-	#line 3851 "format.w"
+	#line 3853 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(leaders_kind,(yyvsp[-1].info)));}
-#line 2759 "parser.c"
+#line 2793 "parser.c"
     break;
 
   case 104: /* $@5: %empty  */
-#line 581 "parser.y"
+#line 583 "parser.y"
                   {
-	#line 3957 "format.w"
+	#line 3959 "format.w"
 	if((yyvsp[0].d)!=0)HPUT32((yyvsp[0].d));}
-#line 2767 "parser.c"
+#line 2801 "parser.c"
     break;
 
   case 105: /* baseline: dimension $@5 glue_node glue_node  */
-#line 584 "parser.y"
+#line 586 "parser.y"
                    {
-	#line 3958 "format.w"
+	#line 3960 "format.w"
 	(yyval.info)= b000;if((yyvsp[-3].d)!=0)(yyval.info)	|= b001;
 	if((yyvsp[-1].b))(yyval.info)	|= b100;
 	if((yyvsp[0].b))(yyval.info)	|= b010;
 	}
-#line 2778 "parser.c"
+#line 2812 "parser.c"
     break;
 
   case 106: /* content_node: start "baseline" baseline ">"  */
-#line 591 "parser.y"
+#line 593 "parser.y"
 {
-	#line 3963 "format.w"
+	#line 3965 "format.w"
 	if((yyvsp[-1].info)==b000)HPUT8(0);hput_tags((yyvsp[-3].u),TAG(baseline_kind,(yyvsp[-1].info)));}
-#line 2786 "parser.c"
+#line 2820 "parser.c"
     break;
 
   case 108: /* cc_list: cc_list TXT_CC  */
-#line 595 "parser.y"
+#line 597 "parser.y"
                                {
-	#line 4046 "format.w"
+	#line 4048 "format.w"
 	hput_utf8((yyvsp[0].u));}
-#line 2794 "parser.c"
+#line 2828 "parser.c"
     break;
 
   case 109: /* lig_cc: UNSIGNED  */
-#line 598 "parser.y"
+#line 600 "parser.y"
                {
-	#line 4047 "format.w"
+	#line 4049 "format.w"
 	RNG("UTF-8 code",(yyvsp[0].u),0,0x1FFFFF);(yyval.u)= hpos-hstart;hput_utf8((yyvsp[0].u));}
-#line 2802 "parser.c"
+#line 2836 "parser.c"
     break;
 
   case 110: /* lig_cc: CHARCODE  */
-#line 601 "parser.y"
+#line 603 "parser.y"
                {
-	#line 4048 "format.w"
+	#line 4050 "format.w"
 	(yyval.u)= hpos-hstart;hput_utf8((yyvsp[0].u));}
-#line 2810 "parser.c"
+#line 2844 "parser.c"
     break;
 
   case 111: /* ref: REFERENCE  */
-#line 604 "parser.y"
+#line 606 "parser.y"
              {
-	#line 4049 "format.w"
+	#line 4051 "format.w"
 	HPUT8((yyvsp[0].u));(yyval.u)= (yyvsp[0].u);}
-#line 2818 "parser.c"
+#line 2852 "parser.c"
     break;
 
   case 112: /* $@6: %empty  */
-#line 607 "parser.y"
+#line 609 "parser.y"
             {
-	#line 4050 "format.w"
+	#line 4052 "format.w"
 	REF(font_kind,(yyvsp[0].u));}
-#line 2826 "parser.c"
+#line 2860 "parser.c"
     break;
 
   case 113: /* ligature: ref $@6 lig_cc TXT_START cc_list TXT_END  */
-#line 610 "parser.y"
+#line 612 "parser.y"
 {
-	#line 4051 "format.w"
+	#line 4053 "format.w"
 	(yyval.lg).f= (yyvsp[-5].u);(yyval.lg).l.p= (yyvsp[-3].u);(yyval.lg).l.s= (hpos-hstart)-(yyvsp[-3].u);
 	RNG("Ligature size",(yyval.lg).l.s,0,255);}
-#line 2835 "parser.c"
+#line 2869 "parser.c"
     break;
 
   case 114: /* content_node: start "ligature" ligature ">"  */
-#line 614 "parser.y"
+#line 616 "parser.y"
                                         {
-	#line 4053 "format.w"
+	#line 4055 "format.w"
 	hput_tags((yyvsp[-3].u),hput_ligature(&((yyvsp[-1].lg))));}
-#line 2843 "parser.c"
+#line 2877 "parser.c"
     break;
 
   case 115: /* replace_count: explicit  */
-#line 618 "parser.y"
+#line 620 "parser.y"
                       {
-	#line 4163 "format.w"
+	#line 4165 "format.w"
 	if((yyvsp[0].b)){(yyval.u)= 0x80;HPUT8(0x80);}else (yyval.u)= 0x00;}
-#line 2851 "parser.c"
+#line 2885 "parser.c"
     break;
 
   case 116: /* replace_count: explicit UNSIGNED  */
-#line 621 "parser.y"
+#line 623 "parser.y"
                           {
-	#line 4164 "format.w"
+	#line 4166 "format.w"
 	RNG("Replace count",(yyvsp[0].u),0,31);
 	(yyval.u)= ((yyvsp[0].u))	|(((yyvsp[-1].b))?0x80:0x00);if((yyval.u)!=0)HPUT8((yyval.u));}
-#line 2860 "parser.c"
+#line 2894 "parser.c"
     break;
 
   case 117: /* disc: replace_count list list  */
-#line 625 "parser.y"
+#line 627 "parser.y"
                             {
-	#line 4166 "format.w"
+	#line 4168 "format.w"
 	(yyval.dc).r= (yyvsp[-2].u);(yyval.dc).p= (yyvsp[-1].l);(yyval.dc).q= (yyvsp[0].l);
 	if((yyvsp[0].l).s==0){hpos= hpos-3;if((yyvsp[-1].l).s==0)hpos= hpos-3;}}
-#line 2869 "parser.c"
+#line 2903 "parser.c"
     break;
 
   case 118: /* disc: replace_count list  */
-#line 629 "parser.y"
+#line 631 "parser.y"
                            {
-	#line 4168 "format.w"
+	#line 4170 "format.w"
 	(yyval.dc).r= (yyvsp[-1].u);(yyval.dc).p= (yyvsp[0].l);if((yyvsp[0].l).s==0)hpos= hpos-3;(yyval.dc).q.s= 0;}
-#line 2877 "parser.c"
+#line 2911 "parser.c"
     break;
 
   case 119: /* disc: replace_count  */
-#line 632 "parser.y"
+#line 634 "parser.y"
                       {
-	#line 4169 "format.w"
+	#line 4171 "format.w"
 	(yyval.dc).r= (yyvsp[0].u);(yyval.dc).p.s= 0;(yyval.dc).q.s= 0;}
-#line 2885 "parser.c"
+#line 2919 "parser.c"
     break;
 
   case 120: /* disc_node: start "disc" disc ">"  */
-#line 638 "parser.y"
+#line 640 "parser.y"
 {
-	#line 4173 "format.w"
+	#line 4175 "format.w"
 	hput_tags((yyvsp[-3].u),hput_disc(&((yyvsp[-1].dc))));}
-#line 2893 "parser.c"
+#line 2927 "parser.c"
     break;
 
   case 122: /* par_dimen: xdimen  */
-#line 644 "parser.y"
+#line 646 "parser.y"
                 {
-	#line 4325 "format.w"
+	#line 4327 "format.w"
 	hput_xdimen_node(&((yyvsp[0].xd)));}
-#line 2901 "parser.c"
+#line 2935 "parser.c"
     break;
 
   case 123: /* par: xdimen_ref param_ref list  */
-#line 647 "parser.y"
+#line 649 "parser.y"
                              {
-	#line 4326 "format.w"
+	#line 4328 "format.w"
 	(yyval.info)= b000;}
-#line 2909 "parser.c"
+#line 2943 "parser.c"
     break;
 
   case 124: /* par: xdimen_ref param_list list  */
-#line 650 "parser.y"
+#line 652 "parser.y"
                                    {
-	#line 4327 "format.w"
+	#line 4329 "format.w"
 	(yyval.info)= b010;}
-#line 2917 "parser.c"
+#line 2951 "parser.c"
     break;
 
   case 125: /* $@7: %empty  */
-#line 653 "parser.y"
+#line 655 "parser.y"
                          {
-	#line 4328 "format.w"
+	#line 4330 "format.w"
 	hput_xdimen_node(&((yyvsp[-1].xd)));}
-#line 2925 "parser.c"
+#line 2959 "parser.c"
     break;
 
   case 126: /* par: xdimen param_ref $@7 list  */
-#line 655 "parser.y"
+#line 657 "parser.y"
                                      {
-	#line 4328 "format.w"
+	#line 4330 "format.w"
 	(yyval.info)= b100;}
-#line 2933 "parser.c"
+#line 2967 "parser.c"
     break;
 
   case 127: /* par: par_dimen param_list list  */
-#line 658 "parser.y"
+#line 660 "parser.y"
                                   {
-	#line 4329 "format.w"
+	#line 4331 "format.w"
 	(yyval.info)= b110;}
-#line 2941 "parser.c"
+#line 2975 "parser.c"
     break;
 
   case 128: /* content_node: start "par" par ">"  */
-#line 662 "parser.y"
+#line 664 "parser.y"
                               {
-	#line 4331 "format.w"
+	#line 4333 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(par_kind,(yyvsp[-1].info)));}
-#line 2949 "parser.c"
+#line 2983 "parser.c"
     break;
 
   case 129: /* math: param_ref list  */
-#line 666 "parser.y"
+#line 668 "parser.y"
                    {
-	#line 4397 "format.w"
+	#line 4399 "format.w"
 	(yyval.info)= b000;}
-#line 2957 "parser.c"
+#line 2991 "parser.c"
     break;
 
   case 130: /* math: param_ref list hbox_node  */
-#line 669 "parser.y"
+#line 671 "parser.y"
                                  {
-	#line 4398 "format.w"
+	#line 4400 "format.w"
 	(yyval.info)= b001;}
-#line 2965 "parser.c"
+#line 2999 "parser.c"
     break;
 
   case 131: /* math: param_ref hbox_node list  */
-#line 672 "parser.y"
+#line 674 "parser.y"
                                  {
-	#line 4399 "format.w"
+	#line 4401 "format.w"
 	(yyval.info)= b010;}
-#line 2973 "parser.c"
+#line 3007 "parser.c"
     break;
 
   case 132: /* math: param_list list  */
-#line 675 "parser.y"
+#line 677 "parser.y"
                         {
-	#line 4400 "format.w"
+	#line 4402 "format.w"
 	(yyval.info)= b100;}
-#line 2981 "parser.c"
+#line 3015 "parser.c"
     break;
 
   case 133: /* math: param_list list hbox_node  */
-#line 678 "parser.y"
+#line 680 "parser.y"
                                   {
-	#line 4401 "format.w"
+	#line 4403 "format.w"
 	(yyval.info)= b101;}
-#line 2989 "parser.c"
+#line 3023 "parser.c"
     break;
 
   case 134: /* math: param_list hbox_node list  */
-#line 681 "parser.y"
+#line 683 "parser.y"
                                   {
-	#line 4402 "format.w"
+	#line 4404 "format.w"
 	(yyval.info)= b110;}
-#line 2997 "parser.c"
+#line 3031 "parser.c"
     break;
 
   case 135: /* content_node: start "math" math ">"  */
-#line 685 "parser.y"
+#line 687 "parser.y"
                                 {
-	#line 4404 "format.w"
+	#line 4406 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(math_kind,(yyvsp[-1].info)));}
-#line 3005 "parser.c"
+#line 3039 "parser.c"
     break;
 
   case 136: /* on_off: "on"  */
-#line 689 "parser.y"
+#line 691 "parser.y"
          {
-	#line 4454 "format.w"
+	#line 4456 "format.w"
 	(yyval.i)= 1;}
-#line 3013 "parser.c"
+#line 3047 "parser.c"
     break;
 
   case 137: /* on_off: "off"  */
-#line 691 "parser.y"
+#line 693 "parser.y"
                     {
-	#line 4454 "format.w"
+	#line 4456 "format.w"
 	(yyval.i)= 0;}
-#line 3021 "parser.c"
+#line 3055 "parser.c"
     break;
 
   case 138: /* math: on_off  */
-#line 694 "parser.y"
+#line 696 "parser.y"
            {
-	#line 4455 "format.w"
+	#line 4457 "format.w"
 	(yyval.info)= b011	|((yyvsp[0].i)<<2);}
-#line 3029 "parser.c"
+#line 3063 "parser.c"
     break;
 
   case 139: /* content_node: start "adjust" list ">"  */
-#line 698 "parser.y"
+#line 700 "parser.y"
                                   {
-	#line 4486 "format.w"
+	#line 4488 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(adjust_kind,1));}
-#line 3037 "parser.c"
+#line 3071 "parser.c"
     break;
 
   case 140: /* span_count: UNSIGNED  */
-#line 702 "parser.y"
+#line 704 "parser.y"
                    {
-	#line 4585 "format.w"
+	#line 4587 "format.w"
 	(yyval.info)= hput_span_count((yyvsp[0].u));}
-#line 3045 "parser.c"
+#line 3079 "parser.c"
     break;
 
   case 141: /* content_node: start "item" content_node ">"  */
-#line 705 "parser.y"
+#line 707 "parser.y"
                                         {
-	#line 4586 "format.w"
+	#line 4588 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(item_kind,1));}
-#line 3053 "parser.c"
+#line 3087 "parser.c"
     break;
 
   case 142: /* content_node: start "item" span_count content_node ">"  */
-#line 708 "parser.y"
+#line 710 "parser.y"
                                                    {
-	#line 4587 "format.w"
+	#line 4589 "format.w"
 	hput_tags((yyvsp[-4].u),TAG(item_kind,(yyvsp[-2].info)));}
-#line 3061 "parser.c"
+#line 3095 "parser.c"
     break;
 
   case 143: /* content_node: start "item" list ">"  */
-#line 711 "parser.y"
+#line 713 "parser.y"
                                 {
-	#line 4588 "format.w"
+	#line 4590 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(item_kind,b000));}
-#line 3069 "parser.c"
+#line 3103 "parser.c"
     break;
 
   case 144: /* table: "h" box_goal list list  */
-#line 715 "parser.y"
+#line 717 "parser.y"
                           {
-	#line 4590 "format.w"
+	#line 4592 "format.w"
 	(yyval.info)= (yyvsp[-2].info);}
-#line 3077 "parser.c"
+#line 3111 "parser.c"
     break;
 
   case 145: /* table: "v" box_goal list list  */
-#line 718 "parser.y"
+#line 720 "parser.y"
                           {
-	#line 4591 "format.w"
+	#line 4593 "format.w"
 	(yyval.info)= (yyvsp[-2].info)	|b010;}
-#line 3085 "parser.c"
+#line 3119 "parser.c"
     break;
 
   case 146: /* content_node: start "table" table ">"  */
-#line 722 "parser.y"
+#line 724 "parser.y"
                                   {
-	#line 4593 "format.w"
+	#line 4595 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(table_kind,(yyvsp[-1].info)));}
-#line 3093 "parser.c"
+#line 3127 "parser.c"
     break;
 
   case 147: /* image_aspect: number  */
-#line 726 "parser.y"
+#line 728 "parser.y"
                    {
-	#line 4731 "format.w"
+	#line 4733 "format.w"
 	(yyval.f)= (yyvsp[0].f);}
-#line 3101 "parser.c"
+#line 3135 "parser.c"
     break;
 
   case 148: /* image_aspect: %empty  */
-#line 728 "parser.y"
+#line 730 "parser.y"
                          {
-	#line 4731 "format.w"
+	#line 4733 "format.w"
 	(yyval.f)= 0.0;}
-#line 3109 "parser.c"
+#line 3143 "parser.c"
     break;
 
   case 149: /* image_width: "width" xdimen  */
-#line 731 "parser.y"
+#line 733 "parser.y"
                         {
-	#line 4732 "format.w"
+	#line 4734 "format.w"
 	(yyval.xd)= (yyvsp[0].xd);}
-#line 3117 "parser.c"
+#line 3151 "parser.c"
     break;
 
   case 150: /* image_width: %empty  */
-#line 734 "parser.y"
+#line 736 "parser.y"
          {
-	#line 4733 "format.w"
+	#line 4735 "format.w"
 	(yyval.xd)= xdimen_defaults[zero_xdimen_no];}
-#line 3125 "parser.c"
+#line 3159 "parser.c"
     break;
 
   case 151: /* image_height: "height" xdimen  */
-#line 737 "parser.y"
+#line 739 "parser.y"
                           {
-	#line 4734 "format.w"
+	#line 4736 "format.w"
 	(yyval.xd)= (yyvsp[0].xd);}
-#line 3133 "parser.c"
+#line 3167 "parser.c"
     break;
 
   case 152: /* image_height: %empty  */
-#line 740 "parser.y"
+#line 742 "parser.y"
          {
-	#line 4735 "format.w"
+	#line 4737 "format.w"
 	(yyval.xd)= xdimen_defaults[zero_xdimen_no];}
-#line 3141 "parser.c"
+#line 3175 "parser.c"
     break;
 
   case 153: /* image_spec: UNSIGNED image_aspect image_width image_height  */
-#line 745 "parser.y"
+#line 747 "parser.y"
 {
-	#line 4738 "format.w"
+	#line 4740 "format.w"
 	(yyval.info)= hput_image_spec((yyvsp[-3].u),(yyvsp[-2].f),0,&((yyvsp[-1].xd)),0,&((yyvsp[0].xd)));}
-#line 3149 "parser.c"
+#line 3183 "parser.c"
     break;
 
   case 154: /* image_spec: UNSIGNED image_aspect "width" REFERENCE image_height  */
-#line 749 "parser.y"
+#line 751 "parser.y"
 {
-	#line 4740 "format.w"
+	#line 4742 "format.w"
 	(yyval.info)= hput_image_spec((yyvsp[-4].u),(yyvsp[-3].f),(yyvsp[-1].u),NULL,0,&((yyvsp[0].xd)));}
-#line 3157 "parser.c"
+#line 3191 "parser.c"
     break;
 
   case 155: /* image_spec: UNSIGNED image_aspect image_width "height" REFERENCE  */
-#line 753 "parser.y"
+#line 755 "parser.y"
 {
-	#line 4742 "format.w"
+	#line 4744 "format.w"
 	(yyval.info)= hput_image_spec((yyvsp[-4].u),(yyvsp[-3].f),0,&((yyvsp[-2].xd)),(yyvsp[0].u),NULL);}
-#line 3165 "parser.c"
+#line 3199 "parser.c"
     break;
 
   case 156: /* image_spec: UNSIGNED image_aspect "width" REFERENCE "height" REFERENCE  */
-#line 757 "parser.y"
+#line 759 "parser.y"
 {
-	#line 4744 "format.w"
+	#line 4746 "format.w"
 	(yyval.info)= hput_image_spec((yyvsp[-5].u),(yyvsp[-4].f),(yyvsp[-2].u),NULL,(yyvsp[0].u),NULL);}
-#line 3173 "parser.c"
+#line 3207 "parser.c"
     break;
 
   case 157: /* image: image_spec list  */
-#line 761 "parser.y"
+#line 763 "parser.y"
                      {
-	#line 4746 "format.w"
+	#line 4748 "format.w"
 	(yyval.info)= (yyvsp[-1].info);}
-#line 3181 "parser.c"
+#line 3215 "parser.c"
     break;
 
   case 158: /* content_node: start "image" image ">"  */
-#line 765 "parser.y"
+#line 767 "parser.y"
                                   {
-	#line 4748 "format.w"
+	#line 4750 "format.w"
 	hput_tags((yyvsp[-3].u),TAG(image_kind,(yyvsp[-1].info)));}
-#line 3189 "parser.c"
+#line 3223 "parser.c"
     break;
 
   case 159: /* max_value: "outline" UNSIGNED  */
-#line 769 "parser.y"
+#line 771 "parser.y"
                           {
-	#line 5373 "format.w"
+	#line 5383 "format.w"
 	max_outline= (yyvsp[0].u);
 	RNG("max outline",max_outline,0,0xFFFF);
 	DBG(DBGDEF	|DBGLABEL,"Setting max outline to %d\n",max_outline);
 	}
-#line 3200 "parser.c"
+#line 3234 "parser.c"
     break;
 
   case 160: /* placement: "top"  */
-#line 776 "parser.y"
+#line 778 "parser.y"
              {
-	#line 5465 "format.w"
+	#line 5476 "format.w"
 	(yyval.i)= LABEL_TOP;}
-#line 3208 "parser.c"
+#line 3242 "parser.c"
     break;
 
   case 161: /* placement: "bot"  */
-#line 778 "parser.y"
+#line 780 "parser.y"
                             {
-	#line 5465 "format.w"
+	#line 5476 "format.w"
 	(yyval.i)= LABEL_BOT;}
-#line 3216 "parser.c"
+#line 3250 "parser.c"
     break;
 
   case 162: /* placement: "mid"  */
-#line 780 "parser.y"
+#line 782 "parser.y"
                             {
-	#line 5465 "format.w"
+	#line 5476 "format.w"
 	(yyval.i)= LABEL_MID;}
-#line 3224 "parser.c"
+#line 3258 "parser.c"
     break;
 
   case 163: /* placement: %empty  */
-#line 782 "parser.y"
+#line 784 "parser.y"
                          {
-	#line 5465 "format.w"
+	#line 5476 "format.w"
 	(yyval.i)= LABEL_MID;}
-#line 3232 "parser.c"
+#line 3266 "parser.c"
     break;
 
   case 164: /* content_node: "<" "label" REFERENCE placement ">"  */
-#line 786 "parser.y"
+#line 788 "parser.y"
 {
-	#line 5467 "format.w"
+	#line 5478 "format.w"
 	hset_label((yyvsp[-2].u),(yyvsp[-1].i));}
-#line 3240 "parser.c"
+#line 3274 "parser.c"
     break;
 
   case 165: /* content_node: start "link" REFERENCE on_off ">"  */
-#line 791 "parser.y"
+#line 793 "parser.y"
 {
-	#line 5725 "format.w"
-	hput_tags((yyvsp[-4].u),hput_link((yyvsp[-2].u),(yyvsp[-1].i)));}
-#line 3248 "parser.c"
+	#line 5767 "format.w"
+	hput_tags((yyvsp[-4].u),hput_link((yyvsp[-2].u),(yyvsp[-1].i)?1:0xFF,(yyvsp[-1].i)));}
+#line 3282 "parser.c"
     break;
 
-  case 166: /* def_node: "<" "outline" REFERENCE integer position list ">"  */
-#line 795 "parser.y"
+  case 166: /* content_node: start "link" REFERENCE on_off REFERENCE ">"  */
+#line 797 "parser.y"
+{
+	#line 5769 "format.w"
+	hput_tags((yyvsp[-5].u),hput_link((yyvsp[-3].u),(yyvsp[-1].u),(yyvsp[-2].i)));}
+#line 3290 "parser.c"
+    break;
+
+  case 167: /* def_node: "<" "outline" REFERENCE integer position list ">"  */
+#line 801 "parser.y"
                                                           {
-	#line 5855 "format.w"
+	#line 5901 "format.w"
 	
 	static int outline_no= -1;
 	(yyval.rf).k= outline_kind;(yyval.rf).n= (yyvsp[-4].u);
@@ -3258,253 +3300,331 @@
 	outline_no++;
 	hset_outline(outline_no,(yyvsp[-4].u),(yyvsp[-3].i),(yyvsp[-2].u));
 	}
-#line 3262 "parser.c"
+#line 3304 "parser.c"
     break;
 
-  case 167: /* def_node: start "unknown" UNSIGNED UNSIGNED ">"  */
-#line 805 "parser.y"
+  case 168: /* color: "<" UNSIGNED UNSIGNED UNSIGNED UNSIGNED ">"  */
+#line 812 "parser.y"
+{
+	#line 6191 "format.w"
+	RNG("red",(yyvsp[-4].u),0,0xFF);RNG("green",(yyvsp[-3].u),0,0xFF);
+	RNG("blue",(yyvsp[-2].u),0,0xFF);RNG("alpha",(yyvsp[-1].u),0,0xFF);
+	colors_n[colors_i++]= ((yyvsp[-4].u)<<24)	|((yyvsp[-3].u)<<16)	|((yyvsp[-2].u)<<8)	|(yyvsp[-1].u);
+	}
+#line 3315 "parser.c"
+    break;
+
+  case 169: /* color: "<" UNSIGNED UNSIGNED UNSIGNED ">"  */
+#line 819 "parser.y"
+{
+	#line 6196 "format.w"
+	RNG("red",(yyvsp[-3].u),0,0xFF);RNG("green",(yyvsp[-2].u),0,0xFF);
+	RNG("blue",(yyvsp[-1].u),0,0xFF);
+	colors_n[colors_i++]= ((yyvsp[-3].u)<<24)	|((yyvsp[-2].u)<<16)	|((yyvsp[-1].u)<<8)	|0xFF;
+	}
+#line 3326 "parser.c"
+    break;
+
+  case 170: /* color: UNSIGNED  */
+#line 825 "parser.y"
+              {
+	#line 6200 "format.w"
+	colors_n[colors_i++]= (yyvsp[0].u);}
+#line 3334 "parser.c"
+    break;
+
+  case 172: /* color_pair: "<" color ">"  */
+#line 830 "parser.y"
+                        {
+	#line 6210 "format.w"
+	colors_n[colors_i++]= 0;}
+#line 3342 "parser.c"
+    break;
+
+  case 173: /* color_unset: %empty  */
+#line 833 "parser.y"
+            {
+	#line 6211 "format.w"
+	colors_i+= 2;}
+#line 3350 "parser.c"
+    break;
+
+  case 179: /* $@8: %empty  */
+#line 845 "parser.y"
+                        {
+	#line 6241 "format.w"
+	HPUT8(6);color_init();}
+#line 3358 "parser.c"
+    break;
+
+  case 180: /* def_node: start "color" ref $@8 color_set ">"  */
+#line 848 "parser.y"
+{
+	#line 6242 "format.w"
+	DEF((yyval.rf),color_kind,(yyvsp[-3].u));hput_color_def((yyvsp[-5].u),(yyvsp[-3].u));}
+#line 3366 "parser.c"
+    break;
+
+  case 181: /* content_node: start "color" ref ">"  */
+#line 853 "parser.y"
+{
+	#line 6296 "format.w"
+	REF_RNG(color_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(color_kind,b000));}
+#line 3374 "parser.c"
+    break;
+
+  case 182: /* content_node: start "color" "off" ">"  */
+#line 857 "parser.y"
+{
+	#line 6298 "format.w"
+	HPUT8(0xFF);hput_tags((yyvsp[-3].u),TAG(color_kind,b000));}
+#line 3382 "parser.c"
+    break;
+
+  case 183: /* def_node: start "unknown" UNSIGNED UNSIGNED ">"  */
+#line 861 "parser.y"
                                             {
-	#line 6013 "format.w"
+	#line 6426 "format.w"
 	hput_tags((yyvsp[-4].u),hput_unknown_def((yyvsp[-2].u),(yyvsp[-1].u),0));}
-#line 3270 "parser.c"
+#line 3390 "parser.c"
     break;
 
-  case 168: /* def_node: start "unknown" UNSIGNED UNSIGNED UNSIGNED ">"  */
-#line 808 "parser.y"
+  case 184: /* def_node: start "unknown" UNSIGNED UNSIGNED UNSIGNED ">"  */
+#line 864 "parser.y"
                                                      {
-	#line 6014 "format.w"
+	#line 6427 "format.w"
 	hput_tags((yyvsp[-5].u),hput_unknown_def((yyvsp[-3].u),(yyvsp[-2].u),(yyvsp[-1].u)));}
-#line 3278 "parser.c"
+#line 3398 "parser.c"
     break;
 
-  case 169: /* content_node: start "unknown" UNSIGNED unknown_bytes unknown_nodes ">"  */
-#line 812 "parser.y"
+  case 185: /* content_node: start "unknown" UNSIGNED unknown_bytes unknown_nodes ">"  */
+#line 868 "parser.y"
                                                                    {
-	#line 6026 "format.w"
+	#line 6439 "format.w"
 	hput_tags((yyvsp[-5].u),hput_unknown((yyvsp[-5].u),(yyvsp[-3].u),(yyvsp[-2].u),(yyvsp[-1].u)));}
-#line 3286 "parser.c"
+#line 3406 "parser.c"
     break;
 
-  case 170: /* unknown_bytes: %empty  */
-#line 815 "parser.y"
+  case 186: /* unknown_bytes: %empty  */
+#line 871 "parser.y"
               {
-	#line 6027 "format.w"
+	#line 6440 "format.w"
 	(yyval.u)= 0;}
-#line 3294 "parser.c"
+#line 3414 "parser.c"
     break;
 
-  case 171: /* unknown_bytes: unknown_bytes UNSIGNED  */
-#line 817 "parser.y"
+  case 187: /* unknown_bytes: unknown_bytes UNSIGNED  */
+#line 873 "parser.y"
                                        {
-	#line 6027 "format.w"
+	#line 6440 "format.w"
 	RNG("byte",(yyvsp[0].u),0,0xFF);HPUT8((yyvsp[0].u));(yyval.u)= (yyvsp[-1].u)+1;}
-#line 3302 "parser.c"
+#line 3422 "parser.c"
     break;
 
-  case 176: /* unknown_nodes: %empty  */
-#line 821 "parser.y"
+  case 192: /* unknown_nodes: %empty  */
+#line 877 "parser.y"
               {
-	#line 6029 "format.w"
+	#line 6442 "format.w"
 	(yyval.u)= 0;}
-#line 3310 "parser.c"
+#line 3430 "parser.c"
     break;
 
-  case 177: /* unknown_nodes: unknown_nodes unknown_node  */
-#line 823 "parser.y"
+  case 193: /* unknown_nodes: unknown_nodes unknown_node  */
+#line 879 "parser.y"
                                            {
-	#line 6029 "format.w"
+	#line 6442 "format.w"
 	RNG("unknown subnodes",(yyvsp[-1].u),0,3);(yyval.u)= (yyvsp[-1].u)+1;}
-#line 3318 "parser.c"
+#line 3438 "parser.c"
     break;
 
-  case 178: /* stream_link: ref  */
-#line 827 "parser.y"
+  case 194: /* stream_link: ref  */
+#line 883 "parser.y"
                {
-	#line 6464 "format.w"
+	#line 6877 "format.w"
 	REF_RNG(stream_kind,(yyvsp[0].u));}
-#line 3326 "parser.c"
+#line 3446 "parser.c"
     break;
 
-  case 179: /* stream_link: "*"  */
-#line 829 "parser.y"
+  case 195: /* stream_link: "*"  */
+#line 885 "parser.y"
                                                     {
-	#line 6464 "format.w"
+	#line 6877 "format.w"
 	HPUT8(255);}
-#line 3334 "parser.c"
+#line 3454 "parser.c"
     break;
 
-  case 180: /* stream_split: stream_link stream_link UNSIGNED  */
-#line 832 "parser.y"
+  case 196: /* stream_split: stream_link stream_link UNSIGNED  */
+#line 888 "parser.y"
                                              {
-	#line 6465 "format.w"
+	#line 6878 "format.w"
 	RNG("split ratio",(yyvsp[0].u),0,1000);HPUT16((yyvsp[0].u));}
-#line 3342 "parser.c"
+#line 3462 "parser.c"
     break;
 
-  case 181: /* $@8: %empty  */
-#line 835 "parser.y"
+  case 197: /* $@9: %empty  */
+#line 891 "parser.y"
                                 {
-	#line 6466 "format.w"
+	#line 6879 "format.w"
 	RNG("magnification factor",(yyvsp[0].u),0,1000);HPUT16((yyvsp[0].u));}
-#line 3350 "parser.c"
+#line 3470 "parser.c"
     break;
 
-  case 183: /* stream_type: stream_info  */
-#line 839 "parser.y"
+  case 199: /* stream_type: stream_info  */
+#line 895 "parser.y"
                        {
-	#line 6468 "format.w"
+	#line 6881 "format.w"
 	(yyval.info)= 0;}
-#line 3358 "parser.c"
+#line 3478 "parser.c"
     break;
 
-  case 184: /* stream_type: "first"  */
-#line 841 "parser.y"
+  case 200: /* stream_type: "first"  */
+#line 897 "parser.y"
                       {
-	#line 6468 "format.w"
+	#line 6881 "format.w"
 	(yyval.info)= 1;}
-#line 3366 "parser.c"
+#line 3486 "parser.c"
     break;
 
-  case 185: /* stream_type: "last"  */
-#line 843 "parser.y"
+  case 201: /* stream_type: "last"  */
+#line 899 "parser.y"
                      {
-	#line 6468 "format.w"
+	#line 6881 "format.w"
 	(yyval.info)= 2;}
-#line 3374 "parser.c"
+#line 3494 "parser.c"
     break;
 
-  case 186: /* stream_type: "top"  */
-#line 845 "parser.y"
+  case 202: /* stream_type: "top"  */
+#line 901 "parser.y"
                     {
-	#line 6468 "format.w"
+	#line 6881 "format.w"
 	(yyval.info)= 3;}
-#line 3382 "parser.c"
+#line 3502 "parser.c"
     break;
 
-  case 187: /* stream_def_node: start "stream (definition)" ref stream_type list xdimen_node glue_node list glue_node ">"  */
-#line 851 "parser.y"
+  case 203: /* stream_def_node: start "stream (definition)" ref stream_type list xdimen_node glue_node list glue_node ">"  */
+#line 907 "parser.y"
 {
-	#line 6472 "format.w"
+	#line 6885 "format.w"
 	DEF((yyval.rf),stream_kind,(yyvsp[-7].u));hput_tags((yyvsp[-9].u),TAG(stream_kind,(yyvsp[-6].info)	|b100));}
-#line 3390 "parser.c"
+#line 3510 "parser.c"
     break;
 
-  case 188: /* stream_ins_node: start "stream (definition)" ref ">"  */
-#line 856 "parser.y"
+  case 204: /* stream_ins_node: start "stream (definition)" ref ">"  */
+#line 912 "parser.y"
 {
-	#line 6475 "format.w"
+	#line 6888 "format.w"
 	RNG("Stream insertion",(yyvsp[-1].u),0,max_ref[stream_kind]);hput_tags((yyvsp[-3].u),TAG(stream_kind,b100));}
-#line 3398 "parser.c"
+#line 3518 "parser.c"
     break;
 
-  case 191: /* stream: param_list list  */
-#line 862 "parser.y"
+  case 207: /* stream: param_list list  */
+#line 918 "parser.y"
                       {
-	#line 6570 "format.w"
+	#line 6983 "format.w"
 	(yyval.info)= b010;}
-#line 3406 "parser.c"
+#line 3526 "parser.c"
     break;
 
-  case 192: /* stream: param_ref list  */
-#line 865 "parser.y"
+  case 208: /* stream: param_ref list  */
+#line 921 "parser.y"
                        {
-	#line 6571 "format.w"
+	#line 6984 "format.w"
 	(yyval.info)= b000;}
-#line 3414 "parser.c"
+#line 3534 "parser.c"
     break;
 
-  case 193: /* content_node: start "stream" stream_ref stream ">"  */
-#line 869 "parser.y"
+  case 209: /* content_node: start "stream" stream_ref stream ">"  */
+#line 925 "parser.y"
 {
-	#line 6573 "format.w"
+	#line 6986 "format.w"
 	hput_tags((yyvsp[-4].u),TAG(stream_kind,(yyvsp[-1].info)));}
-#line 3422 "parser.c"
+#line 3542 "parser.c"
     break;
 
-  case 194: /* page_priority: %empty  */
-#line 873 "parser.y"
+  case 210: /* page_priority: %empty  */
+#line 929 "parser.y"
               {
-	#line 6676 "format.w"
+	#line 7089 "format.w"
 	HPUT8(1);}
-#line 3430 "parser.c"
+#line 3550 "parser.c"
     break;
 
-  case 195: /* page_priority: UNSIGNED  */
-#line 876 "parser.y"
+  case 211: /* page_priority: UNSIGNED  */
+#line 932 "parser.y"
                  {
-	#line 6677 "format.w"
+	#line 7090 "format.w"
 	RNG("page priority",(yyvsp[0].u),0,255);HPUT8((yyvsp[0].u));}
-#line 3438 "parser.c"
+#line 3558 "parser.c"
     break;
 
-  case 198: /* $@9: %empty  */
-#line 882 "parser.y"
+  case 214: /* $@10: %empty  */
+#line 938 "parser.y"
            {
-	#line 6681 "format.w"
+	#line 7094 "format.w"
 	hput_string((yyvsp[0].s));}
-#line 3446 "parser.c"
+#line 3566 "parser.c"
     break;
 
-  case 199: /* $@10: %empty  */
-#line 884 "parser.y"
+  case 215: /* $@11: %empty  */
+#line 940 "parser.y"
                                                           {
-	#line 6681 "format.w"
+	#line 7094 "format.w"
 	HPUT32((yyvsp[0].d));}
-#line 3454 "parser.c"
+#line 3574 "parser.c"
     break;
 
-  case 201: /* content_node: "<" "range" REFERENCE "on" ">"  */
-#line 891 "parser.y"
+  case 217: /* content_node: "<" "range" REFERENCE "on" ">"  */
+#line 947 "parser.y"
                                          {
-	#line 6794 "format.w"
+	#line 7207 "format.w"
 	REF(page_kind,(yyvsp[-2].u));hput_range((yyvsp[-2].u),true);}
-#line 3462 "parser.c"
+#line 3582 "parser.c"
     break;
 
-  case 202: /* content_node: "<" "range" REFERENCE "off" ">"  */
-#line 894 "parser.y"
+  case 218: /* content_node: "<" "range" REFERENCE "off" ">"  */
+#line 950 "parser.y"
                                       {
-	#line 6795 "format.w"
+	#line 7208 "format.w"
 	REF(page_kind,(yyvsp[-2].u));hput_range((yyvsp[-2].u),false);}
-#line 3470 "parser.c"
+#line 3590 "parser.c"
     break;
 
-  case 204: /* $@11: %empty  */
-#line 900 "parser.y"
+  case 220: /* $@12: %empty  */
+#line 956 "parser.y"
                                           {
-	#line 7493 "format.w"
+	#line 7906 "format.w"
 	new_directory((yyvsp[0].u)+1);new_output_buffers();}
-#line 3478 "parser.c"
+#line 3598 "parser.c"
     break;
 
-  case 208: /* entry: "<" "entry" UNSIGNED string ">"  */
-#line 905 "parser.y"
+  case 224: /* entry: "<" "entry" UNSIGNED string ">"  */
+#line 961 "parser.y"
 {
-	#line 7496 "format.w"
+	#line 7909 "format.w"
 	RNG("Section number",(yyvsp[-2].u),3,max_section_no);hset_entry(&(dir[(yyvsp[-2].u)]),(yyvsp[-2].u),0,0,(yyvsp[-1].s));}
-#line 3486 "parser.c"
+#line 3606 "parser.c"
     break;
 
-  case 209: /* $@12: %empty  */
-#line 909 "parser.y"
+  case 225: /* $@13: %empty  */
+#line 965 "parser.y"
                                     {
-	#line 8039 "format.w"
+	#line 8453 "format.w"
 	hput_definitions_start();}
-#line 3494 "parser.c"
+#line 3614 "parser.c"
     break;
 
-  case 210: /* definition_section: "<" "definitions" $@12 max_definitions definition_list ">"  */
-#line 913 "parser.y"
+  case 226: /* definition_section: "<" "definitions" $@13 max_definitions definition_list ">"  */
+#line 969 "parser.y"
    {
-	#line 8041 "format.w"
+	#line 8455 "format.w"
 	hput_definitions_end();}
-#line 3502 "parser.c"
+#line 3622 "parser.c"
     break;
 
-  case 213: /* max_definitions: "<" "max" max_list ">"  */
-#line 919 "parser.y"
+  case 229: /* max_definitions: "<" "max" max_list ">"  */
+#line 975 "parser.y"
 {
-	#line 8157 "format.w"
+	#line 8571 "format.w"
 		/*253:*/
 	if(max_ref[label_kind]>=0)
 	ALLOCATE(labels,max_ref[label_kind]+1,Label);
@@ -3511,10 +3631,15 @@
 		/*:253*/	/*274:*/
 	if(max_outline>=0)
 	ALLOCATE(outlines,max_outline+1,Outline);
-		/*:274*/	/*310:*/
+		/*:274*/	/*290:*/
+	{int i;
+	for(i= 0;i<sizeof(ColorSet)/4;i++)
+	colors_0[i]= color_defaults[0][i];
+	}
+		/*:290*/	/*325:*/
 	ALLOCATE(page_on,max_ref[page_kind]+1,int);
 	ALLOCATE(range_pos,2*(max_ref[range_kind]+1),RangePos);
-		/*:310*/	/*376:*/
+		/*:325*/	/*391:*/
 	definition_bits[0][list_kind]= (1<<(MAX_LIST_DEFAULT+1))-1;
 	definition_bits[0][param_kind]= (1<<(MAX_LIST_DEFAULT+1))-1;
 	definition_bits[0][int_kind]= (1<<(MAX_INT_DEFAULT+1))-1;
@@ -3525,536 +3650,545 @@
 	definition_bits[0][page_kind]= (1<<(MAX_PAGE_DEFAULT+1))-1;
 	definition_bits[0][stream_kind]= (1<<(MAX_STREAM_DEFAULT+1))-1;
 	definition_bits[0][range_kind]= (1<<(MAX_RANGE_DEFAULT+1))-1;
-		/*:376*/	/*391:*/
+	definition_bits[0][color_kind]= (1<<(MAX_COLOR_DEFAULT+1))-1;
+		/*:391*/	/*406:*/
 	ALLOCATE(hfont_name,max_ref[font_kind]+1,char*);
-		/*:391*/hput_max_definitions();}
-#line 3532 "parser.c"
+		/*:406*/hput_max_definitions();}
+#line 3658 "parser.c"
     break;
 
-  case 216: /* max_value: "font" UNSIGNED  */
-#line 947 "parser.y"
+  case 232: /* max_value: "font" UNSIGNED  */
+#line 1009 "parser.y"
                        {
-	#line 8161 "format.w"
+	#line 8575 "format.w"
 	hset_max(font_kind,(yyvsp[0].u));}
-#line 3540 "parser.c"
+#line 3666 "parser.c"
     break;
 
-  case 217: /* max_value: "int" UNSIGNED  */
-#line 950 "parser.y"
+  case 233: /* max_value: "int" UNSIGNED  */
+#line 1012 "parser.y"
                          {
-	#line 8162 "format.w"
+	#line 8576 "format.w"
 	hset_max(int_kind,(yyvsp[0].u));}
-#line 3548 "parser.c"
+#line 3674 "parser.c"
     break;
 
-  case 218: /* max_value: "dimen" UNSIGNED  */
-#line 953 "parser.y"
+  case 234: /* max_value: "dimen" UNSIGNED  */
+#line 1015 "parser.y"
                        {
-	#line 8163 "format.w"
+	#line 8577 "format.w"
 	hset_max(dimen_kind,(yyvsp[0].u));}
-#line 3556 "parser.c"
+#line 3682 "parser.c"
     break;
 
-  case 219: /* max_value: "ligature" UNSIGNED  */
-#line 956 "parser.y"
+  case 235: /* max_value: "ligature" UNSIGNED  */
+#line 1018 "parser.y"
                           {
-	#line 8164 "format.w"
+	#line 8578 "format.w"
 	hset_max(ligature_kind,(yyvsp[0].u));}
-#line 3564 "parser.c"
+#line 3690 "parser.c"
     break;
 
-  case 220: /* max_value: "disc" UNSIGNED  */
-#line 959 "parser.y"
+  case 236: /* max_value: "disc" UNSIGNED  */
+#line 1021 "parser.y"
                       {
-	#line 8165 "format.w"
+	#line 8579 "format.w"
 	hset_max(disc_kind,(yyvsp[0].u));}
-#line 3572 "parser.c"
+#line 3698 "parser.c"
     break;
 
-  case 221: /* max_value: "glue" UNSIGNED  */
-#line 962 "parser.y"
+  case 237: /* max_value: "glue" UNSIGNED  */
+#line 1024 "parser.y"
                       {
-	#line 8166 "format.w"
+	#line 8580 "format.w"
 	hset_max(glue_kind,(yyvsp[0].u));}
-#line 3580 "parser.c"
+#line 3706 "parser.c"
     break;
 
-  case 222: /* max_value: "language" UNSIGNED  */
-#line 965 "parser.y"
+  case 238: /* max_value: "language" UNSIGNED  */
+#line 1027 "parser.y"
                           {
-	#line 8167 "format.w"
+	#line 8581 "format.w"
 	hset_max(language_kind,(yyvsp[0].u));}
-#line 3588 "parser.c"
+#line 3714 "parser.c"
     break;
 
-  case 223: /* max_value: "rule" UNSIGNED  */
-#line 968 "parser.y"
+  case 239: /* max_value: "rule" UNSIGNED  */
+#line 1030 "parser.y"
                       {
-	#line 8168 "format.w"
+	#line 8582 "format.w"
 	hset_max(rule_kind,(yyvsp[0].u));}
-#line 3596 "parser.c"
+#line 3722 "parser.c"
     break;
 
-  case 224: /* max_value: "image" UNSIGNED  */
-#line 971 "parser.y"
+  case 240: /* max_value: "image" UNSIGNED  */
+#line 1033 "parser.y"
                        {
-	#line 8169 "format.w"
+	#line 8583 "format.w"
 	hset_max(image_kind,(yyvsp[0].u));}
-#line 3604 "parser.c"
+#line 3730 "parser.c"
     break;
 
-  case 225: /* max_value: "leaders" UNSIGNED  */
-#line 974 "parser.y"
+  case 241: /* max_value: "leaders" UNSIGNED  */
+#line 1036 "parser.y"
                          {
-	#line 8170 "format.w"
+	#line 8584 "format.w"
 	hset_max(leaders_kind,(yyvsp[0].u));}
-#line 3612 "parser.c"
+#line 3738 "parser.c"
     break;
 
-  case 226: /* max_value: "baseline" UNSIGNED  */
-#line 977 "parser.y"
+  case 242: /* max_value: "baseline" UNSIGNED  */
+#line 1039 "parser.y"
                           {
-	#line 8171 "format.w"
+	#line 8585 "format.w"
 	hset_max(baseline_kind,(yyvsp[0].u));}
-#line 3620 "parser.c"
+#line 3746 "parser.c"
     break;
 
-  case 227: /* max_value: "xdimen" UNSIGNED  */
-#line 980 "parser.y"
+  case 243: /* max_value: "xdimen" UNSIGNED  */
+#line 1042 "parser.y"
                         {
-	#line 8172 "format.w"
+	#line 8586 "format.w"
 	hset_max(xdimen_kind,(yyvsp[0].u));}
-#line 3628 "parser.c"
+#line 3754 "parser.c"
     break;
 
-  case 228: /* max_value: "param" UNSIGNED  */
-#line 983 "parser.y"
+  case 244: /* max_value: "param" UNSIGNED  */
+#line 1045 "parser.y"
                        {
-	#line 8173 "format.w"
+	#line 8587 "format.w"
 	hset_max(param_kind,(yyvsp[0].u));}
-#line 3636 "parser.c"
+#line 3762 "parser.c"
     break;
 
-  case 229: /* max_value: "stream (definition)" UNSIGNED  */
-#line 986 "parser.y"
+  case 245: /* max_value: "stream (definition)" UNSIGNED  */
+#line 1048 "parser.y"
                            {
-	#line 8174 "format.w"
+	#line 8588 "format.w"
 	hset_max(stream_kind,(yyvsp[0].u));}
-#line 3644 "parser.c"
+#line 3770 "parser.c"
     break;
 
-  case 230: /* max_value: "page" UNSIGNED  */
-#line 989 "parser.y"
+  case 246: /* max_value: "page" UNSIGNED  */
+#line 1051 "parser.y"
                       {
-	#line 8175 "format.w"
+	#line 8589 "format.w"
 	hset_max(page_kind,(yyvsp[0].u));}
-#line 3652 "parser.c"
+#line 3778 "parser.c"
     break;
 
-  case 231: /* max_value: "range" UNSIGNED  */
-#line 992 "parser.y"
+  case 247: /* max_value: "range" UNSIGNED  */
+#line 1054 "parser.y"
                        {
-	#line 8176 "format.w"
+	#line 8590 "format.w"
 	hset_max(range_kind,(yyvsp[0].u));}
-#line 3660 "parser.c"
+#line 3786 "parser.c"
     break;
 
-  case 232: /* max_value: "label" UNSIGNED  */
-#line 995 "parser.y"
+  case 248: /* max_value: "label" UNSIGNED  */
+#line 1057 "parser.y"
                        {
-	#line 8177 "format.w"
+	#line 8591 "format.w"
 	hset_max(label_kind,(yyvsp[0].u));}
-#line 3668 "parser.c"
+#line 3794 "parser.c"
     break;
 
-  case 233: /* def_node: start "font" ref font ">"  */
-#line 1001 "parser.y"
+  case 249: /* max_value: "color" UNSIGNED  */
+#line 1060 "parser.y"
                        {
-	#line 8377 "format.w"
+	#line 8592 "format.w"
+	hset_max(color_kind,(yyvsp[0].u));}
+#line 3802 "parser.c"
+    break;
+
+  case 250: /* def_node: start "font" ref font ">"  */
+#line 1066 "parser.y"
+                       {
+	#line 8794 "format.w"
 	DEF((yyval.rf),font_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),(yyvsp[-1].info));}
-#line 3676 "parser.c"
+#line 3810 "parser.c"
     break;
 
-  case 234: /* def_node: start "int" ref integer ">"  */
-#line 1004 "parser.y"
+  case 251: /* def_node: start "int" ref integer ">"  */
+#line 1069 "parser.y"
                                       {
-	#line 8378 "format.w"
+	#line 8795 "format.w"
 	DEF((yyval.rf),int_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_int((yyvsp[-1].i)));}
-#line 3684 "parser.c"
+#line 3818 "parser.c"
     break;
 
-  case 235: /* def_node: start "dimen" ref dimension ">"  */
-#line 1007 "parser.y"
+  case 252: /* def_node: start "dimen" ref dimension ">"  */
+#line 1072 "parser.y"
                                       {
-	#line 8379 "format.w"
+	#line 8796 "format.w"
 	DEF((yyval.rf),dimen_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_dimen((yyvsp[-1].d)));}
-#line 3692 "parser.c"
+#line 3826 "parser.c"
     break;
 
-  case 236: /* def_node: start "language" ref string ">"  */
-#line 1010 "parser.y"
+  case 253: /* def_node: start "language" ref string ">"  */
+#line 1075 "parser.y"
                                       {
-	#line 8380 "format.w"
+	#line 8797 "format.w"
 	DEF((yyval.rf),language_kind,(yyvsp[-2].u));hput_string((yyvsp[-1].s));hput_tags((yyvsp[-4].u),TAG(language_kind,0));}
-#line 3700 "parser.c"
+#line 3834 "parser.c"
     break;
 
-  case 237: /* def_node: start "glue" ref glue ">"  */
-#line 1013 "parser.y"
+  case 254: /* def_node: start "glue" ref glue ">"  */
+#line 1078 "parser.y"
                                 {
-	#line 8381 "format.w"
+	#line 8798 "format.w"
 	DEF((yyval.rf),glue_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_glue(&((yyvsp[-1].g))));}
-#line 3708 "parser.c"
+#line 3842 "parser.c"
     break;
 
-  case 238: /* def_node: start "xdimen" ref xdimen ">"  */
-#line 1016 "parser.y"
+  case 255: /* def_node: start "xdimen" ref xdimen ">"  */
+#line 1081 "parser.y"
                                     {
-	#line 8382 "format.w"
+	#line 8799 "format.w"
 	DEF((yyval.rf),xdimen_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_xdimen(&((yyvsp[-1].xd))));}
-#line 3716 "parser.c"
+#line 3850 "parser.c"
     break;
 
-  case 239: /* def_node: start "rule" ref rule ">"  */
-#line 1019 "parser.y"
+  case 256: /* def_node: start "rule" ref rule ">"  */
+#line 1084 "parser.y"
                                 {
-	#line 8383 "format.w"
+	#line 8800 "format.w"
 	DEF((yyval.rf),rule_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_rule(&((yyvsp[-1].r))));}
-#line 3724 "parser.c"
+#line 3858 "parser.c"
     break;
 
-  case 240: /* def_node: start "leaders" ref leaders ">"  */
-#line 1022 "parser.y"
+  case 257: /* def_node: start "leaders" ref leaders ">"  */
+#line 1087 "parser.y"
                                       {
-	#line 8384 "format.w"
+	#line 8801 "format.w"
 	DEF((yyval.rf),leaders_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),TAG(leaders_kind,(yyvsp[-1].info)));}
-#line 3732 "parser.c"
+#line 3866 "parser.c"
     break;
 
-  case 241: /* def_node: start "baseline" ref baseline ">"  */
-#line 1025 "parser.y"
+  case 258: /* def_node: start "baseline" ref baseline ">"  */
+#line 1090 "parser.y"
                                         {
-	#line 8385 "format.w"
+	#line 8802 "format.w"
 	DEF((yyval.rf),baseline_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),TAG(baseline_kind,(yyvsp[-1].info)));}
-#line 3740 "parser.c"
+#line 3874 "parser.c"
     break;
 
-  case 242: /* def_node: start "ligature" ref ligature ">"  */
-#line 1028 "parser.y"
+  case 259: /* def_node: start "ligature" ref ligature ">"  */
+#line 1093 "parser.y"
                                         {
-	#line 8386 "format.w"
+	#line 8803 "format.w"
 	DEF((yyval.rf),ligature_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_ligature(&((yyvsp[-1].lg))));}
-#line 3748 "parser.c"
+#line 3882 "parser.c"
     break;
 
-  case 243: /* def_node: start "disc" ref disc ">"  */
-#line 1031 "parser.y"
+  case 260: /* def_node: start "disc" ref disc ">"  */
+#line 1096 "parser.y"
                                 {
-	#line 8387 "format.w"
+	#line 8804 "format.w"
 	DEF((yyval.rf),disc_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_disc(&((yyvsp[-1].dc))));}
-#line 3756 "parser.c"
+#line 3890 "parser.c"
     break;
 
-  case 244: /* def_node: start "image" ref image ">"  */
-#line 1034 "parser.y"
+  case 261: /* def_node: start "image" ref image ">"  */
+#line 1099 "parser.y"
                                   {
-	#line 8388 "format.w"
+	#line 8805 "format.w"
 	DEF((yyval.rf),image_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),TAG(image_kind,(yyvsp[-1].info)));}
-#line 3764 "parser.c"
+#line 3898 "parser.c"
     break;
 
-  case 245: /* def_node: start "param" ref parameters ">"  */
-#line 1037 "parser.y"
+  case 262: /* def_node: start "param" ref parameters ">"  */
+#line 1102 "parser.y"
                                        {
-	#line 8389 "format.w"
+	#line 8806 "format.w"
 	DEF((yyval.rf),param_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),hput_list((yyvsp[-4].u)+2,&((yyvsp[-1].l))));}
-#line 3772 "parser.c"
+#line 3906 "parser.c"
     break;
 
-  case 246: /* def_node: start "page" ref page ">"  */
-#line 1040 "parser.y"
+  case 263: /* def_node: start "page" ref page ">"  */
+#line 1105 "parser.y"
                                 {
-	#line 8390 "format.w"
+	#line 8807 "format.w"
 	DEF((yyval.rf),page_kind,(yyvsp[-2].u));hput_tags((yyvsp[-4].u),TAG(page_kind,0));}
-#line 3780 "parser.c"
+#line 3914 "parser.c"
     break;
 
-  case 247: /* def_node: start "int" ref ref ">"  */
-#line 1045 "parser.y"
+  case 264: /* def_node: start "int" ref ref ">"  */
+#line 1110 "parser.y"
                          {
-	#line 8409 "format.w"
+	#line 8826 "format.w"
 	DEF_REF((yyval.rf),int_kind,(yyvsp[-2].u),(yyvsp[-1].u));hput_tags((yyvsp[-4].u),TAG(int_kind,0));}
-#line 3788 "parser.c"
+#line 3922 "parser.c"
     break;
 
-  case 248: /* def_node: start "dimen" ref ref ">"  */
-#line 1048 "parser.y"
+  case 265: /* def_node: start "dimen" ref ref ">"  */
+#line 1113 "parser.y"
                                 {
-	#line 8410 "format.w"
+	#line 8827 "format.w"
 	DEF_REF((yyval.rf),dimen_kind,(yyvsp[-2].u),(yyvsp[-1].u));hput_tags((yyvsp[-4].u),TAG(dimen_kind,0));}
-#line 3796 "parser.c"
+#line 3930 "parser.c"
     break;
 
-  case 249: /* def_node: start "glue" ref ref ">"  */
-#line 1051 "parser.y"
+  case 266: /* def_node: start "glue" ref ref ">"  */
+#line 1116 "parser.y"
                                {
-	#line 8411 "format.w"
+	#line 8828 "format.w"
 	DEF_REF((yyval.rf),glue_kind,(yyvsp[-2].u),(yyvsp[-1].u));hput_tags((yyvsp[-4].u),TAG(glue_kind,0));}
-#line 3804 "parser.c"
+#line 3938 "parser.c"
     break;
 
-  case 251: /* def_list: def_list def_node  */
-#line 1056 "parser.y"
+  case 268: /* def_list: def_list def_node  */
+#line 1121 "parser.y"
                           {
-	#line 8527 "format.w"
+	#line 8951 "format.w"
 	check_param_def(&((yyvsp[0].rf)));}
-#line 3812 "parser.c"
+#line 3946 "parser.c"
     break;
 
-  case 252: /* parameters: estimate def_list  */
-#line 1059 "parser.y"
+  case 269: /* parameters: estimate def_list  */
+#line 1124 "parser.y"
                             {
-	#line 8528 "format.w"
+	#line 8952 "format.w"
 	(yyval.l).p= (yyvsp[0].u);(yyval.l).t= TAG(param_kind,b001);(yyval.l).s= (hpos-hstart)-(yyvsp[0].u);}
-#line 3820 "parser.c"
+#line 3954 "parser.c"
     break;
 
-  case 253: /* named_param_list: start "param" parameters ">"  */
-#line 1064 "parser.y"
+  case 270: /* named_param_list: start "param" parameters ">"  */
+#line 1129 "parser.y"
 {
-	#line 8541 "format.w"
+	#line 8965 "format.w"
 	hput_tags((yyvsp[-3].u),hput_list((yyvsp[-3].u)+1,&((yyvsp[-1].l))));}
-#line 3828 "parser.c"
+#line 3962 "parser.c"
     break;
 
-  case 255: /* param_list: start parameters ">"  */
-#line 1068 "parser.y"
+  case 272: /* param_list: start parameters ">"  */
+#line 1133 "parser.y"
 {
-	#line 8543 "format.w"
+	#line 8967 "format.w"
 	hput_tags((yyvsp[-2].u),hput_list((yyvsp[-2].u)+1,&((yyvsp[-1].l))));}
-#line 3836 "parser.c"
+#line 3970 "parser.c"
     break;
 
-  case 257: /* font_head: string dimension UNSIGNED UNSIGNED  */
-#line 1076 "parser.y"
+  case 274: /* font_head: string dimension UNSIGNED UNSIGNED  */
+#line 1141 "parser.y"
 {
-	#line 8689 "format.w"
+	#line 9113 "format.w"
 	uint8_t f= (yyvsp[-4].u);SET_DBIT(f,font_kind);hfont_name[f]= strdup((yyvsp[-3].s));(yyval.info)= hput_font_head(f,hfont_name[f],(yyvsp[-2].d),(yyvsp[-1].u),(yyvsp[0].u));}
-#line 3844 "parser.c"
+#line 3978 "parser.c"
     break;
 
-  case 260: /* font_param: start "penalty" fref penalty ">"  */
-#line 1083 "parser.y"
+  case 277: /* font_param: start "penalty" fref penalty ">"  */
+#line 1148 "parser.y"
                               {
-	#line 8694 "format.w"
+	#line 9118 "format.w"
 	hput_tags((yyvsp[-4].u),hput_int((yyvsp[-1].i)));}
-#line 3852 "parser.c"
+#line 3986 "parser.c"
     break;
 
-  case 261: /* font_param: start "kern" fref kern ">"  */
-#line 1086 "parser.y"
+  case 278: /* font_param: start "kern" fref kern ">"  */
+#line 1151 "parser.y"
                                  {
-	#line 8695 "format.w"
+	#line 9119 "format.w"
 	hput_tags((yyvsp[-4].u),hput_kern(&((yyvsp[-1].kt))));}
-#line 3860 "parser.c"
+#line 3994 "parser.c"
     break;
 
-  case 262: /* font_param: start "ligature" fref ligature ">"  */
-#line 1089 "parser.y"
+  case 279: /* font_param: start "ligature" fref ligature ">"  */
+#line 1154 "parser.y"
                                          {
-	#line 8696 "format.w"
+	#line 9120 "format.w"
 	hput_tags((yyvsp[-4].u),hput_ligature(&((yyvsp[-1].lg))));}
-#line 3868 "parser.c"
+#line 4002 "parser.c"
     break;
 
-  case 263: /* font_param: start "disc" fref disc ">"  */
-#line 1092 "parser.y"
+  case 280: /* font_param: start "disc" fref disc ">"  */
+#line 1157 "parser.y"
                                  {
-	#line 8697 "format.w"
+	#line 9121 "format.w"
 	hput_tags((yyvsp[-4].u),hput_disc(&((yyvsp[-1].dc))));}
-#line 3876 "parser.c"
+#line 4010 "parser.c"
     break;
 
-  case 264: /* font_param: start "glue" fref glue ">"  */
-#line 1095 "parser.y"
+  case 281: /* font_param: start "glue" fref glue ">"  */
+#line 1160 "parser.y"
                                  {
-	#line 8698 "format.w"
+	#line 9122 "format.w"
 	hput_tags((yyvsp[-4].u),hput_glue(&((yyvsp[-1].g))));}
-#line 3884 "parser.c"
+#line 4018 "parser.c"
     break;
 
-  case 265: /* font_param: start "language" fref string ">"  */
-#line 1098 "parser.y"
+  case 282: /* font_param: start "language" fref string ">"  */
+#line 1163 "parser.y"
                                        {
-	#line 8699 "format.w"
+	#line 9123 "format.w"
 	hput_string((yyvsp[-1].s));hput_tags((yyvsp[-4].u),TAG(language_kind,0));}
-#line 3892 "parser.c"
+#line 4026 "parser.c"
     break;
 
-  case 266: /* font_param: start "rule" fref rule ">"  */
-#line 1101 "parser.y"
+  case 283: /* font_param: start "rule" fref rule ">"  */
+#line 1166 "parser.y"
                                  {
-	#line 8700 "format.w"
+	#line 9124 "format.w"
 	hput_tags((yyvsp[-4].u),hput_rule(&((yyvsp[-1].r))));}
-#line 3900 "parser.c"
+#line 4034 "parser.c"
     break;
 
-  case 267: /* font_param: start "image" fref image ">"  */
-#line 1104 "parser.y"
+  case 284: /* font_param: start "image" fref image ">"  */
+#line 1169 "parser.y"
                                    {
-	#line 8701 "format.w"
+	#line 9125 "format.w"
 	hput_tags((yyvsp[-4].u),TAG(image_kind,(yyvsp[-1].info)));}
-#line 3908 "parser.c"
+#line 4042 "parser.c"
     break;
 
-  case 268: /* fref: ref  */
-#line 1108 "parser.y"
+  case 285: /* fref: ref  */
+#line 1173 "parser.y"
         {
-	#line 8703 "format.w"
+	#line 9127 "format.w"
 	RNG("Font parameter",(yyvsp[0].u),0,MAX_FONT_PARAMS);}
-#line 3916 "parser.c"
+#line 4050 "parser.c"
     break;
 
-  case 269: /* xdimen_ref: ref  */
-#line 1112 "parser.y"
+  case 286: /* xdimen_ref: ref  */
+#line 1177 "parser.y"
               {
-	#line 8780 "format.w"
+	#line 9204 "format.w"
 	REF(xdimen_kind,(yyvsp[0].u));}
-#line 3924 "parser.c"
+#line 4058 "parser.c"
     break;
 
-  case 270: /* param_ref: ref  */
-#line 1115 "parser.y"
+  case 287: /* param_ref: ref  */
+#line 1180 "parser.y"
              {
-	#line 8781 "format.w"
+	#line 9205 "format.w"
 	REF(param_kind,(yyvsp[0].u));}
-#line 3932 "parser.c"
+#line 4066 "parser.c"
     break;
 
-  case 271: /* stream_ref: ref  */
-#line 1118 "parser.y"
+  case 288: /* stream_ref: ref  */
+#line 1183 "parser.y"
               {
-	#line 8782 "format.w"
+	#line 9206 "format.w"
 	REF_RNG(stream_kind,(yyvsp[0].u));}
-#line 3940 "parser.c"
+#line 4074 "parser.c"
     break;
 
-  case 272: /* content_node: start "penalty" ref ">"  */
-#line 1124 "parser.y"
+  case 289: /* content_node: start "penalty" ref ">"  */
+#line 1189 "parser.y"
                      {
-	#line 8786 "format.w"
+	#line 9210 "format.w"
 	REF(penalty_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(penalty_kind,0));}
-#line 3948 "parser.c"
+#line 4082 "parser.c"
     break;
 
-  case 273: /* content_node: start "kern" explicit ref ">"  */
-#line 1128 "parser.y"
+  case 290: /* content_node: start "kern" explicit ref ">"  */
+#line 1193 "parser.y"
 {
-	#line 8788 "format.w"
+	#line 9212 "format.w"
 	REF(dimen_kind,(yyvsp[-1].u));hput_tags((yyvsp[-4].u),TAG(kern_kind,((yyvsp[-2].b))?b100:b000));}
-#line 3956 "parser.c"
+#line 4090 "parser.c"
     break;
 
-  case 274: /* content_node: start "kern" explicit "xdimen" ref ">"  */
-#line 1132 "parser.y"
+  case 291: /* content_node: start "kern" explicit "xdimen" ref ">"  */
+#line 1197 "parser.y"
 {
-	#line 8790 "format.w"
+	#line 9214 "format.w"
 	REF(xdimen_kind,(yyvsp[-1].u));hput_tags((yyvsp[-5].u),TAG(kern_kind,((yyvsp[-3].b))?b101:b001));}
-#line 3964 "parser.c"
+#line 4098 "parser.c"
     break;
 
-  case 275: /* content_node: start "glue" ref ">"  */
-#line 1135 "parser.y"
+  case 292: /* content_node: start "glue" ref ">"  */
+#line 1200 "parser.y"
                            {
-	#line 8791 "format.w"
+	#line 9215 "format.w"
 	REF(glue_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(glue_kind,0));}
-#line 3972 "parser.c"
+#line 4106 "parser.c"
     break;
 
-  case 276: /* content_node: start "ligature" ref ">"  */
-#line 1138 "parser.y"
+  case 293: /* content_node: start "ligature" ref ">"  */
+#line 1203 "parser.y"
                                {
-	#line 8792 "format.w"
+	#line 9216 "format.w"
 	REF(ligature_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(ligature_kind,0));}
-#line 3980 "parser.c"
+#line 4114 "parser.c"
     break;
 
-  case 277: /* content_node: start "disc" ref ">"  */
-#line 1141 "parser.y"
+  case 294: /* content_node: start "disc" ref ">"  */
+#line 1206 "parser.y"
                            {
-	#line 8793 "format.w"
+	#line 9217 "format.w"
 	REF(disc_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(disc_kind,0));}
-#line 3988 "parser.c"
+#line 4122 "parser.c"
     break;
 
-  case 278: /* content_node: start "rule" ref ">"  */
-#line 1144 "parser.y"
+  case 295: /* content_node: start "rule" ref ">"  */
+#line 1209 "parser.y"
                            {
-	#line 8794 "format.w"
+	#line 9218 "format.w"
 	REF(rule_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(rule_kind,0));}
-#line 3996 "parser.c"
+#line 4130 "parser.c"
     break;
 
-  case 279: /* content_node: start "image" ref ">"  */
-#line 1147 "parser.y"
+  case 296: /* content_node: start "image" ref ">"  */
+#line 1212 "parser.y"
                             {
-	#line 8795 "format.w"
+	#line 9219 "format.w"
 	REF(image_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(image_kind,0));}
-#line 4004 "parser.c"
+#line 4138 "parser.c"
     break;
 
-  case 280: /* content_node: start "leaders" ref ">"  */
-#line 1150 "parser.y"
+  case 297: /* content_node: start "leaders" ref ">"  */
+#line 1215 "parser.y"
                               {
-	#line 8796 "format.w"
+	#line 9220 "format.w"
 	REF(leaders_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(leaders_kind,0));}
-#line 4012 "parser.c"
+#line 4146 "parser.c"
     break;
 
-  case 281: /* content_node: start "baseline" ref ">"  */
-#line 1153 "parser.y"
+  case 298: /* content_node: start "baseline" ref ">"  */
+#line 1218 "parser.y"
                                {
-	#line 8797 "format.w"
+	#line 9221 "format.w"
 	REF(baseline_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),TAG(baseline_kind,0));}
-#line 4020 "parser.c"
+#line 4154 "parser.c"
     break;
 
-  case 282: /* content_node: start "language" REFERENCE ">"  */
-#line 1156 "parser.y"
+  case 299: /* content_node: start "language" REFERENCE ">"  */
+#line 1221 "parser.y"
                                      {
-	#line 8798 "format.w"
+	#line 9222 "format.w"
 	REF(language_kind,(yyvsp[-1].u));hput_tags((yyvsp[-3].u),hput_language((yyvsp[-1].u)));}
-#line 4028 "parser.c"
+#line 4162 "parser.c"
     break;
 
-  case 283: /* glue_node: start "glue" ref ">"  */
-#line 1160 "parser.y"
+  case 300: /* glue_node: start "glue" ref ">"  */
+#line 1225 "parser.y"
                             {
-	#line 8800 "format.w"
+	#line 9224 "format.w"
 	REF(glue_kind,(yyvsp[-1].u));
 	if((yyvsp[-1].u)==zero_skip_no){hpos= hpos-2;(yyval.b)= false;}
 	else{hput_tags((yyvsp[-3].u),TAG(glue_kind,0));(yyval.b)= true;}}
-#line 4038 "parser.c"
+#line 4172 "parser.c"
     break;
 
-  case 284: /* $@13: %empty  */
-#line 1167 "parser.y"
+  case 301: /* $@14: %empty  */
+#line 1232 "parser.y"
                              {
-	#line 9247 "format.w"
+	#line 9710 "format.w"
 	hput_content_start();}
-#line 4046 "parser.c"
+#line 4180 "parser.c"
     break;
 
-  case 285: /* content_section: "<" "content" $@13 content_list ">"  */
-#line 1170 "parser.y"
+  case 302: /* content_section: "<" "content" $@14 content_list ">"  */
+#line 1235 "parser.y"
 {
-	#line 9248 "format.w"
+	#line 9711 "format.w"
 	hput_content_end();hput_range_defs();hput_label_defs();}
-#line 4054 "parser.c"
+#line 4188 "parser.c"
     break;
 
 
-#line 4058 "parser.c"
+#line 4192 "parser.c"
 
       default: break;
     }
@@ -4278,6 +4412,6 @@
   return yyresult;
 }
 
-#line 1174 "parser.y"
+#line 1239 "parser.y"
 
-	/*:534*/
+	/*:553*/

Modified: trunk/Build/source/texk/web2c/hitexdir/hiparser.h
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/hiparser.h	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/hiparser.h	2024-11-11 13:34:37 UTC (rev 72815)
@@ -124,22 +124,23 @@
     MID = 325,                     /* "mid"  */
     LINK = 326,                    /* "link"  */
     OUTLINE = 327,                 /* "outline"  */
-    UNKNOWN = 328,                 /* "unknown"  */
-    STREAM = 329,                  /* "stream"  */
-    STREAMDEF = 330,               /* "stream (definition)"  */
-    FIRST = 331,                   /* "first"  */
-    LAST = 332,                    /* "last"  */
-    TOP = 333,                     /* "top"  */
-    NOREFERENCE = 334,             /* "*"  */
-    PAGE = 335,                    /* "page"  */
-    RANGE = 336,                   /* "range"  */
-    DIRECTORY = 337,               /* "directory"  */
-    SECTION = 338,                 /* "entry"  */
-    DEFINITIONS = 339,             /* "definitions"  */
-    MAX = 340,                     /* "max"  */
-    PARAM = 341,                   /* "param"  */
-    FONT = 342,                    /* "font"  */
-    CONTENT = 343                  /* "content"  */
+    COLOR = 328,                   /* "color"  */
+    UNKNOWN = 329,                 /* "unknown"  */
+    STREAM = 330,                  /* "stream"  */
+    STREAMDEF = 331,               /* "stream (definition)"  */
+    FIRST = 332,                   /* "first"  */
+    LAST = 333,                    /* "last"  */
+    TOP = 334,                     /* "top"  */
+    NOREFERENCE = 335,             /* "*"  */
+    PAGE = 336,                    /* "page"  */
+    RANGE = 337,                   /* "range"  */
+    DIRECTORY = 338,               /* "directory"  */
+    SECTION = 339,                 /* "entry"  */
+    DEFINITIONS = 340,             /* "definitions"  */
+    MAX = 341,                     /* "max"  */
+    PARAM = 342,                   /* "param"  */
+    FONT = 343,                    /* "font"  */
+    CONTENT = 344                  /* "content"  */
   };
   typedef enum yytokentype yytoken_kind_t;
 #endif
@@ -150,7 +151,7 @@
 {
 #line 79 "parser.y"
 
-	#line 11164 "format.w"
+	#line 11653 "format.w"
 	uint32_t u;  int32_t i;  char *s;  float64_t f;  Glyph c;
 	Dimen d;Stretch st;Xdimen xd;Kern kt;
 	Rule r;Glue g;Image x;
@@ -158,7 +159,7 @@
 	Ref rf;Info info;Order o;bool b;
 	
 
-#line 162 "hiparser.h"
+#line 163 "hiparser.h"
 
 };
 typedef union YYSTYPE YYSTYPE;

Modified: trunk/Build/source/texk/web2c/hitexdir/hitex.w
===================================================================
--- trunk/Build/source/texk/web2c/hitexdir/hitex.w	2024-11-11 00:41:42 UTC (rev 72814)
+++ trunk/Build/source/texk/web2c/hitexdir/hitex.w	2024-11-11 13:34:37 UTC (rev 72815)
@@ -251,7 +251,7 @@
 
 @* Introduction.
 This is Hi\TeX, a program derived from \TeX, extending its capabilities
-using \eTeX and \Prote, and adding functions common to other engines from
+using \eTeX\ and \Prote, and adding functions common to other engines from
 the \TeX\ Live distribution. Hi\TeX\ writes output files in
 the \HINT\ file format. Like \TeX, it is
 a document compiler intended to produce typesetting of high
@@ -375,7 +375,7 @@
 @d Prote_banner "This is Prote, Version " Prote_version_string
    /*printed when \Prote\ starts*/
 @#
- at d banner "This is HiTeX, Version 3.141592653"
+ at d banner "This is HiTeX, Version 3.141592653"@|
           eTeX_version_string"-"HINT_VERSION_STRING" "TL_VERSION
           /*printed when \TeX\ starts*/
 
@@ -435,7 +435,9 @@
 
 @p @<Header files and function declarations@>@;
 @h
-enum {@+@<Constants in the outer block@>@+};
+enum {@<Constants in the outer block@>@;
+      @!empty_string=256 /*the empty string follows after 256 characters*/
+};
 @<Types in the outer block@>@;
 @<Forward declarations@>@;
 @<Global variables@>@;
@@ -557,7 +559,6 @@
 @!file_name_size=1024, /*file names shouldn't be longer than this*/
 @!xchg_buffer_size=64, /*must be at least 64*/
    /*size of |eight_bits| buffer for exchange with system routines*/
-@!empty_string=256 /*the empty string follows after 256 characters*/
 
 @ Like the preceding parameters, the following quantities can be changed
 at compile time to extend or reduce \TeX's capacity. But if they are changed,
@@ -567,7 +568,7 @@
 One can't simply make helter-skelter changes to the following constants,
 since certain rather complex initialization
 numbers are computed from them. They are defined here using
-\.{WEB} macros, instead of being put into \PASCAL's |const| list, in order to
+\.{WEB} macros, instead of being put into the above |enum| list in order to
 emphasize this distinction.
 
 @d mem_bot 0 /*smallest index in the |mem| array dumped by \.{INITEX};
@@ -1493,7 +1494,7 @@
 
 @<Basic printing procedures@>=
 #define @[put(F)@]    @[fwrite(&((F).d)@],@[sizeof((F).d),1,(F).f)@]@;
-#define @[get(F)@]    @[fread(&((F).d),sizeof((F).d),1,(F).f)@]
+#define @[get(F)@]    @[(void)fread(&((F).d),sizeof((F).d),1,(F).f)@]
 
 #define @[pascal_close(F)@]    @[fclose((F).f)@]
 #define @[eof(F)@]    @[feof((F).f)@]
@@ -13470,7 +13471,7 @@
 
 @d exactly 0 /*a box dimension is pre-specified*/
 @d additional 1 /*a box dimension is increased from the natural one*/
- at d natural 0, 0, 0, additional /*shorthand for parameters to |hpack| and |vpack|*/
+ at d natural 0, 0, 0, additional, false /*shorthand for parameters to |hpack| and |vpack|*/
 
 @ The parameters to |hpack| and |vpack| correspond to \TeX's primitives
 like `\.{\\hbox} \.{to} \.{300pt}', `\.{\\hbox} \.{spread} \.{10pt}'; note
@@ -13546,7 +13547,7 @@
 
 @ Here now is |hpack|, which contains few if any surprises.
 
- at p static pointer hpack(pointer p, scaled w, scaled hf, scaled vf, small_number m);
+ at p static pointer hpack(pointer p, scaled w, scaled hf, scaled vf, small_number m, bool keep_cs);
 
 @ @<Clear dimensions to zero@>=
 d=0;x=0;
@@ -13771,7 +13772,7 @@
 
 @p
 #define vpack(...) @[vpackage(__VA_ARGS__, max_dimen)@] /*special case of unconstrained depth*/
-static pointer vpackage(pointer p, scaled h, scaled hf, scaled vf, small_number m, scaled l);
+static pointer vpackage(pointer p, scaled h, scaled hf, scaled vf, small_number m, bool keep_cs, scaled l);
 
 @ @<Examine node |p| in the vlist, taking account of its effect...@>=
 {@+if (is_char_node(p)) confusion("vpack");
@@ -14701,7 +14702,7 @@
   b=new_glue(ss_glue);link(b)=p;
   while (link(p)!=null) p=link(p);
   link(p)=new_glue(ss_glue);
-  return hpack(b, w, 0, 0, exactly);
+  return hpack(b, w, 0, 0, exactly, false);
   }
 else{@+width(b)=w;return b;
   }
@@ -16505,12 +16506,12 @@
 if (mode==-vmode)
   {@+rule_save=overfull_rule;
   overfull_rule=0; /*prevent rule from being packaged*/
-  p=hpack(preamble, saved(1), saved_hfactor(1), saved_vfactor(1), saved(0));overfull_rule=rule_save;
+  p=hpack(preamble, saved(1), saved_hfactor(1), saved_vfactor(1), saved(0), false);overfull_rule=rule_save;
   }
 else{@+q=link(preamble);
   @/do at +{height(q)=width(q);width(q)=0;q=link(link(q));
   }@+ while (!(q==null));
-  p=vpack(preamble, saved(1), saved_hfactor(1), saved_vfactor(1), saved(0));
+  p=vpack(preamble, saved(1), saved_hfactor(1), saved_vfactor(1), saved(0), false);
   q=link(preamble);
   @/do at +{width(q)=height(q);height(q)=0;q=link(link(q));
   }@+ while (!(q==null));
@@ -17968,6 +17969,7 @@
 @<Reverse the links of the relevant passive nodes, setting |cur_p| to the
 first breakpoint@>;
 cur_line=prev_graf+1;
+@<initialize the color stack@>@;
 @/do at +{@<Justify the line ending at breakpoint |cur_p|, and append it to the
 current vertical list, together with associated penalties and other insertions@>;
 incr(cur_line);cur_p=next_break(cur_p);
@@ -18128,7 +18130,27 @@
 else{@+cur_width=mem[par_shape_ptr+2*cur_line].sc;
   cur_indent=mem[par_shape_ptr+2*cur_line-1].sc;
   }
-adjust_tail=adjust_head;just_box=hpack(q, cur_width, 0, 0, exactly);
+{ pointer before_color_tos=color_tos;
+  pointer before_link_tos=link_tos;
+  adjust_tail=adjust_head;just_box=hpack(q, cur_width, 0, 0, exactly, true);
+  if (before_link_tos!=before_color_tos)
+  { pointer r;
+    r=new_color_node(color_ref(before_color_tos));
+    link(r) = list_ptr(just_box);
+    list_ptr(just_box)=r;
+  }
+  if (before_link_tos!=null) /* an unfinished link was in the previous line */
+  { pointer r;
+    int words;
+    r=get_node(link_node_size);
+    for (words=0;words<link_node_size; words++)
+      mem[r+words]= mem[before_link_tos+words];
+    if (label_has_name(as_label(r)))
+      add_token_ref(label_ptr(as_label(r)));
+    link(r) = list_ptr(just_box);
+    list_ptr(just_box)=r;
+  }
+}
 shift_amount(just_box)=cur_indent
 
 @ Penalties between the lines of a paragraph come from club and widow lines,
@@ -19803,9 +19825,17 @@
 to |null| at the break@>;
 q=prune_page_top(q, saving_vdiscards > 0);
 p=list_ptr(v);list_ptr(v)=null;flush_node_list(v);
-if (q!=null) q=vpack(q, natural);
+p=vpackage(p, h, 0, 0, exactly, false, split_max_depth);
+if (q!=null)
+{ if (color_tos!=null)
+  { pointer r = new_color_node(color_ref(color_tos));
+    color_tos=color_link(color_tos);
+    link(r)=q; q=r;
+  }
+  q=vpack(q, natural);
+}
 change_box(q); /*the |eq_level| of the box stays the same*/
-return vpackage(p, h, 0, 0, exactly, split_max_depth);
+return p;
 }
 
 @ @<Dispense with trivial cases of void or bad boxes@>=
@@ -20558,7 +20588,7 @@
   }
 save_vbadness=vbadness;vbadness=inf_bad;
 save_vfuzz=vfuzz;vfuzz=max_dimen; /*inhibit error messages*/
-box(255)=vpackage(link(page_head), best_size, 0, 0, exactly, page_max_depth);
+box(255)=vpackage(link(page_head), best_size, 0, 0, exactly, false, page_max_depth);
 vbadness=save_vbadness;vfuzz=save_vfuzz;
 if (last_glue!=max_halfword) delete_glue_ref(last_glue);
 @<Start a new current page@>; /*this sets |last_glue=max_halfword|*/
@@ -21125,7 +21155,7 @@
 
 @<Cases of |main_control| that are not part of the inner loop@>=
 any_mode(relax): case vmode+spacer: case mmode+spacer:
-  case mmode+no_boundary: do_nothing;
+  case mmode+no_boundary: do_nothing;@+break;
 any_mode(ignore_spaces): {@+@<Get the next non-blank non-call...@>;
   goto reswitch;
   }
@@ -21834,8 +21864,8 @@
 pointer @!p; /*first node in a box*/
 scaled @!d; /*max depth*/
 d=box_max_depth;unsave();save_ptr=save_ptr-3;
-if (mode==-hmode) cur_box=hpack(link(head), saved(2), saved_hfactor(2), saved_vfactor(2),  saved(1));
-else{@+cur_box=vpackage(link(head), saved(2), saved_hfactor(2), saved_vfactor(2), saved(1), d);
+if (mode==-hmode) cur_box=hpack(link(head), saved(2), saved_hfactor(2), saved_vfactor(2),  saved(1), false);
+else{@+cur_box=vpackage(link(head), saved(2), saved_hfactor(2), saved_vfactor(2), saved(1), false, d);
   if (c==vtop_code) @<Readjust the height and depth of |cur_box|, for \.{\\vtop}@>;
   }
 pop_nest();box_end(saved(0));
@@ -22911,7 +22941,7 @@
 
 @ @<Cases of |handle...@>=
 case vcenter_group: {@+end_graf();unsave();save_ptr=save_ptr-2;
-  p=vpack(link(head), saved(1), saved_hfactor(1), saved_vfactor(1), saved(0));pop_nest();
+  p=vpack(link(head), saved(1), saved_hfactor(1), saved_vfactor(1), saved(0), false);pop_nest();
   tail_append(new_noad());type(tail)=vcenter_noad;
   math_type(nucleus(tail))=sub_box;info(nucleus(tail))=p;
   } @+break;
@@ -23351,12 +23381,12 @@
    (total_shrink[fil]!=0)||(total_shrink[fill]!=0)||
    (total_shrink[filll]!=0)))
   {@+list_ptr(b)=null;flush_node_list(b);
-  b=hpack(p, z-q, 0, 0, exactly);
+  b=hpack(p, z-q, 0, 0, exactly, false);
   }
 else{@+e=0;
   if (w > z)
     {@+list_ptr(b)=null;flush_node_list(b);
-    b=hpack(p, z, 0, 0, exactly);
+    b=hpack(p, z, 0, 0, exactly, false);
     }
   }
 w=width(b);
@@ -25661,21 +25691,31 @@
 @d ignore_info(A)    type(A+1)
 @d ignore_list(A)    link(A+1)
 
- at d label_node hitex_ext+17 /* represents a link to a another location */
+ at d color_node hitex_ext+17 /* represent a color node */
+ at d end_color_node hitex_ext+18 /* represent an end color node */
+ at d default_color_node hitex_ext+19 /* set default colors*/
+ at d link_color_node hitex_ext+20 /* set link colors */
+ at d default_link_color_node hitex_ext+21 /* set default link colors */
+ at d no_color_node  hitex_ext+22 /* a deleted end color node */
+ at d color_node_size small_node_size
+ at d color_ref(A)  type(A+1) /* reference to the color set */
+ at d color_link(A)     link(A+1) /* pointer down the color stack */
+
+ at d label_node hitex_ext+23 /* represents a link to a another location */
 @d label_node_size 2
 @d label_has_name(A)  type(A+1) /* 1 for a name , 0 for a number */
 @d label_where(A)  subtype(A+1) /* 1 for top, 2 for bot, 3 for mid */
- at d label_ptr(A) link(A+1) /* for a name the token list or the number */
- at d label_ref(A) link(A+1) /*alternatively the label number */
+ at d label_ptr(A) link(A+1) /* hitex: a name (token list) or a number */
 
- at d start_link_node hitex_ext+18 /* represents a link to a another location */
- at d end_link_node hitex_ext+19 /* represents a link to a another location */
- at d link_node_size 2 /* second word like a |label_node| */
+ at d start_link_node hitex_ext+24 /* represents a link to another location */
+ at d end_link_node hitex_ext+25 /* represents a link to another location */
+ at d link_node_size 3 /* second word like a |color_node| */
+ at d as_label(A) ((A)+1) /* third word like a |label_node| */
 
- at d outline_node hitex_ext+20 /* represents an outline item */
- at d outline_node_size 4 /* second word like a |label_node| */
+ at d outline_node hitex_ext+26 /* represents an outline item */
+ at d outline_node_size 3 /* second word like a |label_node| */
 @d outline_ptr(A)   link(A+2) /* text to be displayed */
- at d outline_depth(A) mem[A+3].i /* depth of sub items */
+ at d outline_depth(A) info(A+2) /* depth of sub items */
 
 
 @ The sixteen possible \.{\\write} streams are represented by the |write_file|
@@ -25712,47 +25752,9 @@
 @!@:special\_}{\.{\\special} primitive@>
 primitive("immediate", extension, immediate_code);@/
 @!@:immediate\_}{\.{\\immediate} primitive@>
-
 primitive("setlanguage", extension, set_language_code);@/
 @!@:set\_language\_}{\.{\\setlanguage} primitive@>
 
-primitive("HINTversion", last_item, HINT_version_code);
-@!@:HINT\_version\_}{\.{\\HINTversion} primitive@>
-
-primitive("HINTminorversion", last_item, HINT_minor_version_code);
-@!@:HINT\_minor\_version\_}{\.{\\HINTminorversion} primitive@>
-
-primitive("HINTdest", extension, label_node);@/
-@!@:HINTdest\_}{\.{\\HINTdest} primitive@>
-
-primitive("HINTstartlink", extension, start_link_node);@/
-@!@:startlink\_}{\.{\\HINTstartlink} primitive@>
-
-primitive("HINTendlink", extension, end_link_node);@/
-@!@:HINTendlink\_}{\.{\\HINTendlink} primitive@>
-
-primitive("HINToutline", extension, outline_node);@/
-@!@:HINToutline\_}{\.{\\HINToutline} primitive@>
-
-primitive("HINTimage", extension, image_node);@/
-@!@:image\_}{\.{\\image} primitive@>
-
-primitive("HINTsetpage", extension, setpage_node);@/
-@!@:setpage\_}{\.{\\setpage} primitive@>
-
-primitive("HINTstream", extension, stream_node);@/
-@!@:stream\_}{\.{\\stream} primitive@>
-
-primitive("HINTsetstream", extension, setstream_node);@/
-@!@:setstream\_}{\.{\\setstream} primitive@>
-
-primitive("HINTbefore", extension, stream_before_node);@/
-@!@:before\_}{\.{\\before} primitive@>
-
-primitive("HINTafter", extension, stream_after_node);@/
-@!@:after\_}{\.{\\after} primitive@>
-
-
 @ The variable |write_loc| just introduced is used to provide an
 appropriate error message in case of ``runaway'' write texts.
 
@@ -25766,6 +25768,12 @@
   case close_node: print_esc("closeout");@+break;
   case special_node: print_esc("special");@+break;
   case image_node: print_esc("HINTimage");@+break;
+  case color_node: print_esc("HINTcolor");@+break;
+  case end_color_node: print_esc("HINTendcolor");@+break;
+  case no_color_node: print_esc("HINTendcolor ignored");@+break;
+  case default_color_node: print_esc("HINTdefaultcolor");@+break;
+  case link_color_node: print_esc("HINTlinkcolor");@+break;
+  case default_link_color_node: print_esc("HINTdefaultlinkcolor");@+break;
   case start_link_node: print_esc("HINTstartlink");@+break;
   case end_link_node: print_esc("HINTendlink");@+break;
   case label_node: print_esc("HINTdest");@+break;
@@ -25819,21 +25827,27 @@
 case align_node: @+break;@#
 case image_node:@/
 {@+ pointer p;
+  scaled iw=0,ih=0;
+  double ia=0.0;
   scan_optional_equals();
   scan_file_name();
   p=new_image_node(cur_name,cur_area,cur_ext);
   loop {
     if (scan_keyword("width"))
-    {@+scan_normal_dimen; image_xwidth(p)=new_xdimen(cur_val,cur_hfactor,cur_vfactor); }
+    {@+scan_normal_dimen; image_xwidth(p)=new_xdimen(cur_val,cur_hfactor,cur_vfactor);
+     if (cur_hfactor==0 && cur_vfactor==0) iw=cur_val;
+    }
     else if (scan_keyword("height"))
-    {@+scan_normal_dimen; image_xheight(p)=new_xdimen(cur_val,cur_hfactor,cur_vfactor); }
+    {@+scan_normal_dimen; image_xheight(p)=new_xdimen(cur_val,cur_hfactor,cur_vfactor);
+      if (cur_hfactor==0 && cur_vfactor==0) ih=cur_val;
+    }
     else
       break;
   }
-  { scaled iw,ih;
-    double ia;
+  {
     pointer r,q;
-    hextract_image_dimens(image_no(p),&ia,&iw,&ih);
+    if (ih!=0 && iw!=0 ) ia=(double)iw/ih;
+    else hextract_image_dimens(image_no(p),&ia,&iw,&ih);
     image_aspect(p)=round(ia*ONE);
     r=image_xwidth(p);
     q=image_xheight(p);
@@ -25845,8 +25859,8 @@
       else if (iw<0)
       { MESSAGE("Unable to determine size of image %s; using 72dpi.\n",
 		dir[image_no(p)].file_name);
-	image_xwidth(p)=r=new_xdimen(-iw*ONE,0,0);
-        image_xheight(p)=q=new_xdimen(-ih*ONE,0,0);
+	image_xwidth(p)=r=new_xdimen(-iw,0,0);
+        image_xheight(p)=q=new_xdimen(-ih,0,0);
       }
       else
       { MESSAGE("Unable to determine size of image %s; using 100pt x 100pt\n",
@@ -25871,12 +25885,57 @@
     tail_append(p);
   break;
 }
+case color_node:
+    { ColorSet c;
+      new_whatsit(color_node,color_node_size);
+      scan_color_spec(c,0);
+      color_ref(tail)=next_colorset(c);
+      color_link(tail)=null;
+      default_color_frozen=true;
+    }
+    break;
+case no_color_node: break;
+case end_color_node:
+    { new_whatsit(end_color_node,color_node_size);
+      color_ref(tail)=0xFF;
+      color_link(tail)=null;
+    }
+    break;
+case default_color_node:
+    if (default_color_frozen)
+    { print_err("You can not use \\HINTdefaultcolor after \\HINTcolor");
+      error();
+    }
+    else
+    { ColorSet c;
+      scan_color_spec(c,0);
+      colorset_copy(colors[0],c);
+    }
+    break;
+case link_color_node:
+    { ColorSet c;
+      scan_color_spec(c,1);
+      cur_link_color=next_colorset(c);
+      default_link_color_frozen=true;
+    }
+    break;
+case default_link_color_node:
+    if (default_link_color_frozen)
+    {@+print_err("You can not use \\HINTdefaultlinkcolor after \\HINTlinkcolor");      error();
+    }
+    else
+    { ColorSet c;
+      scan_color_spec(c,1);
+      colorset_copy(colors[1],c);
+    }
+    break;
 case start_link_node:
   if (abs(mode) == vmode)
     fatal_error("HINTstartlink cannot be used in vertical mode");
   else
   { new_whatsit(start_link_node,link_node_size);
-    scan_label(tail);
+    scan_label(as_label(tail));
+    color_ref(tail)=cur_link_color;
   }
   break;
 case end_link_node:
@@ -25883,7 +25942,9 @@
   if (abs(mode) == vmode)
     fatal_error("HINTendlink cannot be used in vertical mode");
   else
-    new_whatsit(end_link_node,link_node_size);
+  { new_whatsit(end_link_node,link_node_size);
+    color_ref(tail)=0xFF;
+  }
   break;
 case label_node:
   new_whatsit(label_node,label_node_size);
@@ -26168,6 +26229,15 @@
   print("), section ");print_int(image_no(p));
   if (image_name(p)!=0) {print(", "); printn(image_name(p));}
   break;
+case color_node:
+  print_esc("HINTcolor ");print_int(color_ref(p));
+  break;
+case no_color_node:
+  print_esc("HINTendcolor ignored");
+  break;
+case end_color_node:
+  print_esc("HINTendcolor ");
+  break;
 case align_node:
   print_esc("align(");
   print(align_m(p)==exactly?"exactly ":"additional ");
@@ -26211,10 +26281,12 @@
   break;
 case start_link_node:
   print_esc("HINTstartlink ");
-  print_label(p);
+  print_label(as_label(p));
+  if (color_ref(p)!=1) { print("color "); print_int(color_ref(p)); }
   break;
 case end_link_node:
   print_esc("HINTendlink ");
+  if (color_ref(p)!=0xFF) { print("color "); print_int(color_ref(p)); }
   break;
 case label_node:
   print_esc("HINTdest ");
@@ -26297,6 +26369,12 @@
     image_alt(r)=copy_node_list(image_alt(p));
     words=image_node_size-1;
     break;
+case color_node:
+case no_color_node:
+case end_color_node:
+    r=get_node(color_node_size);
+    words=color_node_size;
+    break;
 case align_node:
   {@+r=get_node(align_node_size);
      align_preamble(r)=copy_node_list(align_preamble(p));
@@ -26331,7 +26409,7 @@
   break;
 case start_link_node:
     r=get_node(link_node_size);
-    if (label_has_name(p)) add_token_ref(label_ptr(p));
+    if (label_has_name(as_label(p))) add_token_ref(label_ptr(as_label(p)));
     words=link_node_size;
     break;
 case end_link_node:
@@ -26347,6 +26425,7 @@
     r=get_node(outline_node_size);
     if (label_has_name(p)) add_token_ref(label_ptr(p));
     outline_ptr(r)=copy_node_list(outline_ptr(p));
+    outline_depth(r)=outline_depth(p);
     words=outline_node_size-1;
     break;
 case stream_node:
@@ -26395,6 +26474,10 @@
   delete_xdimen_ref(image_xwidth(p)); delete_xdimen_ref(image_xheight(p));
   flush_node_list(image_alt(p));
   free_node(p,image_node_size);@+break;
+case color_node:
+case no_color_node:
+case end_color_node:
+  free_node(p,color_node_size);@+break;
 case align_node:
   delete_xdimen_ref(align_extent(p));
   flush_node_list(align_preamble(p));
@@ -26419,7 +26502,7 @@
   flush_node_list(ignore_list(p));
   free_node(p,ignore_node_size); @+break;
 case start_link_node:
-  if (label_has_name(p)) delete_token_ref(label_ptr(p));
+  if (label_has_name(as_label(p))) delete_token_ref(label_ptr(as_label(p)));
   free_node(p,link_node_size);@+break;
 case end_link_node:
   free_node(p,link_node_size);@+break;
@@ -30457,6 +30540,13 @@
 @d HINT_version_code (eTeX_last_last_item_cmd_mod+7) /* \.{\\HINTversion} */
 @d HINT_minor_version_code (eTeX_last_last_item_cmd_mod+8) /* \.{\\HINTminorversion} */
 
+@<Put each...@>=
+primitive("HINTversion", last_item, HINT_version_code);
+@!@:HINT\_version\_}{\.{\\HINTversion} primitive@>
+primitive("HINTminorversion", last_item, HINT_minor_version_code);
+@!@:HINT\_minor\_version\_}{\.{\\HINTminorversion} primitive@>
+
+
 @ Now this new primitive needs its implementation.
 
 @<Cases of |last_item| for |print_cmd_chr|@>=
@@ -30672,6 +30762,8 @@
   pointer pp;
   scaled par_max_depth=0;
   bool par_shape_fix=false;
+  @<initialize the color stack@>@,
+#if DEBUG
   if (DBGTEX&debugflags)
   { print_ln();print("Before hline_break:\n");
     breadth_max=200;
@@ -30678,6 +30770,7 @@
     depth_threshold=200;
     show_node_list(link(head));print_ln();
   }
+#endif
   if (dimen_par_hfactor(hsize_code)==0 && dimen_par_vfactor(hsize_code)==0)
   { line_break(final_widow_penalty); /* the easy case */
     return;
@@ -30746,8 +30839,13 @@
     }
     switch (type(cur_p))
 	{ case whatsit_node:
-	    adv_past(cur_p);
-		break;
+          { pointer p=cur_p; /* reusing code written for |p| */
+	    switch (subtype(cur_p))
+	    { @<cases that flatten the color stack@>
+             default: adv_past(cur_p); break;
+            }
+            break;
+	  }
 	  case glue_node:
      	if (auto_breaking) /* Try to hyphenate the following word*/
 		  hyphenate_word();
@@ -30846,9 +30944,486 @@
   par_shape_fix=true;
 }
 
+@*1 Colors.
+Hi\TeX\ adds these primitives to handle colors:
+
+@<Put each...@>=
+primitive("HINTcolor", extension, color_node);@/
+@!@:HINTcolor\_}{\.{\\HINTcolor} primitive@>
+primitive("HINTendcolor", extension, end_color_node);@/
+@!@:HINTendcolor\_}{\.{\\HINTendcolor} primitive@>
+primitive("HINTdefaultcolor", extension, default_color_node);@/
+@!@:HINTdefaultcolor\_}{\.{\\HINTdefaultcolor} primitive@>
+primitive("HINTlinkcolor", extension, link_color_node);@/
+@!@:HINTlinkcolor\_}{\.{\\HINTlinkcolor} primitive@>
+primitive("HINTdefaultlinkcolor", extension, default_link_color_node);@/
+@!@:HINTdefaultlinkcolor\_}{\.{\\HINTdefaultlinkcolor} primitive@>
+
+@ To begin with the implementation,
+we need the function |scan_scaled| which is a simpler version of |scan_dimen|.
+It will just scan a pure number without any units.
+We need this function to scan colors.
+
+@<Declare procedures needed in |do_extension|@>=
+static void scan_scaled(void)
+{@+
+  bool negative=false; /*should the answer be negated?*/
+  int @!f; /*numerator of a fraction whose denominator is $2^{16}$*/
+  int @!k, @!kk; /*number of digits in a decimal fraction*/
+  pointer @!p, @!q; /*top of decimal digit stack*/
+  f=0;arith_error=false;cur_order=normal;negative=false;
+  @<Get the next non-blank non-call token@>;
+  if (cur_tok==other_token+'-') negative=true;
+  else if (cur_tok==other_token+'+') negative=false;
+  else back_input();
+  if (cur_tok==continental_point_token) cur_tok=point_token;
+  if (cur_tok!=point_token) scan_int();
+  else {@+radix=10;cur_val=0; }
+  if (cur_tok==continental_point_token) cur_tok=point_token;
+  if ((radix==10)&&(cur_tok==point_token)) @<Scan decimal fraction@>;
+  if (cur_val < 0)  /*in this case |f==0|*/
+    {@+negative=!negative;negate(cur_val);}
+  if (cur_val >= 040000) arith_error=true;
+  else cur_val=cur_val*unity+f;
+  @<Scan an optional space@>;
+  if (arith_error||(abs(cur_val) >= 010000000000))
+    @<Report that this dimension is out of range@>;
+  if (negative)  negate(cur_val);
+}
+
+@ A color specification starting with ``FG'' or ``BG'' expects
+integers in the range 0 to |0xFF|;
+a color specification starting with ``fg'' or ``bg'' expects
+real numbers in the range 0 to 1 which are then scalled to the
+same range as before.
+The four color components are enclosed in braces. The last
+component is optional and its default value is |0xFF|.
+
+@<Declare procedures needed in |do_extension|@>=
+static uint8_t scan_color_component(bool expect_reals)
+{ if (expect_reals)
+  { scan_scaled(); cur_val=(cur_val*0xFF+0x1000)>>16; }
+  else
+    scan_int();
+  if (cur_val>0xFF) return 0xFF;
+  else if (cur_val<0) return 0x00;
+  else return cur_val;
+}
+
+static uint32_t scan_color(bool expect_reals)
+{ uint8_t r,g,b,a;
+  scan_left_brace();
+  r=scan_color_component(expect_reals);
+  g=scan_color_component(expect_reals);
+  b=scan_color_component(expect_reals);
+  @<Get the next non-blank non-relax...@>;
+  if (cur_cmd==right_brace)
+    a=0xFF;
+  else
+  { back_input();
+    a=scan_color_component(expect_reals);
+    @<Get the next non-blank non-call token@>;
+    if (cur_cmd!=right_brace)
+    { back_input();
+      print_err("Missing right brace after color definition");
+    }
+  }
+  return (r<<24)|(g<<16)|(b<<8)|a;
+}
+
+@ Colors are specified in pairs of a foreground color, prefixed
+by ``FG'' or ``fg'', followed by an optional background color
+prefixed by ``BG'' or ``bg''.
+Up to three color pairs, for normal text, highlighted text, and focus text
+make up a color set. A color specification can contain two
+color sets the first one for ``day mode'' the second, prefixed
+by the keyword ``dark'' for ``night mode''.
+
+@<Declare procedures needed in |do_extension|@>=
+static void colorset_copy(ColorSet to, ColorSet from)
+{ int i;
+  for (i=0;i<sizeof(ColorSet)/sizeof(uint32_t);i++)
+    to[i]=from[i];
+}
+
+static bool scan_color_pair(ColorSet c, int m, int s)
+{ if (scan_keyword("FG")) c[m*6+s*2+0] =scan_color(false);
+  else if (scan_keyword("fg")) c[6*m+2*s+0]=scan_color(true);
+  else return false;
+  if (scan_keyword("BG")) c[m*6+s*2+1]=scan_color(false);
+  else if (scan_keyword("bg")) c[m*6+s*2+1]=scan_color(true);
+  return true;
+}
+
+static void scan_color_triple(ColorSet c, int m)
+{ if (!scan_color_pair(c,m,0))
+  { print_err("Missing color specification");
+    return;
+  }
+  if (scan_color_pair(c,m,1)) scan_color_pair(c,m,2);
+}
+
+static void scan_color_spec(ColorSet c, int i)
+{ colorset_copy(c,colors[i]); /* initialize with defaults */
+  scan_left_brace();
+  scan_color_triple(c,0);
+  if (scan_keyword("dark")) scan_color_triple(c,1);
+  @<Get the next non-blank non-relax non-call token@>;
+  if (cur_cmd!=right_brace)
+  {@+print_err("A color specification must end with }");
+    back_error();
+  }
+}
+
+@ We store color sets in a dynamic array
+
+@<Forward declarations@>=
+static ColorSet *colors=NULL;
+static int max_color=-1, colors_allocated=0;
+static bool default_color_frozen=false, default_link_color_frozen=false;
+static int cur_link_color=1;
+static int next_colorset(ColorSet c);
+
+@ @<Hi\TeX\ auxiliary routines@>=
+static bool colorset_equal(ColorSet old, ColorSet new)
+{ int i;
+  for (i=0;i<sizeof(ColorSet)/sizeof(uint32_t);i++)
+    if (old[i]!=new[i]) return false;
+  return true;
+}
+
+
+static int next_colorset(ColorSet c)
+{ int i;
+  for (i=0; i<=max_color; i++)
+    if (colorset_equal(colors[i],c)) return i;
+  if (max_color<0xFF) max_ref[color_kind]=++max_color;
+  else overflow("colors",0xFF);
+  if (max_color>=colors_allocated)
+    RESIZE(colors,colors_allocated,ColorSet);
+  colorset_copy(colors[max_color],c);
+#if DEBUG
+  if (debugflags&DBGDEF)
+  { print_nl("HINT Defining new color "); print_int(max_color);print(": ");
+    print_color_spec(max_color); }
+#endif
+  return max_color;
+}
+
+@ @<Initialize definitions for colors@>=
+colors_allocated=8;
+ALLOCATE(colors,colors_allocated,ColorSet);
+max_ref[color_kind]=max_color=MAX_COLOR_DEFAULT;
+memcpy(colors,color_defaults,sizeof(ColorSet)*(max_color+1));
+
+
+@ Next we implement a procedure to print a color specification.
+
+@ @<Hi\TeX\ auxiliary routines@>=
+
+static bool is_default_color_pair(ColorSet c, int m, int s)
+{ return c[6*m+2*s] == colors[0][6*m+2*s]
+      && c[6*m+2*s+1] == colors[0][6*m+2*s+1];
+}
+
+static void print_color(uint32_t c)
+{ print_char('{');
+  print_hex((c>>24)&0xFF);print_char(' ');
+  print_hex((c>>16)&0xFF);print_char(' ');
+  print_hex((c>>8)&0xFF);print_char(' ');
+  if ((c&0xFF)!=0xFF) print_hex(c&0xFF);
+  print_char('}');
+}
+
+static void print_color_pair(ColorSet c, int m, int s)
+{ print("FG"); print_color(c[6*m+2*s+0]);
+  print(" BG"); print_color(c[6*m+2*s+1]);
+}
+
+static void print_color_triple(ColorSet c, int m)
+{ bool diff_high, diff_focus;
+  print_color_pair(c,m,0);
+  diff_high= is_default_color_pair(c,m,1);
+  diff_focus= is_default_color_pair(c,m,2);
+  if (diff_high || diff_focus)
+  { print_char(' '); print_color_pair(c,m,1); }
+  if (diff_focus)
+  { print_char(' '); print_color_pair(c,m,2); }
+}
+
+static void print_color_spec(int i)
+{ if (i>max_color) {print("undefined color "); print_int(i);}
+  else if (i<0 || i>0xFF) { print("illegal color "); print_int(i);}
+  else
+  { print_color_triple(colors[i],0);
+    if (is_default_color_pair(colors[i],1,0) &&
+        is_default_color_pair(colors[i],1,1) &&
+	is_default_color_pair(colors[i],1,2))
+	return;
+    print(" dark "); print_color_triple(colors[i],1);
+  }
+}
+
+@ @<Forward declarations@>=
+static void print_color_spec(int i);
+
+@ To create a color node you can use the following function:
+@<Hi\TeX\ auxiliary routines@>=
+static pointer new_color_node(uint8_t c)
+{ pointer r = get_node(color_node_size);
+  type(r)=whatsit_node;subtype(r)=color_node;
+  color_ref(r)=c; color_link(r)=null;
+  return r;
+}
+
+@ @<Forward declarations@>=
+static void print_color_spec(int i);
+static pointer new_color_node(uint8_t c);
+
+@ Writing a color node to the output is simple.
+When we come to the output routine, every |end_color_node|
+should have been replaced by a |color_node|.
+To switch back to the color of the enclosing box,
+a |color_node| uses the color reference |0xFF|.
+An |end_color_node| is converted to a |color_node|
+when flattening the color stack.
+If an |end_color_node| does not have
+a matching |color_node| it is converted
+into a |no_color_node| which is silently ignored.
+If an |end_color_node| remains, it is ignored as well.
+
+@<cases to output whatsit content nodes@>=
+case color_node:
+  HPUT8(color_ref(p));
+  tag=TAG(color_kind,b000);
+  break;
+case no_color_node:
+case end_color_node:
+  hpos--;
+  return;
+
+@ For the top level color nodes we provide a function to output colors
+without the need to construct (and destroy) a color node.
+
+@<Hi\TeX\ auxiliary routines@>=
+static void hout_color_ref(uint8_t c)
+{ uint8_t tag=TAG(color_kind,b000);
+  HPUTNODE;
+  HPUT8(tag);
+  HPUT8(c);
+  HPUT8(tag);
+}
+
+@ The output of color definitions is more complex:
+
+@<Output color definitions@>=
+  DBG(DBGDEF,"DEfining %d color references\n",max_ref[color_kind]);
+  HPUTX((1+1+1+sizeof(ColorSet)+1)*(max_ref[color_kind]+1));
+  for (i=max_fixed[color_kind]+1;i<=max_default[color_kind]; i++)
+    { if (!colorset_equal(colors[i],color_defaults[i]))
+        HPUTDEF(hout_color_def(colors[i]),i);
+    }
+  for (;i<=max_ref[color_kind]; i++)
+           HPUTDEF(hout_color_def(colors[i]),i);
+
+@ @<Hi\TeX\ auxiliary routines@>=
+static Tag hout_color_def(ColorSet c)
+{ int i;
+//  HPUTX(3+12*4);
+  HPUT8(6);
+  for (i=0;i<sizeof(ColorSet)/sizeof(uint32_t);i++)
+    HPUT32(c[i]);
+  return TAG(color_kind,b000);
+}
+
+@ Hi\TeX\ treats colors different than \HINT\ files:
+Hi\TeX\ maintains a color stack inside a box while \HINT\
+files implement only a flat sequence of colors inside a box.
+As a consequence an |end_color_node| must be converted to a
+plain |color_node|. An |end_color_node| without a matching
+|color_node| is converted to a |no_color_node|, so that after
+flattening a node list no |end_color_node| remains.
+It will make flattening a list idempotent.
+Since link nodes are part of the color change
+mechanism they are part of the color stack.
+The color stack is a linked stack using the |color_link| field
+of color and link nodes. A pointer to the top node on this stack
+is in the variable |color_tos|. A pointer to the top link node
+on this stack (if any) is in the variable |link_tos|.
+Note that links are not nested, hence the |link_tos| variable
+is not strictly necessary but it avoids searching the color
+stack for a link node.
+
+@<Global variables@>=
+static  pointer color_tos=null;
+static  pointer link_tos=null;
+
+@ @<initialize the color stack@>=
+color_tos=null;
+link_tos=null;
+
+@ @<Incorporate a |color_node| into the box@>=
+color_link(p)=color_tos;
+color_tos=p;
+
+@ @<Incorporate an |end_color_node| into the box@>=
+if (color_tos==link_tos)
+  subtype(p)=no_color_node;
+else if (color_tos!=null)
+{ color_tos=color_link(color_tos);
+  subtype(p)=color_node;
+  if (color_tos!=null)
+    color_ref(p)=color_ref(color_tos);
+  else
+    color_ref(p)=0xFF;
+}
+else
+  subtype(p)=no_color_node;
+
+@ In contrast, link nodes must not be nested, and an |end_link_node|
+  is mandatory. So a link stack is not necessary. Hi\TeX\ just maintains
+  a pointer to current |start_link_node| to be able to restore the color stack.
+
+@<Incorporate a |start_link_node| into the box@>=
+if (link_tos!=null)
+{@+begin_diagnostic();
+  print_err("This link is preceeded by a \\HINTlink without \\HINTendlink:");
+  end_diagnostic(true);
+}
+@<Incorporate a |color_node| into the box@>@;
+link_tos= color_tos;
+
+@ @<Incorporate an |end_link_node| into the box@>=
+if (link_tos==null)
+{@+begin_diagnostic();
+  print_err("\\HINTendlink without matching \\HINTlink:");
+  end_diagnostic(true);
+}
+else
+{ color_tos=color_link(link_tos);
+  link_tos=null;
+  if (color_tos!=null)
+    color_ref(p)=color_ref(color_tos);
+  else
+    color_ref(p)=0xFF;
+}
+
+@ Together these routines flatten the color stack.
+ @<cases that flatten the color stack@>=
+case color_node:
+  @<Incorporate a |color_node| into the box@>@; break;
+case end_color_node:
+  @<Incorporate an |end_color_node| into the box@>@; break;
+case start_link_node:
+  @<Incorporate a |start_link_node| into the box@>@; break;
+case end_link_node:
+  @<Incorporate an |end_link_node| into the box@>@; break;
+case no_color_node: break;
+
+@ Special care is needed for color changes in the top level vertical
+list. Because this list can grow quite large, nodes are deallocated
+right after being written to the output file. Therefore maintaining
+the color stack in the color nodes contained in the vertical list
+is not quite possible. Further page breaks can occur at many different
+places and to switch to the correct color, we might need to insert color
+nodes at all points where a new page might start.
+
+Page breaks are possible
+at glue nodes if the preceeding node was descardable
+(a node is descardable if its type is less than |math_node|),
+at kern nodes if they precede a glue node
+and at penalty nodes. It is inconvenient to test whether a kern node is
+followed by glue node; but because the kern node will disapear
+in the page break, it is sufficient to postpone the color information
+and insert it after the following glue node. If there are several
+glue or kern nodes in a row, it is sufficient to insert the color
+information only once at the beginning.
+
+We keep track of the possible breaks
+and the color stack using four static variables.
+
+@<Define the top level color stack@>=
+#define MAX_COLOR_STACK 256  /* a power of two */
+#define COLOR_STACK_MASK (MAX_COLOR_STACK-1)
+static uint8_t color_stack[MAX_COLOR_STACK];
+static int color_sp=0, color_stack_depth=0;
+static bool possible_break=true;
+
+
+@ Penalties and glue nodes but also baseline skips are possible page breaks.
+
+@<|p| might be a page break@>=
+( type(p)==penalty_node ||
+  type(p)==glue_node ||
+  (type(p)==whatsit_node && subtype(p)==baseline_node))
+
+@ After a possible page break, we need to output the current color
+if a non discardable node shows up. Of course no such output is needed
+if that node is a color change itself.
+
+@<Output the current color if needed@>=
+if (non_discardable(p))
+{ if (color_stack_depth>0 && possible_break)
+  { if (!(type(p)==whatsit_node &&
+            (subtype(p)==color_node || subtype(p)==end_color_node)))
+       hout_color_ref(color_stack[color_sp]);
+  }
+  possible_break=false;
+}
+
+
+@ It remains to organize the color stack.
+There are two possible cases to consider: A \TeX\ file might use
+nested colors on the top level with color nodes and matching end
+color nodes; or alternatively, a \TeX\ file might use color nodes without
+matching |end_color| nodes. Of course a \TeX\ file might also mix both approaches.
+In the first case, a limited nesting level can be assumed and a small
+color stack should suffice. In the second case, even a very large
+color stack will overflow sooner or later. To be as flexible as
+possible, we implement the color stack as a circular buffer.
+It is able to restore colors up to a limited nesting depth, but
+an overflow will not cause big problems.
+
+@<Record the current top level color@>=
+if (type(p)==whatsit_node)
+{ if (subtype(p)==color_node)
+  {  color_stack_depth++;
+     color_sp = (color_sp+1)&COLOR_STACK_MASK;
+     if (color_stack_depth>=MAX_COLOR_STACK)
+     { static bool stackoverflow_printed=false;
+       if (!stackoverflow_printed)
+       { print_err("Overflow of top level color stack");
+	 stackoverflow_printed=true;
+       }
+     }
+     color_stack[color_sp]=color_ref(p);
+  }
+  else if (subtype(p)==end_color_node)
+  { if (color_stack_depth>0)
+    { color_stack_depth--;
+      color_sp = (color_sp-1)&COLOR_STACK_MASK;
+      subtype(p)=color_node;
+      color_ref(p)=color_stack[color_sp];
+    }
+  }
+}
+if (@<|p| might be a page break@>) possible_break=true;
+
+
 @*1 Links, Labels, and Outlines.
 The \HINT\ format knows about labels, links, and outlines.
-When generating a short format \HINT\ file, links are part of
+
+@<Put each...@>=
+primitive("HINTdest", extension, label_node);@/
+@!@:HINTdest\_}{\.{\\HINTdest} primitive@>
+primitive("HINTstartlink", extension, start_link_node);@/
+@!@:HINTstartlink\_}{\.{\\HINTstartlink} primitive@>
+primitive("HINTendlink", extension, end_link_node);@/
+@!@:HINTendlink\_}{\.{\\HINTendlink} primitive@>
+primitive("HINToutline", extension, outline_node);@/
+@!@:HINToutline\_}{\.{\\HINToutline} primitive@>
+
+@ When generating a short format \HINT\ file, links are part of
 the content section, where as labels and outlines are found in
 the definition section. Because labels are defined while
 writing the content section, the writing of labels and outlines
@@ -31014,7 +31589,7 @@
 @<Hi\TeX\ auxiliary routines@>=
 static int last_link=-1;
 static int new_start_link(pointer p)
-{ int n=find_label(p);
+{ int n=find_label(as_label(p));
   if (last_link>=0)
     fatal_error("Missing end link before start link");
   labels[n].used=true;
@@ -31065,6 +31640,7 @@
 @<Hi\TeX\ routines@>=
 static void build_page(void)
 { static bool initial=true;
+  @<Define the top level color stack@>@;
   if(link(contrib_head)==null||output_active)return;
   do
   { pointer p= link(contrib_head);
@@ -31074,6 +31650,7 @@
     int page_penalty=0;
     if (eject) page_penalty=penalty(p);
     @<Record the bottom mark@>@;
+    @<Record the current top level color@>@;
     @<Suppress empty pages if requested@>@;
     link(contrib_head)= link(p);link(p)= null;
     if (link(contrib_head)==null)
@@ -31084,7 +31661,9 @@
     page_goal=0x3fffffff; /* maximum dimension */
     t=collect_output(&p,&q);
     if (p!=null)
-    { hpos0=hpos; hout_node(p); }
+    { hpos0=hpos; hout_node(p);
+      @<Output the current color if needed@>@;
+    }
 recycle_p:
     flush_node_list(p);
     if (q!=null||(eject&&page_contents>=box_there))
@@ -31446,11 +32025,12 @@
 The following routines extend \TeX's original routines. They check for
 any dependency of the box size on {\tt hsize} or {\tt vsize} and
 create an hset node or hpack node if such a dependency was found.
+The |keep_cs| variable will prevent the initialization of the color
+stack; this is needed in the |line_break| routine, where the color
+stack is maintained for the whole paragraph not for the individual lines.
 
-
 @<Hi\TeX\ routines@>=
-
-static pointer hpack(pointer p,scaled w, scaled hf, scaled vf, small_number m)
+static pointer hpack(pointer p,scaled w, scaled hf, scaled vf, small_number m, bool keep_cs)
 {
   pointer r; /*the box node that will be returned*/
   pointer q; /*trails behind |p|*/
@@ -31462,6 +32042,7 @@
   four_quarters i;  /*font information about a |char_node|*/
   eight_bits hd; /*height and depth indices for a character*/
   bool repack=false; /* whether repacking is necessary */
+  if (!keep_cs) { @<initialize the color stack@>@;}
   last_badness= 0;r= get_node(box_node_size);type(r)= hlist_node;
   subtype(r)= min_quarterword;shift_amount(r)= 0;
   q= r+list_offset;link(q)= p;
@@ -31480,9 +32061,19 @@
       case glue_node: @<Incorporate glue into the horizontal totals@>@;@+break;
       case kern_node: case math_node: x=x+width(p);@+break;
       case ligature_node: @<Make node |p| look like a |char_node| and |goto reswitch|@>@;
-      case whatsit_node: @<Incorporate the various extended boxes into an hbox@>@;@+break;
+      case whatsit_node: @<Incorporate the various whatsit nodes into an hbox@>@;@+break;
       default:do_nothing;
       }
+      if (link(p)==null && keep_cs && link_tos!=null)
+      { pointer r;
+        r=get_node(link_node_size);
+	type(r)=whatsit_node; subtype(r)=end_link_node;
+        if (color_link(color_tos)!=null)
+	  color_ref(r)=color_ref(color_link(color_tos));
+        else
+          color_ref(r)=0xFF;
+        link(r)=null; link(p)=r; p=r;
+      }
       p= link(p);
     }
   }
@@ -31561,7 +32152,7 @@
 complicated. | graph_node|s should not be in a horizontal list, and |disp_node|s
 should be only inside |graph_node|s.
 
-@<Incorporate the various extended boxes into an hbox@>=
+@<Incorporate the various whatsit nodes into an hbox@>=
 switch (subtype(p))
 { case par_node: if (depth(p)> d) d=depth(p); break;
   case disp_node:  break;
@@ -31586,16 +32177,18 @@
       else { repack=true; break;}
     }
     break;
+    @<cases that flatten the color stack@>@;
   default: break;
 }
 
 @ @<Hi\TeX\ routines@>=
-static pointer vpackage(pointer p, scaled h, scaled hf, scaled vf, small_number m, scaled l)
+static pointer vpackage(pointer p, scaled h, scaled hf, scaled vf, small_number m, bool keep_cs, scaled l)
 { pointer r; /*the box node that will be returned*/
   scaled w,d,x; /*width, depth, and natural height*/
   scaled s=0; /*shift amount*/
   pointer g; /*points to a glue specification*/
   glue_ord sho, sto; /*order of infinity*/
+  if (!keep_cs) {@<initialize the color stack@>@;}
   last_badness= 0; r= get_node(box_node_size); type(r)= vlist_node;
   subtype(r)= min_quarterword; shift_amount(r)= 0;
   list_ptr(r)= p;
@@ -31619,36 +32212,34 @@
           case unset_set_node: case unset_pack_node:
               goto repack;
           case whatsit_node:
-            if (subtype(p)==par_node)
-                          { if (depth(p) > d) d=depth(p);
-			    goto repack; }
-			else if (subtype(p)==disp_node )
-			  goto repack;
-			else if (subtype(p)==vpack_node )
-			  goto repack;
-			else if (subtype(p)==hpack_node )
-			  goto repack;
-			else if (subtype(p)==hset_node )
-			  goto repack;
-			else if (subtype(p)==vset_node )
-			  goto repack;
-			else if (subtype(p)==stream_node )
-			  goto repack;
-			else if (subtype(p)==image_node)
-			{ if (image_xwidth(p)!=null)
-                          { pointer r=image_xwidth(p);
-                            if (xdimen_hfactor(r)==0 && xdimen_vfactor(r)==0)
-                            { if (xdimen_width(r)> w) w= xdimen_width(r); }
-                            else goto repack;
-                          }
-                          if (image_xheight(p)!=null)
-                          { pointer r=image_xheight(p);
-                            if (xdimen_hfactor(r)==0 && xdimen_vfactor(r)==0)
-			    {  x= x+d+xdimen_width(r);d=0;}
-                            else goto repack;
-                          }
-			}
-             break;
+	    switch(subtype(p))
+	    { case par_node:
+                if (depth(p) > d) d=depth(p);
+	        goto repack;
+	      case disp_node:
+	      case vpack_node:
+	      case hpack_node:
+	      case hset_node:
+      	      case vset_node:
+      	      case stream_node:
+		goto repack;
+              case image_node:
+	        if (image_xwidth(p)!=null)
+                { pointer r=image_xwidth(p);
+                  if (xdimen_hfactor(r)==0 && xdimen_vfactor(r)==0)
+                  { if (xdimen_width(r)> w) w= xdimen_width(r); }
+                  else goto repack;
+                }
+                if (image_xheight(p)!=null)
+                { pointer r=image_xheight(p);
+                  if (xdimen_hfactor(r)==0 && xdimen_vfactor(r)==0)
+		  {  x= x+d+xdimen_width(r);d=0;}
+                  else goto repack;
+                }
+                break;
+	        @<cases that flatten the color stack@>
+	    }
+            break;
           case glue_node:
             { glue_ord o;
 			  x= x+d;d= 0;
@@ -31963,8 +32554,25 @@
   pop_nest();
 }
 @*1 Page Template Definitions.
+These are the primitives needed to implement page templates:
 
-The data describing a page template is stored in a whatsit node with subtype
+@<Put each...@>=
+primitive("HINTsetpage", extension, setpage_node);@/
+@!@:setpage\_}{\.{\\setpage} primitive@>
+
+primitive("HINTstream", extension, stream_node);@/
+@!@:stream\_}{\.{\\stream} primitive@>
+
+primitive("HINTsetstream", extension, setstream_node);@/
+@!@:setstream\_}{\.{\\setstream} primitive@>
+
+primitive("HINTbefore", extension, stream_before_node);@/
+@!@:before\_}{\.{\\before} primitive@>
+
+primitive("HINTafter", extension, stream_after_node);@/
+@!@:after\_}{\.{\\after} primitive@>
+
+@ The data describing a page template is stored in a whatsit node with subtype
 |setpage_node|.
 Given a pointer |p| to such a node, here are the macros used to access the data stored there:
 
@@ -32259,6 +32867,7 @@
   @<Initialize definitions for baseline skips@>@;
   @<Initialize definitions for fonts@>@;
   @<Initialize definitions for labels@>@;
+  @<Initialize definitions for colors@>@;
 #if 0
   overfull_rule=0;    /* no overfull rules please */
 #endif
@@ -32288,6 +32897,7 @@
    @<Output baseline skip definitions@>@;
    @<Output parameter list definitions@>@;
    @<Output discretionary break definitions@>@;
+   @<Output color definitions@>@;
    @<Output page template definitions@>@;
    hput_definitions_end();
    hput_range_defs(); /* expects the definitions section to be ended */
@@ -34000,6 +34610,7 @@
   int n=new_start_link(p);
   i=b010;
   if (n>0xFF) { i|=b001; HPUT16(n);@+} @+else HPUT8(n);
+  if (color_ref(p)!=1) {i|=b100; HPUT8(color_ref(p)); }
   tag= TAG(link_kind,i);
 }
 break;
@@ -34008,6 +34619,7 @@
   int n=new_end_link();
   i=b000;
   if (n>0xFF) { i|=b001; HPUT16(n);@+} @+else HPUT8(n);
+  if (color_ref(p)!=0xFF) {i|=b100; HPUT8(color_ref(p)); }
   tag= TAG(link_kind,i);
 }
 break;
@@ -34014,8 +34626,12 @@
 case outline_node: hpos--; new_outline(p);  return;
 
 @*1 Images.
-\indent
-@<cases to output whatsit content nodes@>=
+There is a single primitive to handle images:
+@<Put each...@>=
+primitive("HINTimage", extension, image_node);@/
+@!@:HINTimage\_}{\.{\\HINTimage} primitive@>
+
+@ @<cases to output whatsit content nodes@>=
      case image_node:
         { Xdimen w={0},h={0}; List d; uint32_t pos;
           if (image_xwidth(p)!=null)



More information about the tex-live-commits mailing list.