% gerolf.tex
% ==========

% This file is part of Gerolf Markup Shredder,                  <!-- ##### -->
% written by G. D. Brettschneider (1999-2007). All rights reserved.
% Send corrections to: MarkupShredder(at)Gerolf.org (www.Gerolf.org)

% TeX programming literature:
%   Knuth, Donald Ervin: The TeXbook (1984-1996),
%     Addison-Wesley Publishing Comp., ISBN 0-201-13448-9
%   Schwarz, Norbert: Einfuehrung in TeX (1991-1993),
%     Addison-Wesley Verlag GmbH, ISBN 3-89319-345-6
%   Appelt, Wolfgang: TeX fuer Fortgeschrittene (1988),
%     Addison-Wesley Verlag GmbH, ISBN 3-89319-115-1

% 1. Basics ##################################################################

% Load third - party macros:

\input prologue.cfg

% An "\input plain.tex" command is expected to be found in "prologue.cfg".
% Plain TeX may be replaced by another file that re-defines a few basic macros
% needed by GMS, e. g. \newbox, \newcount, \newdimen, \newtocs, \newrite, 
% \newif, \loop etc.
% In Plain TeX, the "\input hyphen" command should be disabled, because GMS
% too has a pattern loading mechanism. Also, font preloading should be 
% disabled.

% Character category definitions: --------------------------------------------

% compare Knuth, pages 343-344:
  \chardef \CATescape = 0
  \chardef \CATopengroup = 1
  \chardef \CATclosegroup = 2
  \chardef \CATmathmode = 3
  \chardef \CATalignment = 4
  \chardef \CATendofline = 5
  \chardef \CATparameter = 6
  \chardef \CATsuperscript = 7
  \chardef \CATsubscript = 8
  \chardef \CATignore = 9
  \chardef \CATwhitespace = 10
  \chardef \CATletter = 11
  \chardef \CATother = 12
  \chardef \CATactive = 13
  \chardef \CATcomment = 14
  \chardef \CATinvalid = 15

% Basic category code assignments: -------------------------------------------

% This is necessary for defining macros:
  \catcode `\{ = \CATopengroup
  \catcode `\} = \CATclosegroup
  \catcode `\# = \CATparameter

\def \gcatcode {\global \catcode}

\def \CATactivelessthan {\catcode `\< = \CATactive}
\def \CATclosegroupclosebracket {\catcode `\] = \CATclosegroup}
\def \CATcommentbar {\catcode `\| = \CATcomment} 
\def \CATcommenthashmark {\catcode `\# = \CATcomment} 
\def \CATescapelt {\catcode `\< = \CATescape}  
\def \CATletterexclamation {\catcode `\! = \CATletter} 
\def \CATletterhyphen {\catcode `\- = \CATletter} 
\def \CATothergt {\catcode `\> = \CATother} 
\def \CATopengroupopenbracket {\catcode `\[ = \CATopengroup}
\def \CATotherampersand {\catcode `\& = \CATother}
\def \CATotherclosebrace {\catcode `\} = \CATother}
\def \CATotherhashmark {\catcode `\# = \CATother}
\def \CATotherlessthan {\catcode `\< = \CATother}
\def \CATotheropenbrace {\catcode `\{ = \CATother}
\def \CATotherpercent {\catcode `\% = \CATother}
\def \CATothertilde {\catcode `\~ = \CATother}
\def \CATparameterat {\catcode `\@ = \CATparameter}
\def \CATparameterdegree {\catcode `\° = \CATparameter}
\def \CATwhitespacegt {\catcode `\> = \CATwhitespace} 
\def \CATwhitespaceslash {\catcode `\/ = \CATwhitespace}

\def \CATentity {%
  \CATescapelt \CATletterexclamation \CATletterhyphen
  \CATotherampersand \CATotherhashmark \CATothergt \CATparameterat}

\def \CATreference {%
  \CATotherhashmark \CATotherampersand \CATparameterdegree}

\def \CATstylegap {%
  \CATclosegroupclosebracket \CATopengroupopenbracket
  \CATotherclosebrace \CATotheropenbrace}

% This is what initex and "plain.tex" do (Characters not mentioned here
% are assumed to be letters (A-Z, a-z) or other):

\def \endmarkupCAT {%
  \global \catcode 0 = \CATignore % nul
  \global \catcode 1 = \CATsubscript % start of heading
  \global \catcode 9 = \CATwhitespace % horizontal tabulator
  \global \catcode 11 = \CATsuperscript % vertical tabulator
  \global \catcode 12 = \CATactive % form feed
  \global \catcode 13 = \CATendofline % carriage return
  \global \catcode `\  = \CATwhitespace % &32#;
  \global \catcode `\# = \CATparameter % &35#;
  \global \catcode `\$ = \CATmathmode % &36#;
  \global \catcode `\% = \CATcomment % &37#;
  \global \catcode `\& = \CATalignment % &38#;
  \global \catcode `\< = \CATother % &#60;
  \global \catcode `\\ = \CATescape % &92#;
  \global \catcode `\^ = \CATsuperscript % &94#;
  \global \catcode `\_ = \CATsubscript % &95#;
  \global \catcode `\{ = \CATopengroup % &123#;
  \global \catcode `\} = \CATclosegroup % &125#;
  \global \catcode `\~ = \CATactive % &126#;
  \global \catcode 127 = \CATinvalid} % delete

\endmarkupCAT 
  \outer \def ^^L{\par} % &#12; form feed
  \def \activateshredder {%
    \catcode `\< = \CATactive
    \catcode `\# = \CATother
    \catcode `\~ = \CATother}
  \activateshredder
  \def \enableshredder {\let < = \TAGget}
  \def \shredder {\activateshredder \enableshredder}
\endmarkupCAT

% So far, the "plain.tex" assignments will not interfere with Markup Shredder.

  \let \CHARampersand \relax
  \let \CHARhashmark \relax

  \def \preamble {\CHARhashmark \CHARampersand \CHARampersand \CHARhashmark}

  \let \CHARampersand = &
  \let \CHARhashmark = #

  \def \beginhalign {%
    \halign \expandafter \bgroup \preamble \cr}

% Character category changes for input files using html-style markup: --------

% The less-then sign "<" must be made an active character, because texts using
% "html-style" markup are expected as input. Other TeX macro files must be
% loaded before this is done (via "epilogue.cfg").

% This will be executed by the <html> start tag  ("<" is no longer active then
% <!-- in order to allow comments that include <tags> like this one-->):

\def \beginmarkupCAT {%
  \global \catcode 0 = \CATother % nul
  \global \catcode 1 = \CATother % start of heading
  \global \catcode 9 = \CATwhitespace % horizontal tabulator
  \global \catcode 11 = \CATother % vertical tabulator
  \global \catcode 12 = \CATother % form feed
  \global \catcode 13 = \CATwhitespace % carriage return
  \global \catcode `\  = \CATwhitespace % &32#;
  \global \catcode `\# = \CATother % &35#;
  \global \catcode `\$ = \CATother % &36#;
  \global \catcode `\% = \CATother % &37#;
  \global \catcode `\& = \CATother % &38#;
  \global \catcode `\< = \CATactive % &#60;
  \global \catcode `\\ = \CATother % &92#;
  \global \catcode `\^ = \CATother % &94#;
  \global \catcode `\_ = \CATother % &95#;
  \global \catcode `\{ = \CATother % &123#;
  \global \catcode `\} = \CATother % &125#;
  \global \catcode `\~ = \CATother % &126#;
  \global \catcode 127 = \CATother} % delete

% This is used locally, e. g. to skip JavaScripts:

\def \beginscriptCAT {%
  \catcode `\# = \CATother % &35#;
  \catcode `\$ = \CATother % &36#;
  \catcode `\% = \CATother % &37#;
  \catcode `\& = \CATother % &38#;
  \catcode `\< = \CATother % &#60;
  \catcode `\\ = \CATother % &92#;
  \catcode `\^ = \CATother % &94#;
  \catcode `\_ = \CATother % &95#;
  \catcode `\{ = \CATother % &123#;
  \catcode `\} = \CATother % &125#;
  \catcode `\~ = \CATother}% &126#;

% Information about this software: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def \GMSformat  {gerolf}
\def \GMSname    {Gerolf Markup Shredder}
\def \GMSversion {0.07a}%                                       <!-- ##### -->
\def \GMSdate    {20071109}%                                    <!-- ##### -->

\def \GMSauthor  {G. D. Brettschneider}
\def \GMSaddress {Luchtbergstrasse 27, D-28237 Bremen, Germany}
\def \GMSdomain  {www.Gerolf.org}
\def \GMSemail   {MarkupShredder(a)Gerolf.org}

\def \GMScopyright {%                                           <!-- ##### -->
  Copyright (c) 1999 - 2007 by
  Gerolf Diethelm Brettschneider,
  Luchtbergstrasse 27, D-28237 Bremen.  
  All rights reserved. This GMS
  software comes without ANY warrenty.
  You may freely distribute and use it.}

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\tracingstats = 1

% Lines and messages: --------------------------------------------------------

\def \CONSTspace { }
\def \CONSThyphen {-}
\def \CONSThalfline {------}
\def \CONSTline {\CONSThalfline \CONSThalfline}
\def \CONSTlongline {\CONSTline \CONSTline \CONSTline \CONSTline \CONSTline}
\def \CONSThalfLINE {======}
\def \CONSTLINE {\CONSThalfLINE \CONSThalfLINE}
\def \CONSTlongLINE {\CONSTLINE \CONSTLINE \CONSTLINE \CONSTLINE \CONSTLINE}

\def \predashes {\ifcase \count 1
  \or -\or --\or ---\or \temponumber
  \or -----\or --\temponumber \else ?\fi}
\def \postdashes {\ifcase \count 4
  \or -\or --\or ---\or ----\or -----\or
  \CONSThalfline \or \CONSThalfline -\or
  \CONSThalfline --\or \CONSThalfline ---\or
  \CONSThalfline ----\or \CONSThalfline -----\or
  \CONSTline \or -\CONSTline \else ?\fi}

\def \dotmessage {\message {.}}
\def \hyphenmessage {\message {-}}
\def \fillmessage #1#2#3#4{{%
  \count 1 = #1 \count 4 = #4
  \def \temposecond {#2}%
  \ifx \temposecond \CONSThyphen \def \temponumber {----}%
  \else \def \temponumber { #2 -}\fi
  \message {\predashes <#3>\postdashes \CONSTlongline}}}

\def \GMScodepage {CP1252}
\def \GMSwelcome {\fillmessage 0-{GMS}{13}}
\def \GMSgoodbye {\fillmessage 0-{/GMS}{12}}
\def \GMSbeginabout {\message {This is \GMSname,
  Version \GMSversion, written by \GMSauthor}}
\def \GMSendabout {\message {Release: \GMSdate \CONSTspace |
  Domain: \GMSdomain \CONSTspace | Mail: \GMSemail}}

% Load interface and modules: ------------------------------------------------

\GMSwelcome
 \GMSbeginabout
  \fillmessage 2-{initialize}4
   \fillmessage 41{interface}3

% Fixme: lowercase functions without uppercase prefix should be backed up

\let \mef \mathchardef
 
\let \neb \newbox
\let \nec \newcount
\let \ned \newdimen
\let \net \newtoks
\let \new \newif

% Variables: -----------------------------------------------------------------

\net \FONTmonospace 
\net \FONTsansserif 
\net \FONTserif
\let \LINEheight \baselineskip
\ned \LINEheightpageno
\def \LINEupskip {\vskip -\LINEheight}
\ned \TEXTheight
\ned \TEXTwidth

\new \ifCLASSpredefined
\new \ifEND
\new \ifGEDCOM
\new \ifLINEheightgiven
\new \ifOPENbouter
\new \ifOPENcomment
\new \ifOPENdlcompact
\new \ifOPENfloatsuppress
\new \ifOPENfontinner
\new \ifOPENfontouter
\new \ifOPENform
\new \ifOPENh
\new \ifOPENiouter
\new \ifOPENparinner
\new \ifOPENparouter
\new \ifOPENstyle
\new \ifSCRIPTother
\new \ifTEXTindentgiven
\new \ifvalueNUMBER

\let \HYPHENtables \empty
\let \INDENTinputtype \empty
\let \INDENTinputvalue \empty  
\let \NAMESPACE \empty
\let \OBJECTtype \empty
\let \POSTfamilies \empty
\def \REFeuro {80}
\let \SCRIPTtype \empty
\let \TEXTindent \parindent

% Literature: Donald Ervin Knuth, "The TeXbook" (1984-1996), Appendix B and D.

% Abbreviations: -------------------------------------------------------------

\def \glet {\global \let}

\def \ldef {\long \def}
\def \gldef {\global \long \def}

\def \begintrace {%
  \global \tracingmacros = 3 \global \tracingcommands = 1 }

\def \endtrace {%
  \global \tracingmacros = 0 \global \tracingcommands = 0 }

% Indirect definitions: ------------------------------------------------------

% These definitions can have non-letters in their names (see Knuth, page 375):

\def \Def #1 #2{%
  \csname expandafter\endcsname \def
  \csname #1\endcsname {#2}}

\def \gDef #1 #2{%
  \csname expandafter\endcsname \gdef
  \csname #1\endcsname {#2}}

\def \eDef #1 #2{%
  \csname expandafter\endcsname \edef
  \csname #1\endcsname {#2}}

\ldef \lDef #1 #2{%
  \csname expandafter\endcsname \ldef
  \csname #1\endcsname {#2}}

\ldef \glDef #1 #2{%
  \csname expandafter\endcsname \gldef
  \csname #1\endcsname {#2}}

\def \unDef #1{% clear memory
  \csname expandafter\endcsname \let
  \csname #1\endcsname \undefined}

\def \xDef #1 #2{%
  \csname expandafter\endcsname \xdef
  \csname #1\endcsname {#2}}

% Search an expandable command (control sequence definition check): ----------

% compare Knuth, pages 40 and 308; similar to e-TeX's \ifcsname...\endcsname:

\new \ifDEF

\def \DEFsearch #1{\expandafter
  \ifx \csname #1\endcsname \relax \DEFfalse \else \DEFtrue \fi}

\def \blap #1{\vbox to 0pt {#1\vss}}
\def \tlap #1{\vbox to 0pt {\vss #1}}

\bgroup
  \catcode`\^ = \CATsuperscript
  \gdef \^^M{\ } % carriage return = space
\egroup

% System functions: ----------------------------------------------------------

% Log file messages:

\def \echo #1{%
  \immediate \backupwrite 16 {#1}}

\def \noecho {%
  \echo {}}

% System commands:
\def \system #1{%
  \immediate \backupwrite 18 {#1}}

% Count files on Dos:
\def \NOfilemax {1234567}% may be redefined to e.g. 16 on Dos via 'files.cfg'

\def \Message #1{\message {<#1>}}

\ifx \pdfpagewidth \undefined
  \echo {! Unsupported: PDF output (pdfTeX required). Writing DVI instead. }%
\fi

% 2. Functions ###############################################################
  
% ALIGN: =====================================================================

% compare Knuth, pages 107, 317, 353 and 356:

\new \ifALIGN
  
\new \ifALIGNcenter

\def \ALIGNend {%
  \ifALIGNcenter \hskip \parfillskip \else 
    \ifx \BIDI \CONSTltr \ifALIGNright \else \hfill \fi \fi \fi}  
    
\new \ifALIGNleft

\def \ALIGNrespace {%
  \spaceskip = 0.3333em \xspaceskip = 0.5em } 
  
\new \ifALIGNright

\def \ALIGNtextbyvalue {%
  \VALUElowercaseget \ALIGNtextragging \VALUElowercase}  

\def \ALIGNtextcenter {%
  \ALIGNtextragging \CONSTcenter}      

\def \ALIGNtextleft {%
  \ALIGNtextragging \CONSTleft}

  \def \ALIGNtextragging #1{%
    \edef \test {#1}%
    \ALIGNleftfalse \ALIGNcenterfalse \ALIGNrightfalse
    \ifx \test \CONSTleft \ALIGNtextraggingright \ALIGNlefttrue 
    \else \ifx \test \CONSTcenter \ALIGNtextraggingcenter \ALIGNcentertrue
    \else \ifx \test \CONSTright \ALIGNtextraggingleft \ALIGNrighttrue 
    \else \ifx \test \CONSTmiddle \VERIFYerroryoumeantcenter 
      \ALIGNtextraggingcenter \ALIGNcentertrue \fi \fi \fi \fi} 
    
    \def \ALIGNtextraggingany {%
      \parindent = 0pt \parfillskip = \parindent
      \ALIGNrespace \hbadness = 10000 \relax}  
    
    \def \ALIGNtextraggingcenter {%
      \leftskip = 0pt plus 2em \rightskip = \leftskip \ALIGNtextraggingany}
  
    \def \ALIGNtextraggingleft {%
      \leftskip = 0pt plus 2em \ALIGNtextraggingany}

    \def \ALIGNtextraggingright {%
      \rightskip = 0pt plus 2em \ALIGNtextraggingany}        
      
% ANCHOR: ====================================================================

% \Def \CONSTSTYLE a:link {\COLORsetlink} % Fixme
% \Def \CONSTSTYLE a:visited {\COLORsetvlink}

% Fixme: line and page breaks, outsource \GAPwrite 

% Fixme: This may produce masses of control sequences.
% Define limit of destinations to be checked in typeset.cfg
  
\def \ANCHORadd {%
  \DEFsearch {\CONSTdest \ANCHORfirst}\ifDEF
    \VERIFYerrorduplicate \ANCHORfirst
  \else \pdfdest name {\ANCHORfirst} fit\relax 
    % fith, fitv, fitb, fitbh, fitbv
    \xDef {\CONSTdest \ANCHORfirst} {}\fi}
  \ifx \pdfdest \undefined \let \ANCHORadd \relax \fi

\def \ANCHORbegin {% <a>
  \ifLINKunrendered \else \ifLINKunlinked \else 
    \ifx \URLhref \empty 
      \ifx \LINKname \empty 
        \ifx \LINKid \empty \VERIFYerrorunanchored \fi
      \else \ANCHORbyname \LINKname \fi
    \else 
      \ifx \LINKname \empty \else \ANCHORbyname \LINKname \fi 
      \ANCHORbegindo \URLhref \fi \fi \fi}
      
  \def \ANCHORbegindo #1{%
    \edef \ANCHORfirst {#1}%
    \ifx \ANCHORfirst \empty \else \ANCHORbegindohref \fi}
    
    \def \ANCHORbegindoit {%
      \ANCHORedtrue
      \hskip 0mm % get into horizontal mode
      \bgroup
        \pdflinkmargin = 0ex \ANCHORedtrue
        \ifANCHORheightgiven \ANCHORbegindoitheight
        \else \ANCHORbegindoitnoheight \fi}
      \ifx \pdfdest \undefined \let \ANCHORbegindoit \relax \fi
      
      \def \ANCHORbegindoitheight {%
        \pdfstartlink height \ANCHORheight 
          \CONSTspace depth 0pt \CONSTspace}
        \ifx \pdfdest \undefined \let \ANCHORbegindoitheight \relax \fi
        
      \def \ANCHORbegindoitnoheight {%
        \pdfstartlink height 0.7\LINEheight %%%
          \CONSTspace depth 0.3\LINEheight \CONSTspace} %%%
        \ifx \pdfdest \undefined \let \ANCHORbegindoitnoheight \relax \fi

    \def \ANCHORbegindohref {%
      \let \ANCHORext \empty
      \let \ANCHORint \empty
      \URLinternetfalse \URLget \ANCHORfirst
      \ifURLinternet \ANCHORbegindohrefext 
      \else \ANCHORbegindohrefint \fi}

      \def \ANCHORbegindohrefext {%
        \ifx \ANCHORext \ANCHORint \else
          \edef \ANCHORext {\ANCHORext \CONSThashmark \ANCHORint }\fi
        \ANCHORbegindohrefextstart \ANCHORext}

        \def \ANCHORbegindohrefextstart #1{% external destination
          \ANCHORbegindoit
            attr {/C [\the \COLORanchorext] /Border [0 0 1] }%
            user {/Subtype /Link /A << /Type /Action /S /URI /URI (#1) >>}%
          \egroup}          
    
    \def \ANCHORbegindohrefint {%
      \ifx \ANCHORint \empty \ANCHORbegindohrefintempty 
      \else \ANCHORbegindohrefintstart \ANCHORint \fi} 
      
      \def \ANCHORbegindohrefintstart #1{% internal destination
        \ANCHORbegindoit
          attr {/C [\the \COLORanchorint] /Border [0 0 1] }%
          goto name {#1}%
        \egroup}  

      \def \ANCHORbegindohrefintempty {%
        \expandafter \CHAINcopyrelativepath \ANCHORfirst \to \ANCHORint 
        \ANCHORbegindohrefintstart \ANCHORint}        

\def \ANCHORbychain #1{% <link>
  \edef \ANCHORfirst {#1}%
  \ifx \ANCHORfirst \empty \else \ANCHORadd \fi}
    
\def \ANCHORbyname #1{% <a name = "...">, <link id = "...">
  \edef \ANCHORfirst {#1}%
  \message {[\ANCHORfirst]}%
  \ifx \ANCHORfirst \empty \else \ANCHORadd \fi} 

\new \ifANCHORed

\def \ANCHORend {% </a>
  \ifLINKunrendered \else \ifLINKunlinked \else
    \ifx \URLhref \empty \else 
      \ifvmode \leavevmode \fi \ANCHORenddo\fi % Fixme: not if nameLINK
  \fi \fi
  \ifANCHORed \ANCHORenddo \fi} % Fixme: check if-structure
  
  \def \ANCHORenddo{%   
    \GAPwrite
    \ifANCHORed \pdfendlink \fi
    \ANCHORedfalse}
    \ifx \pdfdest \undefined \let \ANCHORenddo \relax \fi
    
\def \ANCHORgedcom {%    
  \ANCHORinit \ELEMENTvalueget \ANCHORbegin 
  \global \GAP = {=>}\GAPwrite \ANCHORend} 
    
\ned \ANCHORheight

\new \ifANCHORheightgiven

\def \ANCHORinit {% <a>
  \glet \LINKname \empty
  \glet \URLhref \empty}
       
% ATT: =======================================================================

\new \ifATT % Section restructured (20070202)

\let \ATTactual \relax

\let \ATTfirst \empty
\let \ATTfirstunquoted \empty
         
\let \ATTfourth \empty

\def \ATTget {%
  \edef \ATTthirdtest {\the \ATTlist}%
    \expandafter \ATTlistparse \ATTthirdtest ... = "GMS-STOP"}
    
\net \ATTlist

  \new \ifATTlistall  
  \new \ifATTlistmissingquotes  
        
  \ldef \ATTlistparse #1#2=#3"#4"{%
    \lowercase {\edef \ATTfirst {#1#2}}%
    \edef \ATTthird {#3}%
    \edef \ATTfourth {#4}%
    \ifx \ATTfourth \CONSTpar \let \ATTfourth \CONSTthatsall \fi
    \let \ATTactual \ATTlistparse
    \ATTlistmissingquotesfalse 
    \let \ATTlistparsenext \relax
    \ifx \ATTfourth \CONSTthatsall \ATTlistalltrue \else
      \ifx \ATTfourth \CONSTstopmark \else
        \ATTlistparsecheck #4 ... = \relax \fi \fi
    \ifx \ATTthird \empty
      \let \ATTlistparsenext \ATTthirdempty
    \else \ifx \ATTthird \CONSTspace
      \let \ATTlistparsenext \ATTthirdempty
    \else \ifx \ATTfourth \empty
      \let \ATTlistparsenext \ATTthirdgiven
    \else \let \ATTlistparsenext \ATTlistparsefourth \fi \fi \fi 
    \ATTlistparsenext
    \ifATTlistall \let \ATTactual \ATTunquotedstop \fi
    \ATTactual}    
  
    \def \ATTlistparsecheck #1 ... = #2\relax {%
      \VALUE = {#1}% %%%
      \edef \ATTlistparsechecktest {#2}%
      \ifx \ATTlistparsechecktest \CONSTthatsall 
        \edef \ATTthird {#1}\ATTlistalltrue
      \else \ATTlistallfalse \fi} 
      
      \let \ATTlistparsechecktest \empty
      
    \def \ATTlistparsefourth {%
      \ifx \ATTfourth \CONSTstopmark 
        \let \ATTlistparsefourthnext \ATTlistparsefourthstop
        \let \ATTactual \relax
      \else \let \ATTlistparsefourthnext \ATTlistparsefourthrun \fi
      \ATTlistparsefourthnext}

      \def \ATTlistparsefourthrun {%
        \edef \ATTlistparsefourthprobe {%
          \ATTfirst = \ATTthird \CONSTspace \CONSTspace GMS-STOP }%
        \expandafter \ATTunquotedparse \ATTlistparsefourthprobe 
        \VALUE = \expandafter {\ATTfourth}%
        \edef \ATTlistparsefourthprobe {%
          \attYETfirst \CONSTspace \ATTfourth}%
        \expandafter \attYETparse \ATTlistparsefourthprobe \relax}

      \def \ATTlistparsefourthstop {%
        \edef \ATTlistparsefourthprobe {%
          \ATTfirst = \ATTthird \CONSTspace \CONSTspace GMS-STOP }%
        \expandafter \ATTunquotedparse \ATTlistparsefourthprobe}
                                      
    \let \ATTthird \empty

    \def \ATTthirdempty {%
      \ifx \ATTfourth \CONSTstopmark 
        \let \ATTactual \relax
      \else \ATTthirdemptydo \fi}
      
      \def \ATTthirdemptydo {%
        \ifATTlistall \let \ATTactual \relax
        \else \let \ATTactual \ATTlistparse \fi
        \ifATTlistmissingquotes \else 
          \VALUE = \expandafter {\ATTfourth}%
          \edef \attSTOPdoprobe {\ATTfirst \CONSTspace}%
          \expandafter \attYETparse \attSTOPdoprobe \relax \fi}
        
    \def \ATTthirdgiven {%
      \ATTlistmissingquotestrue
      \edef \ATTthird {\ATTthird \CONSTspace}%
      \expandafter \ATTthirdgivenparse \ATTthird \relax
      \edef \ATTthirdgiventest {\ATTfirst \CONSTspace}%
      \expandafter \attYETparse \ATTthirdgiventest \relax 
      \ifx \ATTfourth \CONSTstopmark 
        \let \ATTthirdgivennext \ATTthirdgivenstop
      \else \let \ATTthirdgivennext \ATTthirdgivenrun \fi 
      \ATTthirdgivennext}                     
          
      \def \ATTthirdgivenparse #1 #2 #3\relax {%      
        \ifx \ATTfirst \CONSTendmarkdots \VALUE = {}%
          \let \ATTthirdtest \empty
        \else \DEFsearch {\CONSTatt \ATTfirst}%
          \ifDEF \ATTthirdgivenparseit {#1}{#2 #3}%
          \else \DEFsearch {\CONSTtag \the \ELEMENT
            \CONSTatt \ATTfirst}%
             \ifDEF \ATTthirdgivenparseit {#1}{#2 #3}%
             \else \ATTthirdgivenparseit {#2}{#3}\fi \fi \fi
        \ifx \ATTthirdtest \empty \ATTunquotedfalse 
        \else \ifx \ATTthirdtest \CONSTendmark \ATTunquotedfalse 
        \else \ifx \ATTthirdtest \CONSTendmarktwo \ATTunquotedfalse 
        \else \ifx \ATTthirdtest \CONSTendmarkequal \ATTunquotedfalse
        \else \ATTunquotedtrue \fi \fi \fi \fi}
          
        \def \ATTthirdgivenparseit #1#2{%
          \VALUE = \expandafter {#1}%
          \edef \ATTthirdtest {#2}}
          
      \def \ATTthirdgivenrun {%
        \edef \test {%
          \ATTfirst = \ATTthird \CONSTspace \CONSTspace GMS-STOP }%
        \expandafter \ATTunquotedparse \test}

      \def \ATTthirdgivenstop {%
        \edef \test {%
          \ATTfirst \CONSTspace \ATTthird \CONSTspace ...}%
        \expandafter \ATTthirdgivenstopparse \test \relax} 
    
        \def \ATTthirdgivenstopparse #1 #2 ...#3\relax {%
          \let \ATTactual \relax
          \VALUE = {#2}%
          \edef \ATTthirdgivenstopparseprobe {#1 #2}%
          \expandafter \attYETparse \ATTthirdgivenstopparseprobe \relax 
          \VERIFYerrorunquot}
        
  \let \ATTthirdtest \empty
  
  \new \ifATTunquoted  
  
  \new \ifATTunquotedmessage
    
  \ldef \ATTunquotedparse #1=#2#3 {%
    \def \ATTfirstunquoted {#1}%
    \edef \ATTunquotedparsesecond {#2}%
    \ifx \ATTunquotedparsesecond \CONSTapostroph   
      \VERIFYerrorapostrophized \ATTunquotedparseapos #3'\relax
    \else \edef \ATTunquotedsecondthird {#2#3}%
      \ATTunquotedparsedo \fi
    \ifx \ATTunquotedparsesecond \CONSTpar 
      \let \ATTunquotedparsenext \relax \fi 
    \ATTunquotedparsenext}

    \def \ATTunquotedparseapos #1'#2\relax {%
      \edef \ATTunquotedparseapostest {#2}%
      \ifx \ATTunquotedparseapostest \empty 
%%      \let \ATTunquotedparsenext \ATTunquotedparseaposdo
        \let \ATTunquotedparsenext \ATTunquotedgulp %% 
      \else \let \ATTunquotedparsenext \ATTunquotedgulp
        \VALUE = \expandafter {#1}%
        \edef \ATTunquotedparseaposprobe {%
          \ATTfirstunquoted \CONSTspace #1}%
        \expandafter \attYETparse \ATTunquotedparseaposprobe \relax \fi}  
      
      \ldef \ATTunquotedparseaposdo #1'#2GMS-STOP#3{% Fixme: discarding value
        \edef \ATTunquotedparseapostest {#3}\let \ATTactual \relax
        \ifx \ATTunquotedparseapostest \CONSTquotmark 
          \let \ATTunquotedparseapostest \relax \fi 
        \ATTunquotedparseapostest}  
  
    \def \ATTunquotedparsedo {%
      \ifx \ATTunquotedsecondthird \CONSTstopmark
        \ATTunquotedparsedostop
      \else \ATTunquotedparsedorun \fi}      
        
      \def \ATTunquotedparsedorun {%
        \VALUE = \expandafter {\ATTunquotedsecondthird}%
        \edef \ATTunquotedparseall {%
          \ATTfirstunquoted \CONSTspace \ATTunquotedsecondthird}%
        \expandafter \attYETparse \ATTunquotedparseall \relax 
        \VERIFYerrorunquot
        \ifATTlistall \let \ATTunquotedparsenext \ATTunquotedgulp
        \else \let \ATTunquotedparsenext \ATTunquotedparse \fi}
  
      \def \ATTunquotedparsedostop {%
        \ifx \ATTfourth \CONSTstopmark
          \let \ATTunquotedparsenext \relax
        \else \ATTunquotedparsedostoppass \fi} 
  
        \def \ATTunquotedparsedostoppass {%
          \VALUE = \expandafter {\ATTfourth}%
          \edef \ATTunquotedparseall {%
            \ATTfirstunquoted \CONSTspace \ATTfourth}%
          \expandafter \attYETparse \ATTunquotedparseall \relax
          \let \ATTunquotedparsenext \relax}  

    \ldef \ATTunquotedgulp #1GMS-STOP{%
      \let \ATTactual \relax
      \edef \ATTunquotedgulptest {#1}%  FIXME!
      \ifx \ATTunquotedgulptest \CONSTspace 
        \let \ATTunquotedgulptest \ATTunquotedstop
      \else \ifx \ATTunquotedgulptest \CONSTattstop
        \let \ATTunquotedgulptest \relax \ATTlistallfalse     
      \else \ifx \ATTunquotedgulptest \CONSTattstopspace 
        \let \ATTunquotedgulptest \relax \ATTlistallfalse      
      \else \let \ATTunquotedgulptest \relax \fi \fi \fi \ATTunquotedgulptest}  
          
  \ldef \ATTunquotedstop #1GMS-STOP#2{%
    \edef \attSTOPquotequlptest {#2}%
    \let \ATTactual \relax 
    \ifx \attSTOPquotequlptest \CONSTquotmark 
      \let \attSTOPquotequlptest \relax \fi 
    \attSTOPquotequlptest}
      
% attYET: --------------------------------------------------------------------  
  
  \let \attYETfirst \empty
      
  \ldef \attYETparse #1 #2\relax {%
    \lowercase {\edef \attYETfirst {#1}}\attYETparsedo}
    
    \def \attYETparsedo {%
      \let \attYETparsedonext \relax
      \ifx \attYETfirst \CONSTstyle 
        \PROPtrue \PROPlist = \VALUE 
      \else \ifx \attYETfirst \CONSTclass 
        \attYETparsedoclass 
      \else \attYETparsedoelement \fi \fi 
      \attYETparsedonext}      

      \def \attYETparsedoclass {%    
        \VALUElowercaseget \let \attYETclassdotest \VALUElowercase
        \DEFsearch {\CONSTCLASS \attYETclassdotest}%
        \ifDEF \CLASSpredefinedtrue
          \csname \CONSTCLASS \attYETclassdotest \endcsname \fi
        \DEFsearch {\CONSTSTYLE \attYETclassdotest}%
        \ifDEF \attYETparsedoclassprop \else
          \DEFsearch {\CONSTSTYLE \the \ELEMENT .\attYETclassdotest}%
          \ifDEF \attYETparsedoclassstyle \else \ifCLASSpredefined \else
            \VERIFYerrorundefclass \attYETclassdotest \fi \fi \fi}

        \def \attYETparsedoclassprop {%
          \def \attYETparsedonext {\expandafter \PROPlistget
            \csname \CONSTSTYLE \VALUElowercase \endcsname}}

        \def \attYETparsedoclassstyle {%
          \def \attYETparsedonext {%
            \expandafter \PROPlistget \csname 
              \CONSTSTYLE \the \ELEMENT .\VALUElowercase \endcsname}}    

      \def \attYETparsedoelement {%
        \DEFsearch {\CONSTtag \the \ELEMENT \CONSTatt \attYETfirst}%
        \ifDEF \attYETparsedoelementattnext 
        \else \attYETparsedoelementnext \fi}

        \def \attYETparsedoelementattnext {%
          \def \attYETparsedonext {%
            \csname \CONSTtag \the \ELEMENT 
              \CONSTatt \attYETfirst \endcsname}}
    
        \def \attYETparsedoelementnext {%
          \DEFsearch {\CONSTatt \attYETfirst}%
          \ifDEF \def \attYETparsedonext {%
            \csname \CONSTatt \attYETfirst \endcsname }\else
            \let \attYETparsedonext \relax 
            \VERIFYerrorunrecogattprop \attYETfirst \fi}
            
% BACKGROUND: ================================================================

\new \ifBACKGROUND
  
\def \BACKGROUNDcolorsetbody {%
  \edef \BACKGROUNDtest {\the \VALUE \CONSTspace}%
  \expandafter \BACKGROUNDcolorsetbodydo \BACKGROUNDtest \relax}
  
  \def \BACKGROUNDcolorsetbodydo #1 #2\relax {%
    \edef \BACKGROUNDcolorsetbodydosecond {#2}%
    \ifx \BACKGROUNDcolorsetbodydosecond \empty
      \BACKGROUNDgiventrue \COLORsetbg
      \ifcolorGETanyfailed \COLORbgfalse \else 
        \COLORbgbodytrue \edef \COLORbgbody {\COLORbackground}\fi
    \else \VERIFYerrorunsuppattprop \CONSTbackground \fi}
        
\def \BACKGROUNDgeturl #1{%
  \expandafter \BACKGROUNDgeturlparse #1 url(none)\relax}

  \def \BACKGROUNDgeturlparse #1url(#2)#3\relax {%
    \edef \BACKGROUNDsource {#2}\BACKGROUNDload}

\new \ifBACKGROUNDgiven

\ned \BACKGROUNDheight

\def \BACKGROUNDload {%
  \let \FILEname \CONSTnone
  \let \FILEsource \BACKGROUNDsource
  \IMAGEheight = 0mm \IMAGEwidth = 0mm 
  \FILEnameget
  \ifx \FILEname \CONSTdotslashnonejpg 
    \global \BACKGROUNDfalse
  \else \FILEsearch \FILEname 
    \ifFILEexist \BACKGROUNDloaddo \else
      \expandafter \FILEsearchimage \FILEname .jpg\relax 
      \ifFILEexist \BACKGROUNDloaddo \else 
        \VERIFYerrorabsent \FILEname \fi \fi \fi}

  \def \BACKGROUNDloaddo {%
    \xdef \BACKGROUNDimage {\FILEname}%
    \ifx \FILEname \CONSTnone \else
      \verifyWELLFORMtotalfileadvance \ifFILEtoomany \else
      \BACKGROUNDloaddoit \fi \fi} 

    \def \BACKGROUNDloaddoit {%
      \global \BACKGROUNDtrue
      \IMAGEsizedefault
      \IMAGEscaleput \empty \empty
      \setbox \IMAGEbox = \hbox {\IMAGErunput}%
      \IMAGEwidth = \wd \IMAGEbox
      \IMAGEheight = \ht \IMAGEbox
      \global \BACKGROUNDheight = \IMAGEheight
      \global \BACKGROUNDwidth = \IMAGEwidth}
  
\def \BACKGROUNDmake {{%
  \let \FILEname \BACKGROUNDimage   
  \FILEsearch \FILEname \ifFILEexist 
    \IMAGEscaleput \BACKGROUNDheight \BACKGROUNDwidth
    \vbox to 0mm {\vskip -\OUTPUTmargintop 
      \hbox to 0mm {\hskip -\OUTPUTmarginleft
        \ifBACKGROUNDnorepx \BACKGROUNDmakenorepx 
        \else \BACKGROUNDmakerepx \fi 
        \hss }\vss }\fi}}
        
  \def \BACKGROUNDmakenorepx {%
    \ifBACKGROUNDnorepy \hbox {\IMAGErunput}%
    \else \BACKGROUNDmakenorepxdo {\hbox {\IMAGErunput}}\fi}

  \def \BACKGROUNDmakenorepxdo #1{{%
    \vbox {\loop \ifdim \OUTPUTheight > 0mm
      #1\advance \OUTPUTheight by -\BACKGROUNDheight \repeat}}}  
        
  \def \BACKGROUNDmakerepx {%
    \ifBACKGROUNDnorepy \BACKGROUNDmakerepxdo
    \else \BACKGROUNDmakenorepxdo \BACKGROUNDmakerepxdo \fi}    
     
    \def \BACKGROUNDmakerepxdo {{%
      \hbox {\loop \ifdim \OUTPUTwidth > 0mm 
        \IMAGErunput \advance \OUTPUTwidth by -\BACKGROUNDwidth \repeat}}}
        
\new \ifBACKGROUNDnorepx
\new \ifBACKGROUNDnorepy

\def \BACKGROUNDsetrepeat {%
  \edef \BACKGROUNDrepeattest {\the \VALUE}%
  \ifx \BACKGROUNDrepeattest \CONSTrepeatx
    \global \BACKGROUNDnorepxfalse
    \global \BACKGROUNDnorepytrue 
  \else \ifx \BACKGROUNDrepeattest \CONSTrepeaty 
    \global \BACKGROUNDnorepxtrue 
    \global \BACKGROUNDnorepyfalse 
  \else \BACKGROUNDsetrepeatno \fi \fi}   

  \def \BACKGROUNDsetrepeatno {%
    \ifx \BACKGROUNDrepeattest \CONSTnorepeat 
      \global \BACKGROUNDnorepxtrue 
      \global \BACKGROUNDnorepytrue 
    \else \global \BACKGROUNDnorepxfalse 
      \global \BACKGROUNDnorepyfalse \fi}     

\def \BACKGROUNDsourceset {%
  \edef \BACKGROUNDsource {\the \VALUE}}

\ned \BACKGROUNDwidth 
  
% BACKUP: ====================================================================

% Tags and gap contents must be backed up for analyzing tables (2005/10/21):

% Fixme: always clear memory afterwards

\new \ifBACKUP 
  
\nec \BACKUPnest 
\nec \BACKUPno 

\let \BACKUPnocols \empty % stack 
\let \BACKUPnorows \empty % stack 

\nec \BACKUPnotable

\let \BACKUPnotables \empty % stack

\newif \ifBACKUPpop

\def \BACKUPpop {% 
  \global \BACKUPpopfalse
  \global \BACKUPno = 0
  \BACKUPpoploop \ifnum \BACKUPno < \BACKUPstop 
    \BACKUPpopdo \BACKUPpoplooprepeat
  \global \BACKUPno = 0 }

  \def \BACKUPpopdo {%
    \global \advance \BACKUPno by 1 
    \edef \BACKUPpopprobe {% recall tag
      \csname BKPt\the \BACKUPno \endcsname \CONSTspace}%  
    \expandafter \BACKUPpopdoparse \BACKUPpopprobe \relax 
    \edef \BACKUPpopprobe {% recall gap
      \csname BKPg\the \BACKUPno \endcsname \empty}% 
    \expandafter \BACKUPpopdocomment
      \BACKUPpopprobe \empty \empty \empty \relax
    \ifBACKUPpopdocommentend \else \expandafter
      \BACKUPpopdogap \BACKUPpopprobe \relax \fi 
    \BACKUPpopdoclear \TAGgetdoexec}
      
    \def \BACKUPpopdoclear {%   
      \xDef {BKPt\the \BACKUPno} \empty
      \xDef {BKPg\the \BACKUPno} \empty}   
      
    \ldef \BACKUPpopdocomment #1#2#3#4\relax {% 
      \def \BACKUPpopdocommenttest {#1#2#3}%
      \ifx \BACKUPpopdocommenttest \CONSTendcomment 
        \BACKUPpopdocommentendtrue
        \tagCOMMENTfalse \tagCOMMENTbegunfalse \tagCOMMENTfinishedtrue
        \xdef \GAPcontent {#4}%
        \GAPcheckfilled \GAPchecklog \GAPcheckobey 
        \GAPset {#4}%
      \else \BACKUPpopdocommentendfalse \fi}  
        
    \newif \ifBACKUPpopdocommentend

    \ldef \BACKUPpopdogap #1\relax {% see \GAPget  
      \xdef \GAPcontent {#1}%
      \GAPcheckfilled \GAPchecklog \GAPcheckobey \GAPset {#1}}
        
    \ldef \BACKUPpopdoparse #1#2 #3\relax {% see \TAGgetdo
      \lowercase {\ELEMENT = {#1#2}}%
      \edef \TAGfirst {#1}%
      \def \TAGfirstsecond {#1#2}%
      \def \TAGsecond {#2}%
      \def \TAGlast {#3}%
      \ATTlist = {#3}}

  \def \BACKUPpoploop #1\BACKUPpoplooprepeat {% 
    \let \BACKUPpoplooprepeat \fi
    \gdef \BACKUPpoploopbody {#1}% global to pass moziller.htm,
    \BACKUPpoploopiterate}% unnestable, see \loop in plain.tex

    \def \BACKUPpoploopiterate {%
      \BACKUPpoploopbody
        \let \BACKUPpoploopnext \BACKUPpoploopiterate 
      \else \let \BACKUPpoploopnext \relax \fi 
      \BACKUPpoploopnext}
            
\def \BACKUPpush #1{%
  \iftagCOMMENT \ifBACKUP \BACKUPpushcomment \fi \fi
  \edef \BACKUPelement {\the \ELEMENT}% 
  \ifx \BACKUPelement \CONSTtable \BACKUPpushstart \else 
  \ifx \BACKUPelement \CONSTtd \BACKUPpushstarttd \else 
  \ifx \BACKUPelement \CONSTth \BACKUPpushstarttd \else 
  \ifx \BACKUPelement \CONSTtr \BACKUPpushstarttr \else 
  \ifx \BACKUPelement \CONSTendtable \BACKUPpushstop \fi \fi \fi \fi \fi
  \ifBACKUP \let #1\relax \BACKUPpushexec\fi
  \ifBACKUPpop \let #1\relax \BACKUPpop \fi}  

  \def \BACKUPpushcomment {%
    \ELEMENT = \expandafter {\CONSTcomment}}

  \def \BACKUPpushexec{% create array of tags and gaps
    \iftagCOMMENTbegun \iftagCOMMENTfinished \else
      \let \BACKUPelement \CONSTcomment \fi \fi
    \global \advance \BACKUPno by 1 
    \glet \BACKUPtaglast \BACKUPtagnew
    \glet \BACKUPtagnew \BACKUPelement
    \ifx \BACKUPtaglast \CONSTcomment 
      \ifx \BACKUPtagnew \CONSTcomment 
        \GAP = {}\fi \fi
    \xDef {BKPt\the \BACKUPno} {\BACKUPelement \CONSTspace \TAGlast}% 
    \xDef {BKPg\the \BACKUPno} {\the \GAP}}

  \def \BACKUPpushstart {%
    \global \advance \BACKUPnotable by 1
    \expandafter \DATAstackxpush \the \BACKUPnotable \to \BACKUPnotables
    \expandafter \DATAstackxpush \the \BACKUPtr \to \BACKUPnorows
    \expandafter \DATAstackxpush \the \BACKUPtd \to \BACKUPnocols
    \global \advance \BACKUPnest by 1
    \global \BACKUPtd = 0
    \global \BACKUPtdmax = 0
    \global \BACKUPtr = 0 
    \ifnum \BACKUPnest = 1 
      \global \BACKUPtrue
      \xdef \BACKUPstart {\the \BACKUPno}\fi}
      
  \def \BACKUPpushstarttd {% 
    \global \advance \BACKUPtd by 1 
    \ifnum \BACKUPtd > \BACKUPtdmax 
      \global \BACKUPtdmax = \BACKUPtd \fi}
       
  \def \BACKUPpushstarttr {% 
    \global \BACKUPtd = 0
    \global \advance \BACKUPtr by 1 }  

  \def \BACKUPpushstop {%
    \global \advance \BACKUPnest by -1    
    \DATAstackxpopnumber \BACKUPnotable \from \BACKUPnotables
    \xDef {TROWS\the \BACKUPnotable} {\the \BACKUPtr}%
    \DATAstackxpopnumber \BACKUPtr \from \BACKUPnorows
    \xDef {TCOLS\the \BACKUPnotable} {\the \BACKUPtdmax}% 
    \DATAstackxpopnumber \BACKUPtd \from \BACKUPnocols   
    \SPANrowclear 
    \ifnum \BACKUPnest = 0 
      \global \BACKUPpoptrue
      \global \BACKUPfalse 
      \BACKUPpushexec\tagCOMMENTbegunfalse
      \xdef \BACKUPstop {\the \BACKUPno}\fi} 
      
\nec \BACKUPtd 
\nec \BACKUPtdmax 
\nec \BACKUPtr

% BIDI: ======================================================================

\ifx \TeXXeTstate \undefined
  \message {No eTeX: Unidirectional typesetting. -}%
  \csname newcount\endcsname \TeXXeTstate \fi

\def \BIDI {ltr}

\ifx \eTeXversion \undefined 
  \let \BIDIbegin \empty
  \let \BIDIbeginone \empty
  \let \BIDIend \empty
  \let \BIDIendone \empty
  \let \BIDIset \empty
  \let \BIDIsetone \empty
\else
  \def \BIDIbegin {%
    \ifnum \TeXXeTstate = 2 \beginR \fi}
  \def \BIDIbeginone {%
    \ifnum \TeXXeTstate = 1 \beginR \fi}
  \def \BIDIend {%
    \ifnum \TeXXeTstate = 2 \endR \fi}
  \def \BIDIendone {%
    \ifnum \TeXXeTstate = 1 \endR \fi}
  \def \BIDIset {%
    \VALUEset \BIDI
    \ifx \BIDI \CONSTrtl \TeXXeTstate = 2 
    \message {[R=2]}\fi} 
  \def \BIDIsetone {%
    \VALUEset \BIDI
    \ifx \BIDI \CONSTrtl \TeXXeTstate = 1 
    \message {[R=1}\fi} 
\fi
                      
% BORDER: ====================================================================

% The visible border width between cells has to be twice border-width, and
% border greyness should be one third (or skip width should equal twice rule
% width), independent from border style. If a <td> cell is to be drawn within
% a <table>, and both are told to have a solid border, first comes the 
% <table> rule, then two skips, then the <td> rule.
% If TeX is programmed to make a full width overlap of horizontal and 
% vertical rule edges, it turns out that both Acrobat Reader and Ghostview 
% sometimes show a small offset caused by rounding errors that looks ugly. 
% Therefore GMS does half width overlapping, if possible.
  
\ned \BORDER

\ned \BORDERbottom
    
\def \BORDERhandle {%
  \ifBORDERrulegiven \BORDERhandlereset \else \BORDERreset \fi}

  \def \BORDERhandlereset {%
    \BORDERbottom = 0mm 
    \BORDERleft = 0mm 
    \BORDERright = 0mm
    \BORDERtop = 0mm }   
    
\ned \BORDERleft
\ned \BORDERright
        
\let \BORDERprofile \empty

\def \BORDERprofiledraw #1#2{%
  \ifx \BORDERprofile \empty \let \BORDERprofile \CONSTsolid \fi
  \csname \CONSTborderstyle \BORDERprofile #2#1\endcsname}  
    
  \def \BORDERprofileba {1221} % groove cell begin
  \def \BORDERprofilebb {2211} % groove cell end
  \def \BORDERprofileca {0222} % inset cell begin
  \def \BORDERprofilecb {2220} % inset table begin
  \def \BORDERprofileda {1212} % outset table begin
  \def \BORDERprofiledb {2121} % outset cell begin
  \def \BORDERprofileea {1122} % ridge cell begin
  \def \BORDERprofileeb {1221} % ridge cell end 
  \def \BORDERprofilefa {1221} % double cell begin 
  \def \BORDERprofilefb {1221} % double cell end
  
  % Grooved borders that look as if they were carved into the canvas: 
  \def \BORDERprofilegroovecellbegin {%
    \BORDERwritecellbegin \BORDERprofileba}
  \def \BORDERprofilegroovecellend {%
    \BORDERwritecellend \BORDERprofilebb}
  \def \BORDERprofilegroovetablebegin {%
    \BORDERwritetablebegin \BORDERprofilebb}
  \def \BORDERprofilegroovetableend {%
    \BORDERwritetableend \BORDERprofileba}

  % Hidden borders: 
  \def \BORDERprofilehiddencellbegin {\BORDERreset}
  \let \BORDERprofilehiddencellend \BORDERprofilehiddencellbegin
  \let \BORDERprofilehiddentablebegin \BORDERprofilehiddencellbegin
  \let \BORDERprofilehiddentableend \BORDERprofilehiddencellbegin

  % Inset borders that make the box look as if it was embedded in the canvas:
  \def \BORDERprofileinsetcellbegin {%
    \BORDERwritecellbegin \BORDERprofileca}
  \def \BORDERprofileinsetcellend {%
    \BORDERwritecellend \BORDERprofileda}
  \def \BORDERprofileinsettablebegin {%
    \BORDERwritetablebegin \BORDERprofilecb}
  \def \BORDERprofileinsettableend {%
    \BORDERwritetableend \BORDERprofiledb}

  % No borders:
  \let \BORDERprofilenonecellbegin \BORDERprofilehiddencellbegin
  \let \BORDERprofilenonecellend \BORDERprofilehiddencellbegin 
  \let \BORDERprofilenonetablebegin \BORDERprofilehiddencellbegin 
  \let \BORDERprofilenonetableend \BORDERprofilehiddencellbegin

  % Outset borders that make the box look as if it was coming out of the can.:
  \def \BORDERprofileoutsetcellbegin {%
    \BORDERwritecellbegin \BORDERprofiledb}
  \def \BORDERprofileoutsetcellend {%
    \BORDERwritecellend \BORDERprofilecb}
  \def \BORDERprofileoutsettablebegin {%
    \BORDERwritetablebegin \BORDERprofileda}
  \def \BORDERprofileoutsettableend {%
    \BORDERwritetableend \BORDERprofileca}  

  % Ridged borders that look as if they were coming out of the canvas:
  \def \BORDERprofileridgecellbegin {%
    \BORDERwritecellbegin \BORDERprofileea}
  \def \BORDERprofileridgecellend {%
    \BORDERwritecellend \BORDERprofileeb}
  \def \BORDERprofileridgetablebegin {%
    \BORDERwritetablebegin \BORDERprofileeb}
  \def \BORDERprofileridgetableend {%
    \BORDERwritetableend \BORDERprofileea}

  % Simple double borders:
  \def \BORDERprofiledoublecellbegin {%
    \BORDERwritecellbegin \BORDERprofilefa}
  \def \BORDERprofiledoublecellend {%
    \BORDERwritecellend \BORDERprofilefb}
  \def \BORDERprofiledoubletablebegin {%
    \BORDERwritetablebegin \BORDERprofilefb}
  \def \BORDERprofiledoubletableend {%
    \BORDERwritetableend \BORDERprofilefa}

  % Solid borders:
  \def \BORDERprofilesolidcellbegin {%
    \borderLIFTbegin3\BORDERtop \BORDERleft
    \borderDROPbegin 3\BORDERleft \BORDERtop}
  \def \BORDERprofilesolidcellend {%
    \borderDROPend 3\BORDERbottom \BORDERright
    \borderLIFTend 3\BORDERright \BORDERbottom}
  \def \BORDERprofilesolidtablebegin {%
    \borderDROPbegin 3\BORDERleft \BORDERtop 
    \borderLIFTbegin3\BORDERtop \BORDERleft}
  \def \BORDERprofilesolidtableend {%
    \borderLIFTend 3\BORDERright \BORDERbottom
    \borderDROPend 3\BORDERbottom \BORDERright}
          
\def \BORDERreset {%
  \BORDER = 0mm 
  \BORDERbottom = 0mm 
  \BORDERleft = 0mm 
  \BORDERright = 0mm
  \BORDERtop = 0mm }

  \new \ifBORDERrulegiven
  
\def \BORDERset {%
  \edef \BORDERtest {\the \VALUE}%
  \BORDERseteval}
  
\def \BORDERsetdo #1#2{%
  \BORDERsetdotmp = \BORDER 
  \edef \BORDERtest {#1}%
  \BORDERseteval
  #2 = \BORDER 
  \BORDER = \BORDERsetdotmp} 
  \ned \BORDERsetdotmp
  
\def \BORDERseteval {%
  \BORDERrulegiventrue
  \ifx \BORDERtest \CONSTthin \BORDERsetevaldo {12}% Fixme: check numbers
  \else \ifx \BORDERtest \CONSTmedium \BORDERsetevaldo 9
  \else \ifx \BORDERtest \CONSTthick \BORDERsetevaldo 6
  \else \VALUEdimenset \BORDER \hsize \fi \fi \fi}   

  % Set border-width to a fraction of line-height, if #1 is a keyword
  % string, or to #1, which is otherwise supposed to be a dimension:
  \def \BORDERsetevaldo #1{%
    \BORDER = \LINEheight
    \ifdim \BORDER = 0pt \BORDER = \BOXlineheight \fi %%% check this
    \divide \BORDER by #1}
    
\def \BORDERsetevaldobottom {%
  \BORDERsetdo {\the \VALUE }\BORDERbottom}
  
\def \BORDERsetevaldoleft {%
  \BORDERsetdo {\the \VALUE }\BORDERbottom} % check this
  
\def \BORDERsetevaldoright {%
  \BORDERsetdo {\the \VALUE }\BORDERbottom} % check this
  
\def \BORDERsetevaldotop {%
  \BORDERsetdo {\the \VALUE }\BORDERbottom} % check this
  
\ned \BORDERtop

\def \BORDERupdate {%
  \BORDERbottom = \BORDER 
  \BORDERleft = \BORDER
  \BORDERright = \BORDER
  \BORDERtop = \BORDER}  
  
  \def \BORDERwritecellbegin #1{%
    \expandafter \BORDERwritecellbegindo #1\BORDERtop \BORDERleft}
    \def \BORDERwritecellbegindo #1#2#3#4#5#6{% skip rule skip rule
      \borderLIFTbegin{#1}#5#6\borderDROPbegin {#2}#6#5%
      \borderLIFTbegin{#3}#5#6\borderDROPbegin {#4}#6#5}
     
  \def \BORDERwritetablebegin #1{%
    \expandafter \BORDERwritetablebegindo #1\BORDERleft \BORDERtop}
    \def \BORDERwritetablebegindo #1#2#3#4#5#6{% rule skip rule skip
      \borderDROPbegin {#1}#5#6\borderLIFTbegin{#2}#6#5%
      \borderDROPbegin {#3}#5#6\borderLIFTbegin{#4}#6#5}
    
  \def \BORDERwritecellend #1{%
    \expandafter \BORDERwritecellenddo #1\BORDERbottom \BORDERright}
    \def \BORDERwritecellenddo #1#2#3#4#5#6{% rule skip rule skip
      \borderDROPend {#1}#5#6\borderLIFTend {#2}#6#5% 
      \borderDROPend {#3}#5#6\borderLIFTend {#4}#6#5} 
    
  \def \BORDERwritetableend #1{%
    \expandafter \BORDERwritetableenddo #1\BORDERright \BORDERbottom}    
    \def \BORDERwritetableenddo #1#2#3#4#5#6{% skip rule skip rule
      \borderLIFTend {#1}#6#5\borderDROPend {#2}#5#6%
      \borderLIFTend {#3}#6#5\borderDROPend {#4}#5#6}
    
% borderDROP: ----------------------------------------------------------------

  \def \borderDROPbegin #1#2#3{%
    \COLORizeborder
    \global \borderDROPwidthleft = #1#2%
    \global \borderDROPwidthtop = #1#3%
    \ifnum \TABLEnesting < 5 \borderDROPbegindo \fi} 
                
    \def \borderDROPbegindo {%
      \borderDROPwidthget \borderDROPwidthleft \borderDROPwidthtop
      \borderDROPbegindovh 
      \vbox \bgroup 
      \ifTABLEinter \else \borderDROPv \borderDROPwidthtop \fi 
      \hbox \bgroup
      \borderDROPh \borderDROPwidthleft
      \borderDROPbegindovh}
      
      \def \borderDROPbegindovh {%
        \vbox \bgroup 
        \ifTABLEinter \else \vskip \borderDROPwidthtop \fi
        \hbox \bgroup \hskip \borderDROPwidthleft}
            
  \def \borderDROPend #1#2#3{% 
    \COLORizeborder
    \global \borderDROPwidthbottom = #1#2%
    \global \borderDROPwidthright = #1#3%
    \ifnum \TABLEnesting < 5 \borderDROPenddo \fi}
    
    \def \borderDROPenddo {%
      \borderDROPwidthget \borderDROPwidthbottom 
        \borderDROPwidthright 
      \borderDROPenddovh
      \borderDROPh \borderDROPwidthright \egroup
      \ifTABLEinter \else \borderDROPv \borderDROPwidthbottom \fi
      \egroup \borderDROPenddovh}
      
      \def \borderDROPenddovh {%
        \hskip \borderDROPwidthright \egroup
        \ifTABLEinter \else \vskip \borderDROPwidthbottom \fi \egroup}

  \def \borderDROPh #1{%
    \ifdim #1 > 0pt \hskip -#1 \vrule width 2#1 \hskip -#1 \fi}
    
  \def \borderDROPv #1{%
    \ifdim #1 > 0pt \vskip -#1 \hrule height 2#1 \vskip -#1 \fi}
    
  \ned \borderDROPwidth
  \ned \borderDROPwidthbottom

  \def \borderDROPwidthget #1#2{% 
    \global \divide #1 by 12
    \global \divide #2 by 12 }

  \ned \borderDROPwidthleft
  \ned \borderDROPwidthright
  \ned \borderDROPwidthtop 
    
% borderLIFT: ----------------------------------------------------------------

  % hbox inside vbox with border-width fraction skips:
  
  \def \borderLIFTbegin #1#2#3{%
    \borderLIFTwidthget \borderLIFTwidthtop {#1#2}% 
    \borderLIFTwidthget \borderLIFTwidthleft {#1#3}% 
    \vbox \bgroup 
    \ifTABLEinter \else
      \borderLIFTv \borderLIFTwidthtop \fi
    \hbox \bgroup \borderLIFTh \borderLIFTwidthleft}

  \def \borderLIFTend #1#2#3{%
    \borderLIFTwidthget \borderLIFTwidthright {#1#2}% 
    \borderLIFTwidthget \borderLIFTwidthbottom {#1#3}% 
    \borderLIFTh \borderLIFTwidthright \egroup
    \ifTABLEinter \else 
      \borderLIFTv \borderLIFTwidthbottom \fi \egroup}
      
  \def \borderLIFTh #1{%  
    \ifCOLORbgtable \borderLIFTcolorh #1 \else \hskip #1 \fi}    
    \def \borderLIFTcolorh #1{%
      \COLORize \COLORbgtable \hskip 0.1#1\vrule width 0.8#1\hskip 0.1#1}
    
  \def \borderLIFTv #1{%  
    \ifCOLORbgtable \borderLIFTcolorv #1 \else \vskip #1 \fi}       
    \def \borderLIFTcolorv #1{%
      \COLORize \COLORbgtable \vskip 0.1#1\hrule height 0.8#1\vskip 0.1#1}

  \ned \borderLIFTwidth
  \ned \borderLIFTwidthbottom

  \def \borderLIFTwidthget #1#2{%
    \global #1 = #2%
    \global \divide #1 by 6 }

  \ned \borderLIFTwidthleft
  \ned \borderLIFTwidthright
  \ned \borderLIFTwidthtop
      
% BOX: =======================================================================
    
\def \BOXbegin {%
  \SPANcolgivenfalse
  \xdef \NOcollast {0}%
  \BOXwidthgivenfalse \OPENfontinnerfalse
  \leftskip = 0pt \rightskip = 0pt
  \hbadness = 10000 
   %%% \BOXfillerssimple
  \ifBOXvaligngiven \BOXfillersh \else \BOXfillerssimple \fi %%%
  \BOXwidthdefault = \hsize
  \BOXwidth = \BOXwidthdefault
  \BORDERhandle \NOparreset
  \ifSPANrowspangiven \SPANrowpre \BOXwidthdefault \else \MESSAGEtdcol \fi
  \SPANcolpre \BOXwidthdefault
  \LANGUAGEchangedetect \ELEMENTvalueget 
  \BOXbeginlineheightset \BOXbegindo \FONTdo \COLORizeforeground 
  \BOXbeginlineheightreset \MESSAGEtdlanguage}
  
  \def \BOXbegindo {%
    \hskip 0pt % check this
    \hbox \bgroup \raise \LINEheight
    \vtop \bgroup \vskip \MARGIN % align cells of different heights
    \hbox \bgroup \hskip \MARGIN
    \ifSPANrowspangivenhere \else
      \ifdim \BOXheight < \BOXheightold
        \BOXheight = \BOXheightold \BOXheightgiventrue \fi \fi
    \vsize = \BOXheight
    \ifBOXwidthgiven \hsize = \BOXwidth \else 
      \hsize = \BOXwidthdefault \BOXwidthget \fi  
    \advance \vsize by -2\MARGIN
    \advance \hsize by -2\MARGIN
    \ifdim \vfuzz < 1pt \vfuzz = 1pt \fi  
    \ifCOLORbg \BOXbegindoback \fi
    \ifdim \BORDER > 0mm \BORDERupdate \fi
    \BORDERprofiledraw \CONSTbegin \CONSTcell
    \advance \vsize by -\BORDERbottom
    \advance \vsize by -\BORDERtop
    \advance \hsize by -\BORDERleft
    \advance \hsize by -\BORDERright
    \PADDINGbegin 
    \advance \vsize by -\PADDINGtop
    \advance \vsize by -\PADDINGbottom
    \advance \hsize by -\PADDINGleft
    \advance \hsize by -\PADDINGright
    \ifBOXheightgiven \vbox to \vsize \bgroup \else \vbox \bgroup \fi 
    \BOXfillertop \hbox to \hsize \bgroup \strut
    \BOXfillerleft \vbox \bgroup}
    
    \def \BOXbegindoback {%
      \ifTABLEinter \else
        \ifBOXheightgiven 
          \ifBOXwidthgiven \BOXbegindobackdimen
          \else \BOXbegindobacknodimen \fi
        \else \BOXbegindobacknodimen \fi \fi}

      \def \BOXbegindobackdimen {%
        \COLORize \COLORbackground
        \vbox {\vskip -\vsize \hbox {%
          \vrule height \vsize width \hsize \hskip -\hsize }}}

      \def \BOXbegindobacknodimen {%
        \COLORize \COLORbackground
       {\advance \hsize by -\PADDINGleft
        \vrule width \hsize \hskip -\hsize }}
    
  \def \BOXbeginlineheightreset {%   
    \ifdim \LINEheight = 0pt \LINEheight = \BOXlineheight \fi}  
    
  \def \BOXbeginlineheightset {%
    \ifdim \LINEheight > 0pt \edef \BOXlineheight {\the \LINEheight}%
      \LINEheight = 0pt \fi}
        
\let \BOXcellvalign \empty
  
\def \BOXend {%
  \ifOPENtd \BOXenddo \else \ifOPENth \BOXenddo \fi \fi}

  \def \BOXenddo {%
    \egroup \BOXfillerright \strut
    \egroup \BOXfillerbottom
    \egroup \PADDINGend    
    \BORDERprofiledraw \CONSTend \CONSTcell
    \hskip \MARGIN \egroup
    \vskip \MARGIN 
      \ifSPANrowspangivenhere \vskip -\BOXheight \else  
        \ifdim \BOXheight > \BOXheightold
          \global \BOXheightold = \BOXheight \fi \fi  
    \egroup \egroup}

\def \BOXfillersempty {%
  \let \BOXfillertop \empty \let \BOXfillerright \empty
  \let \BOXfillerbottom \empty \let \BOXfillerleft \empty}
  \BOXfillersempty

\def \BOXfillersh {%
  \let \BOXfillerright \empty \let \BOXfillerleft \empty}
  
\def \BOXfillerssimple {%
  \let \BOXfillertop \vfil \let \BOXfillerright \empty
  \let \BOXfillerbottom \vfil \let \BOXfillerleft \empty}
            
\def \BOXgridtrbegin {%
  \global \BOXwidthcolspan = 0pt  
  \BOXheightgivenfalse 
  \BOXwidthdefault = \hsize
  \BOXwidth = \BOXwidthdefault
  \BOXheightold = 0pt
  \BOXheight = \LINEheight} 

\def \BOXgridtrend {% 
   \BOXheightgivenfalse \BOXwidthgivenfalse \OPENtrfalse}
  
\ned \BOXheight

\new \ifBOXheightgiven

\ned \BOXheightold
\ned \BOXheightswapped

\def \BOXheightswappedinit {\BOXheightswapped = \BOXheight}  

\ned \BOXindent
  
\def \BOXinit {%
  \BOXheightgivenfalse \BOXwidthgivenfalse   
  \BOXheight = 0mm \BOXheightswapped = 0mm
  \BOXindent = \hsize \BOXwidth = \hsize}

\edef \BOXlineheight {\the \LINEheight}

\def \BOXlineheightset {%
  \ifnum \TABLEnesting = 1 \edef \BOXlineheight {\the \LINEheight}\fi}
  
\def \BOXrownoadvance {%
  \NOcol = 0 \advance \NOrow by 1 }
    
\def \BOXspancolexec {%
  \ifBOXwidthgiven \xDef {\CONSTcolwidth 
    \the \TABLEnesting.\the \NOcol} {\the \BOXwidth}\fi}

\new \ifBOXvaligngiven %%%

\def \BOXvalignset {%
  \edef \BOXvalign {\the \VALUE}%
  \ifx \BOXvalign \CONSTbottom \BOXvalignsetbottom 
    \BOXvaligngiventrue %%%
  \else \ifx \BOXvalign \CONSTtop \BOXvalignsettop
    \BOXvaligngiventrue %%%
  \else \ifx \BOXvalign \CONSTcenter \VERIFYerroryoumeantmiddle \fi \fi \fi}

  \def \BOXvalignsetbottom {%
    \let \BOXfillertop \vfill \let \BOXfillerbottom \vfil}   

  \def \BOXvalignsettop {%
    \let \BOXfillertop \vfil \let \BOXfillerbottom \vfill}      
    
\ned \BOXwidth
\ned \BOXwidthcolspan
\ned \BOXwidthdefault

\def \BOXwidthget {%
  \DEFsearch {\CONSTcolwidth \the \TABLEnesting.\the \NOcol }\ifDEF
    \edef \BOXwidthgettest {\csname 
      \CONSTcolwidth \the \TABLEnesting.\the \NOcol \endcsname }%
    \ifx \BOXwidthgettest \empty \else 
      \hsize = \BOXwidthgettest \fi \fi}

\new \ifBOXwidthgiven

% CHAIN: =====================================================================

% Input file:

\def \CHAINcheck {% </html>
  \CHAINloadnextfalse
  \glet \CHAINhrefnext \empty 
  \ifOPENobject \else
    \ifx \CHAINhref \empty \else 
      \glet \CHAINhrefnext \CHAINhref
      \ENDfalse \CHAINloadnexttrue \fi \fi}

\def \CHAINcopyrelativepath #1#2\to #3{%
  \let \CHAINfolderbackup \CHAINfoldercurrent
  \glet \chainNEXTfile \empty
  \glet \chainNEXTlevel \empty
  \edef \CHAINcopyfirst {#1}%
  \ifx \CHAINcopyfirst \CONSTslash
    \edef #3{#1#2/}% Fixme: use some absolute path
  \else \edef #3{./#1#2/}\fi
  \expandafter \CHAINfiledofolder #3\relax
  \edef #3{.\CHAINfoldercurrent /\chainNEXTfile}%
  \glet \CHAINfoldercurrent \CHAINfolderbackup}   

\def \CHAINfile #1{% executed by </html>, <link>; indirectly: <object>
  \edef \CHAINloadnextfirst {#1}%
  \glet \URLhref \CHAINloadnextfirst
  \ifx \CHAINloadnextfirst \empty \let \chainNEXTa \relax      
  \else \let \chainNEXTa \CHAINfiledo \fi 
  \chainNEXTa}
  
  \def \CHAINfiledo {% 
    \glet \chainNEXTfile \empty
    \glet \chainNEXTlevel \empty
    \edef \CHAINloadnextfirst {./\CHAINloadnextfirst/}%   
    \expandafter \CHAINfiledofolder \CHAINloadnextfirst \relax
    \edef \CHAINloadnextfirst {.\CHAINfoldercurrent /\chainNEXTfile }% 
    \FILEsearch \CHAINloadnextfirst 
    \global \CHAINloadnextfalse 
    \ifFILEexist \CHAINfiledopresent 
    \else \CHAINfiledoabsent \fi}    

    \def \CHAINfiledofolder #1/#2{% analyse next level of path 
      \def \CHAINfolderfirst {#1}% Fixme: used globally
      \def \CHAINfoldersecond {#2}%
      \ifx \CHAINfoldersecond \CONSTrelax 
        \CHAINfiledofolderrelax
      \else \ifx \CHAINfoldersecond \CONSTslash
        \let \chainNEXT \relax
      \else \CHAINfiledofolderdo \fi \fi 
      \chainNEXT}

      \def \CHAINfiledofolderdo {%
        \let \chainNEXT \CHAINfiledofolder
        \xdef \chainNEXTlevel {\chainNEXTfile \CHAINfolderfirst}%
        \xdef \chainNEXTfile {\CHAINfoldersecond}%
        \ifx \chainNEXTlevel \CONSTdotdot \CHAINfiledofolderdopush 
        \else \ifx \chainNEXTlevel \CONSTdot 
        \else \DATAstackpush \chainNEXTlevel \to \CHAINfoldercurrent \fi \fi}

        \def \CHAINfiledofolderdopush {%
          \DATAstackpop \CHAINfiledofolderdopushlevel 
            \from \CHAINfoldercurrent
          \ifx \CHAINfiledofolderdopushlevel \empty 
            \DATAstackpush \chainNEXTlevel \to \CHAINfoldercurrent 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdot 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdottwo 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdotthree 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdotfour 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdotfive 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdotsix 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdotseven 
            \CHAINfiledofolderdopushit 
          \else \ifx \CHAINfiledofolderdopushlevel \CONSTdotdoteight 
            \CHAINfiledofolderdopushit 
          \fi \fi \fi \fi \fi \fi \fi \fi \fi} 
          
          \def \CHAINfiledofolderdopushit {%
            \DATAstackpush \CHAINfiledofolderdopushlevel 
              \to \CHAINfoldercurrent
            \DATAstackpush \chainNEXTlevel \to \CHAINfoldercurrent} 
      
      \def \CHAINfiledofolderrelax {%
        \let \chainNEXT \relax
        \xdef \chainNEXTfile {\chainNEXTfile \CHAINfolderfirst}}        
    
    \def \CHAINfiledoabsent {%
      \VERIFYerrorabsent \CHAINloadnextfirst 
      \ifOPENobject \else \ENDtrue \CHAINloadnextfalse \fi} 

    \def \CHAINfiledopresent {%
      \ifOPENobject \CHAINfiledopresentobject 
      \else \CHAINfiledopresentmessage \fi
      \ENDfalse \CHAINloadnexttrue}
  
      \def \CHAINfiledopresentmessage {% Fime: move
        \edef \test {- \the \NOinput \CONSTspace -}\echo {\test}%
        \global \advance \NOinput by 1
        \echo {\CONSTlongLINE \CONSTLINE \CONSThalfLINE}%
        \edef \test {- \the \NOinput \CONSTspace -}\echo {\test}}
    
    \def \CHAINfiledopresentobject {%
      \ifOPENiframe \global \advance \NOinclude by 1 \OPENiframefalse 
      \else \ifFILEhtml \global \advance \NOinclude by 1 \fi \fi}
     
\let \CHAINfolderbackup \empty
\let \CHAINfoldercurrent \empty
 
\def \CHAINget #1{%
  \ifx \CHAINhref \empty \let \chainNEXTb \relax 
  \else \let \chainNEXTb \CHAINgethref \fi 
  \ifOPENobject \let \chainNEXTb \relax \fi      
  \chainNEXTb 
  \ifFILEplain \CHAINgetplain \else \CHAINgetnoplain \fi
  \ifOPENobject \CHAINgetobject \else \CHAINgetnoobject #1\fi
  \let \CHAINgetnext \relax
  \FILEsearch \CHAINgetprobe 
  \ifFILEexist \CHAINgetfile \CHAINgetprobe \else \CHAINgetnofile #1\fi 
  \chainNEXT
  \ifOPENobject \let \chainNEXT \relax \else \CHAINgetnoobjecttwo #1\fi 
  \chainNEXT}
  
  \def \CHAINgetfile #1{%
    \CHAINgetfilesave {#1}%
    \expandafter \CHAINgetfileclean #1\empty \empty \relax
    \CHAINgetfilesave \CHAINgetfilenameclean 
    \CHAINgetfilesave {./\CHAINgetfilenameclean}%
    \CHAINgetfilesave {../\CHAINgetfilenameclean}%
    \ifx \CHAINfoldercurrent \empty \else    
      \CHAINgetfilesave {\CHAINfoldercurrent/\chainNEXTfile}\fi 
    \CHAINgetfilesave \chainNEXTfile
    \CHAINgetfilesave {./\chainNEXTfile}}

    \def \CHAINgetfileclean #1#2#3\relax {%
      \edef \CHAINgetfilecleantest {#1#2}%
      \ifx \CHAINgetfilecleantest \CONSTdotslash 
        \edef \CHAINgetfilenameclean {#3}\fi}   

    \def \CHAINgetfilesave #1{%
      \DEFsearch {\CONSTdest #1}\ifDEF \else \ANCHORbychain {#1}\fi}
      
    \def \CHAINgethref {%
      \CHAINfile \CHAINhref \relax
      \glet \CHAINhref \empty}
  
  \def \CHAINgetnofile #1{%
    \let \chainNEXT \relax \let \CHAINgetnext #1}

  \def \CHAINgetnoobject #1{%
    \edef \CHAINgetprobe {.\CHAINfoldercurrent /\chainNEXTfile}%
    \global \advance \verifyWELLFORMtotalfile by -1 
      \verifyWELLFORMtotalfileadvance
    \ifFILEtoomany \let \chainNEXT #1\fi}

  \def \CHAINgetnoobjecttwo #1{%
    \ifx \CHAINgetnext \relax 
    \def \chainNEXT {\CHAINget #1}%     
    \else \let \chainNEXT \CHAINgetnext \fi}

  \def \CHAINgetnoplain {%
    \ifFILETeX \OBJECTtex \fi 
    \let \chainNEXT \CHAINgetnoplaindo}
    \def \CHAINgetnoplaindo {%
      \shredder \CHAINloadnextfalse \input \CHAINgetprobe \relax \shredder}

  \def \CHAINgetobject {%
    \edef \CHAINgetprobe {./\URLhref}}

  \def \CHAINgetplain {% 
    \OBJECTplain 
    \let \chainNEXT \CHAINgetplaindo}     
    \def \CHAINgetplaindo {%
      \chainNEXTplaintext \CHAINgetprobe \shredder}
      
      \def \chainNEXTplaintext #1{%
        \openin \FILEplaintext = #1\relax
        \loop \FILEcheckeof \FILEplaintext
          \ifFILEnotended \read \FILEplaintext to \myline
          \strut \myline
        \repeat \closein \FILEplaintext}%
    
\let \CHAINhref \empty 

\def \CHAINiftable {% executed by '<iframe>'
  \ifOPENtable \CHAINget \VERIFYwellformedness \fi}
  
\new \ifCHAINloadnext

% Fixme: better done in \IMAGEnameget with respect to relative paths: 
\def \CHAINobjectloadurl {% executed by <iframe> and <object>
  \CHAINobjectloaddo \URLhref \relax}
  
  \def \CHAINobjectloaddo #1{%
    \edef \CHAINobjectfirst {#1}%
    \let \CHAINfolderbackup \CHAINfoldercurrent 
      \let \CHAINfoldercurrent \empty  
      \CHAINfile \CHAINobjectfirst  
    \glet \CHAINfoldercurrent \CHAINfolderbackup}
  
% CODEPAGE: ==================================================================

\ifx \eTeXversion \undefined
  \echo {codepages ! Unsupported (eTeX required);}%
\else \message {codepages,}\fi

% Each Unicode Value is stored in a count register. 
% The data associated with that Unicode Value is stored in a token register.
% Codepages are stored in eTeX's extended register set,  
% which can hold 127 of them. They are allocated in reverse order, 
% opposed to the standard allocation mechanism working from bottom to top.
% The first codepage gets \CODEPAGESnumberof = 1 and occupies registers number
% 32512 (= 127*256) to 32767 (= 128*256-1). 
% So \CODEPAGEregofindex runs from \CODEPAGEregbase=32512 to 32767. 
% Second codepage: \CODEPAGESnumberof = 2,
% \CODEPAGEregofindex = (128-2)*256-1 .. (128-1)*256-1

% A codepage is a set of 256 (or less) references to the unicode
% character space. The codepage data file format is: < 1) index,
% two hexadecimal digits; 2) unicode point, four hex. digits;
% 3) unicode character name (optional) >.
% The codepage files like CP1252.txt have been extracted from
% http://www.microsoft.com/typography/unicode/1252.htm etc. 

\let \CODEPAGE \GMScodepage  

\ldef \CODEPAGEadd #1.#2 {% add codepage file to CODEPAGES list
  \def \CODEPAGEaddfirst {#1}%
  \ifx \CODEPAGEaddfirst \empty \MESSAGEcodepageerror \CODEPAGEaddfirst \else
    \uppercase {\edef \CODEPAGEadditem {[#1] }}%
    \expandafter \DATAarrayone \CODEPAGEadditem 
      \DATAarrayafter \CODEPAGES \fi}
  \ifx \eTeXversion \undefined \ldef \CODEPAGEadd #1.#2 {}\fi 

% Create \Def CODEPAGE-<document codepage> {<HTML codepage>, <DOS codepage>}:
\def \CODEPAGEaddalias #1 (#2, #3){%
  \edef \CODEPAGEaddaliastest {#3}%
  \ifx \CODEPAGEaddaliastest \GMScodepage
    \Def {\CONSTCODEPAGE #1} {%
      \VERIFYerrorcodepagereplaced {#1}%
      \lowercase {\xdef \CODEPAGEhtml {#2}}%
      \uppercase {\xdef \CODEPAGE {#3}}}\fi}      

\ldef \CODEPAGEenable #1\relax {% #1: codepage name like CP125x
  \CODEPAGEname = \expandafter {#1}%
    \uppercase {\edef \CODEPAGEenablefirstuc {#1}}%
    \lowercase {\edef \CODEPAGEenablefirstlc {#1}}%
    \DEFsearch {\CONSTcodepagenumber \CODEPAGEenablefirstuc}%
    \ifDEF \CODEPAGEenabledo \CODEPAGEenablefirstuc \else 
      \DEFsearch {\CONSTcodepagenumber \CODEPAGEenablefirstlc}%
      \ifDEF \CODEPAGEenabledo \CODEPAGEenablefirstlc \else 
        \VERIFYerrornocodepage {%
          \CODEPAGEenablefirstlc |\CODEPAGEenablefirstuc}\fi \fi}
  \ifx \eTeXversion \undefined \ldef \CODEPAGEenable #1\relax {}\fi

  \def \CODEPAGEenabledo #1{%
    \CODEPAGEenabledoregbase {#1}\CODEPAGEenabledoregtop
    \ifUNICODEwriteenc \CODEPAGEenabledofileopen #1\fi 
    \CODEPAGEregofindex = \CODEPAGEregbase \count 8 = 0
    \loop
      \ifnum \count 8 > 128
        \catcode \count 8 = \CATletter % Fixme: This just enables hyphenation
        \lccode \count 8 = \count 8 % but is wrong for uppercase letters 
      \fi \advance \count 8 by 1
      \CODEPAGEenabledochar {\the \count \CODEPAGEregofindex}%
      \ifnum \regtopofCODEPAGE > \CODEPAGEregofindex
      \advance \CODEPAGEregofindex by 1
    \repeat \ifUNICODEwriteenc \CODEPAGEenabledofileclose \fi}
          
    \ldef \CODEPAGEenabledochar #1{% Standard Unicode Value (decimal)
      \edef \first {#1}%
      \ifx \first \empty \else
        \UNICODEslotset {#1}%
        \edef \myslot {\the \UNICODEslot slot}%
        \DEFsearch \myslot \ifDEF
          \UNICODEslotpointregset {#1}\UNICODEget
          \ifUNICODEwriteenc \CODEPAGEenabledocharline \fi
        \else \MESSAGEnochar {#1}\fi \fi}
                
      \def \CODEPAGEenabledocharline {%
        \edef \testglyphname {\the \UNICODEglyphname}%
        \ifx \testglyphname \empty \def \testglyphname {.notdef}\fi
        \DATAhexinput = \the \count \CODEPAGEregofindex 
          \DATAhexoutput = {}\DATAhex 
        \edef \codepoint {%
          \CONSTspace \CONSTpercent \CONSTspace \the \DATAhexoutput}%
        \CODEPAGEencwriteline {/\testglyphname \codepoint}}  
        
    \def \CODEPAGEenabledofileclose {%
      \CODEPAGEencwriteline {] def}%
      \CODEPAGEencwriteline {\CONSTpercent \CONSTspace
        Generated by \GMSname \CONSTspace (\GMSdomain)}%
      \immediate \closeout 3 } 
    
    \lowercase {\def \CODEPAGEenabledofileopen #1{%
      \immediate \openout 3 #1.enc\message {#1.enc}%
      \CODEPAGEencwriteline {/#1-Encoding [}}}
      
    \def \CODEPAGEenabledoregbase #1{%
      \CODEPAGEregbase = 128
      \advance \CODEPAGEregbase by -\csname \CONSTcodepagenumber#1\endcsname
      \multiply \CODEPAGEregbase by 256 }
      
    \def \CODEPAGEenabledoregtop {%
      \CODEPAGEregofindex = \CODEPAGEregbase
      \advance \CODEPAGEregofindex by 255
      \edef \regtopofCODEPAGE {\the \CODEPAGEregofindex}}   
                  
\def \CODEPAGEencwrite {%
  \def \\ [##1] {\def \first {##1}%
    \ifx \first \empty \else \expandafter \CODEPAGEenable \first \relax \fi}%
  \hyphenmessage \message {Writing encoding file(s):}%
  \UNICODEwriteenctrue \CODEPAGES \UNICODEwriteencfalse}
  
\ldef \CODEPAGEencwriteline #1{%
  \immediate \backupwrite 3{#1}}
  
\def \CODEPAGEget #1#2#3\relax {%
  \edef \CODEPAGEgettest {#1#2}%
  \ifx \CODEPAGEgettest \CONSTcp
    \xdef \CODEPAGE {CP#3}%
    \xdef \CODEPAGEhtml {CP#3}%
    \ifnum #3 >1249 \ifnum #3 < 1259 
      \xdef \CODEPAGEhtml {windows-#3}\fi \fi \fi}     
      
\def \CODEPAGEgetdefaultname {% get codepage info from markup file
  \expandafter \CODEPAGEget \CODEPAGE \relax
  \ifx \CODEPAGEhtml \empty 
    \expandafter \CODEPAGEgetiso \CODEPAGE \relax \fi
  \ifx \CODEPAGEhtml \empty \DATAlengthget \CODEPAGE
    \ifnum \DATAlength > 8 
      \expandafter \CODEPAGEgetwindows \CODEPAGE \relax \fi \fi} 
  
\lowercase {\def \CODEPAGEgetiso #1#2#3#4#5\relax {%
  \edef \CODEPAGEgetisotest {#1#2#3}%
  \ifx \CODEPAGEgetisotest \CONSTiso 
    \xdef \CODEPAGEhtml {ISO-#5}%
    \xdef \CODEPAGE {I#5}\fi}}   

\def \CODEPAGEgetwindows #1#2#3#4#5#6#7#8#9\relax {%
  \edef \CODEPAGEgetwindowstest {#1#2#3#4#5#6#7}%
  \ifx \CODEPAGEgetwindowstest \CONSTwindows 
    \xdef \CODEPAGEhtml {windows-#9}%
    \xdef \CODEPAGE {CP#9}\fi}  

\let \CODEPAGEhtml \empty

\nec \CODEPAGEindex

\def \CODEPAGEload {%
  \def \\ [##1] {%
    \lowercase {\def \lcfirst {##1}}%
    \uppercase {\def \ucfirst {##1}}%
    \FILEsearch {\lcfirst .txt}%
    \ifFILEexist \CODEPAGEloaddo \lcfirst \else 
      \FILEsearch {\ucfirst .txt}%
      \ifFILEexist \CODEPAGEloaddo \ucfirst \fi \fi}%
  \CODEPAGES}
  \ifx \eTeXversion \undefined \let \CODEPAGEload \relax \fi
    
  \ldef \CODEPAGEloaddo #1{% Code page name like CP125x
    \CODEPAGEloaddonumber {#1}%
    \CODEPAGEloaddoregbasenext %% \CODEPAGEloaddoregnumbershow
    \openin 1 = #1.txt
      \loop \FILEcheckeof 1
        \ifFILEnotended \read 1 to \CODEPAGEloadline
          \ifx \CODEPAGEloadline \CONSTpar \else 
            \ifx \CODEPAGEloadline \empty \else \expandafter
              \CODEPAGEloaddoline \CODEPAGEloadline ; ; \relax \fi \fi
      \repeat
    \closein 1}
    
    \ldef \CODEPAGEloaddoline 
      #1;% Codepage index (2 uppercase hexadecimal digits)
      #2;% Standard Unicode Value or CUS UV (4 uppercase hexadecimal digits)
      #3 ;% Unicode character names for standard UVs
      #4\relax {% Fixme: does it fail if one line is just missing?
        \edef \CODEPAGEloaddolinesecond {#2}%
        \CODEPAGEregofindex = \CODEPAGEregbase
        \uppercase {\advance \CODEPAGEregofindex by "#1}%
        \ifx \CODEPAGEloaddolinesecond \CONSTundefined \else
          \uppercase {\count \CODEPAGEregofindex = "#2}%
            \uppercase {\UNICODEslotset {"#2}}%
            \edef \CODEPAGEloaddolineslot {\the \UNICODEslot slot}%
            \DEFsearch \CODEPAGEloaddolineslot \ifDEF
              \uppercase {\UNICODEslotpointregset {"#2}}\UNICODEget
              \ifx \testdata \empty \else 
                \ifx \testcharset \GMScharset 
                  \uppercase {\UNICODEdataset
                    -;-;-;-;-;\testcharset;"#1;-;-\relax }\fi
                \edef \CODEPAGEloaddolinecheck {\the \CODEPAGEname}%
                \ifx \CODEPAGEloaddolinecheck \empty
                  \uppercase {\UNICODEdataset 
                    -;-;-;-;-;\testcharset;"#1;-;-\relax }\fi
                \global \toks \UNICODEslotpointreg = 
                  \expandafter {\the \UNICODEdata }\fi
            \else \MESSAGEnoslot \fi \fi}
    
    \def \CODEPAGEloaddonumber #1{%
      \edef \testcharset {#1}%
      \advance \CODEPAGESnumberof by 1
      \xDef {\CONSTcodepagenumber#1} {\the \CODEPAGESnumberof}%
      \hyphenmessage \message {\the \CODEPAGESnumberof.}%
      \message {#1.txt}}      

    \def \CODEPAGEloaddoregbasenext {%
      \CODEPAGEregbase = 128
      \advance \CODEPAGEregbase by -\CODEPAGESnumberof
      \multiply \CODEPAGEregbase by 256 }
      
    \def \CODEPAGEloaddoregnumbershow {{%
      \edef \CODEPAGEloaddoregnumbershowtest {\the \CODEPAGEregbase}%
      \message {[ C\CODEPAGEloaddoregnumbershowtest \CONSTspace to}%
      \advance \CODEPAGEregbase by 255
      \edef \CODEPAGEloaddoregnumbershowtest {\the \CODEPAGEregbase}%
      \message {C\CODEPAGEloaddoregnumbershowtest \CONSTspace ].}}}

\net \CODEPAGEname

\new \ifCODEPAGEplain

\nec \CODEPAGEregbase

\nec \CODEPAGEregofindex        

\nec \CODEPAGESnumberof 

\def \CODEPAGEwindowscheck {%
  \expandafter \CODEPAGEwindowscheckdo \CODEPAGE \relax}

  \def \CODEPAGEwindowscheckdo #1#2#3#4#5#6\relax {%
    \edef \CODEPAGEwindowschecktest {#1#2#3#4#5}%
    \ifx \CODEPAGEwindowschecktest \CONSTwindowsCP \CODEPAGEwintrue 
    \else \CODEPAGEwinfalse \fi}  

\let \CODEPAGES \empty

\new \ifCODEPAGEwin 
      
% COLOR: =====================================================================

\new \ifCOLOR

\def \COLORactive {\COLORforeground}

\net \COLORanchorext
\net \COLORanchorint

\def \COLORbackground {1 1 1 rg 1 1 1 RG} % RGB white

\new \ifCOLORbg 
\new \ifCOLORbgbody \let \COLORbgbody \COLORbackground
\new \ifCOLORbgspan \let \COLORbgspan \COLORbackground %%%
\new \ifCOLORbgtable 

\new \ifCOLORborder

\def \COLORborder {0 0 0 rg 0 0 0 RG} % RGB black

\def \COLORforeground {0 0 0 rg 0 0 0 RG} % RGB black  
\let \COLORforegroundbackup \COLORforeground

\def \COLORize #1{%
  \pdfliteral {#1}}
  \ifx \pdfliteral \undefined \def \COLORize #1{\special {PDF:#1}}\fi

\def \COLORizebackground {%
  \COLORize \COLORbgbody
  \vbox to 0mm {\vskip -1in \vskip -\voffset
    \hbox to 0mm {\hskip -1in \hskip -\hoffset
      \vrule height \OUTPUTheight width \OUTPUTwidth \hss }\vss}%
  \COLORize \COLORforeground}   

\def \COLORizeborder {%
  \ifCOLORborder \COLORize \COLORborder 
  \else \COLORize \COLORforeground \fi} %%% 

\def \COLORizeforeground {%
  \ifCOLOR \COLORize \COLORforeground \fi}
    
\def \COLORlistdot {% checkme: was an \edef
  \the \COLORuldot \CONSTspace rg \the \COLORuldot \CONSTspace RG }

\ifx \TeXXeTstate \undefined
  \let \COLORltr \relax
\else
  \def \COLORltr {\ifnum \TeXXeTstate < 1 \COLORizeforeground \fi}%
\fi 

\def \COLORrtl {%
  \ifnum \TeXXeTstate > 0 \COLORizeforeground \fi}
  \ifx \TeXXeTstate \undefined \let \COLORrtl \relax \fi

\def \COLORset #1{%
  \edef #1{\colorGETall \CONSTspace rg \colorGETall \CONSTspace RG}}

\def \COLORsetbackground #1\relax {%
  \edef \COLORbackground {#1}} 
  
\def \COLORsetbackgroundbody {%
  \COLORsetbg \COLORbgbodytrue
  \edef \COLORbgbody {\COLORbackground}}
    
\def \COLORsetbg {%
  \COLORbgtrue \colorGET \COLORset \probe
  \ifcolorGETanyfailed \else \expandafter 
    \COLORsetbackground \probe \relax \fi}

\def \COLORsetbgbody {%
  \COLORsetbg \COLORbgbodytrue \COLORbordertrue
  \edef \COLORbgbody {\COLORbackground}}
  
\def \COLORsetbgspan {%
  \COLORsetbg \COLORbgspantrue
  \edef \COLORbgspan {\COLORbackground}}  
  
\def \COLORsetbgtable {%
  \COLORbgtabletrue \COLORsetbg
  \edef \COLORbgtable {\COLORbackground}}

\def \COLORsetborder {%
  \COLORbordertrue \colorGET \COLORset \COLORborder}

\def \COLORsetforeground {%
  \COLORtrue \colorGET \COLORset \COLORforeground}

\def \COLORsetlink {{%
  \colorGET \edef \COLORsetlinktest {\colorGETall}%
  \global \COLORanchorext = \expandafter {\COLORsetlinktest}}}

\def \COLORsetlistdot {%
  \COLORtrue \colorGET \COLORset \COLORlistdot}  

\def \COLORsetvlink {{%
  \colorGET \edef \COLORsetvlinktest {\colorGETall}%
  \global \COLORanchorint = \expandafter {\COLORsetvlinktest}}}  
    
\net \COLORuldot

% colorGET: ------------------------------------------------------------------

\def \colorGETall {%
  \the \colorGETallRED \CONSTspace 
  \the \colorGETallGREEN \CONSTspace 
  \the \colorGETallBLUE}
  
  \nec \colorGETallblue
  \net \colorGETallBLUE \colorGETallBLUE = {0}

  \nec \colorGETallgreen
  \net \colorGETallGREEN \colorGETallGREEN = {0}

  \nec \colorGETallred
  \net \colorGETallRED \colorGETallRED = {0}
  
\new \ifcolorGETanyfailed

  \new \ifcolorGETanyshort

% Get color by name or hex string:

\bgroup \CATotherhashmark \CATparameterdegree 

\gdef \colorGET {\VALUElowercaseget
  \DEFsearch {\CONSTcolorrgb \VALUElowercase}%
  \ifDEF \colorGETname \else \colorGEThex \fi}

  \gdef \colorGEThex {%     
    \VALUEuppercaseget 
    \expandafter \colorGEThexshort \VALUEuppercase #000000\relax
    \ifcolorGETanyshort \else 
      \expandafter \colorGETrgb \VALUEuppercase #000000#\relax \fi}
            
    \gdef \colorGEThexshort °1#°2°3°4°5°6°7°8\relax {%
      \edef \colorGEThexshorttest {°5}%
      \ifx \colorGEThexshorttest \CONSThashmark \colorGETanyshorttrue 
        \expandafter \colorGETrgb #°2°2°3°3°4°4#000000#\relax
      \else \colorGETanyshortfalse \fi}

  \gdef \colorGETname {%
    \edef \colorGETnameprobe {%
      #\csname \CONSTcolorrgb \VALUElowercase \endcsname}%
    \expandafter \colorGETrgb \colorGETnameprobe #\relax}

  \gdef \colorGETrgb °1#°2°3°4°5°6°7#°8\relax {%
    \lowercase {\edef \colorGETrgbtest {°1}}%
    \ifx \colorGETrgbtest \empty
      \uppercase {\colorGETrgbtrans 
        \colorGETallred \colorGETallRED {"°2°3}}%
      \uppercase {\colorGETrgbtrans 
        \colorGETallgreen \colorGETallGREEN {"°4°5}}%
      \uppercase {\colorGETrgbtrans 
        \colorGETallblue \colorGETallBLUE {"°6°7}}%
    \else \colorGETrgbdo \fi}     
   
\egroup    
 
    \def \colorGETrgbdo {%
      \expandafter \colorGETrgbdoparse \colorGETrgbtest rgb(,,)\relax}    
      
      \def \colorGETrgbdoparse #1rgb#2(#3,#4,#5)#6\relax {%
        \edef \colorGETrgbdoparsetest {#1}%
        \global \colorGETanyfailedfalse
        \ifx \colorGETrgbdoparsetest \empty
          \colorGETrgbtrans \colorGETallred \colorGETallRED {#3}%
          \colorGETrgbtrans \colorGETallgreen \colorGETallGREEN {#4}%
          \colorGETrgbtrans \colorGETallblue \colorGETallBLUE {#5}%
        \else \colorGETrgbdoparseerror \fi}

        \def \colorGETrgbdoparseerror {%
          \global \colorGETanyfailedtrue
          \ifBACKGROUNDgiven \VERIFYerrorunsuppattprop \CONSTbackground 
          \else \global \colorGETanyfailedtrue
            \VERIFYerroruncolored \colorGETrgbdoparsetest \fi}

    \def \colorGETrgbtrans 
      #1% FILEsource color count register
      #2% FILEsource color token register
      #3{% brightness ("00..."FF)
        \def \colorGETrgbtransfirst {#1}%
        \def \colorGETrgbtranssecond {#2}%
        \colorGETrgbtransfirst = #3
        \multiply \colorGETrgbtransfirst by 1000 
        \divide \colorGETrgbtransfirst by 256
        \advance \colorGETrgbtransfirst by 3 % rounding range
        \ifnum \colorGETrgbtransfirst < 4 \colorGETrgbtranssecond = {0}\else
        \ifnum \colorGETrgbtransfirst < 10 \colorGETrgbtransset {00}\else
        \ifnum \colorGETrgbtransfirst < 100 \colorGETrgbtransset {0}\else 
        \ifnum \colorGETrgbtransfirst < 996 \colorGETrgbtransset \empty \else 
        \colorGETrgbtranssecond = {1}\fi \fi \fi \fi}

      \def \colorGETrgbtransset #1{%
        \edef \colorGETrgbtranstest {0.#1\the \colorGETrgbtransfirst}%
          \colorGETrgbtranssecond = \expandafter {\colorGETrgbtranstest}}

% colorRGB: ------------------------------------------------------------------

\def \colorRGBaliceblue {F0F8FF}
\def \colorRGBantiquewhite {FAEBD7}
\def \colorRGBaqua {00FFFF}
\def \colorRGBaquamarine {7FFFD4}
\def \colorRGBazure {F0FFFF}

\def \colorRGBbeige {F5F5DC}
\def \colorRGBbisque {FFE4C4}
\def \colorRGBblack {000000}
\def \colorRGBblanchedalmond {FFEBCD}
\def \colorRGBblue {0000FF}
\def \colorRGBblueviolet {8A2BE2}
\def \colorRGBbrown {A52A2A}
\def \colorRGBburlywood {DEB887}

\def \colorRGBcadetblue {5F9EA0}
\def \colorRGBchartreuse {7FFF00}
\def \colorRGBchocolate {D2691E}
\def \colorRGBcoral {FF7F50}
\def \colorRGBcornflowerblue {6495ED}
\def \colorRGBcornsilk {FFF8DC}
\def \colorRGBcyan {00FFFF}

\def \colorRGBdarkgoldenrod {B8860B}
\def \colorRGBdarkgreen {006400}
\def \colorRGBdarkkhaki {BDB76B}
\def \colorRGBdarkolivegreen {556B2F}
\def \colorRGBdarkorange {FF8C00}
\def \colorRGBdarkorchid {9932CC}
\def \colorRGBdarksalmon {E9967A}
\def \colorRGBdarkseagreen {8FBC8F}
\def \colorRGBdarkslateblue {483D8B}
\def \colorRGBdarkslategray {2F4F4F}
\def \colorRGBdarkturquoise {00CED1}
\def \colorRGBdarkviolet {9400D3}
\def \colorRGBdeeppink {FF1493}
\def \colorRGBdeepskyblue {00BFFF}
\def \colorRGBdimgray {696969}
\def \colorRGBdodgerblue {1E90FF}

\def \colorRGBfirebrick {B22222}
\def \colorRGBfloralwhite {FFFAF0}
\def \colorRGBforestgreen {228B22}
\def \colorRGBfuchsia {FF00FF}

\def \colorRGBgainsboro {DCDCDC}
\def \colorRGBghostwhite {F8F8FF}
\def \colorRGBgold {FFD700}
\def \colorRGBgoldenrod {DAA520}
\def \colorRGBgray {808080}
\def \colorRGBgreen {008000}
\def \colorRGBgreenyellow {ADFF2F}

\def \colorRGBhoneydew {F0FFF0}
\def \colorRGBhotpink {FF69B4}
\def \colorRGBindianred {CD5C5C}
\def \colorRGBivory {FFFFF0}
\def \colorRGBkhaki {F0E68C}

\def \colorRGBlavender {E6E6FA}
\def \colorRGBlavenderblush {FFF0F5}
\def \colorRGBlawngreen {7CFC00}
\def \colorRGBlemonchiffon {FFFACD}
\def \colorRGBlightblue {ADD8E6}
\def \colorRGBlightcoral {F08080}
\def \colorRGBlightcyan {E0FFFF}
\def \colorRGBlightgoldenrodyellow {FAFAD2}
\def \colorRGBlightpink {FFB6C1}
\def \colorRGBlightsalmon {FFA07A}
\def \colorRGBlightseagreen {20B2AA}
\def \colorRGBlightskyblue {87CEFA}
\def \colorRGBlightslategray {778899}
\def \colorRGBlightsteelblue {B0C4DE}
\def \colorRGBlightyellow {FFFFE0}
\def \colorRGBlime {00FF00} 
\def \colorRGBlimegreen {32CD32}
\def \colorRGBlinen {FAF0E6}

\def \colorRGBmagenta {FF00FF}
\def \colorRGBmaroon {800000}
\def \colorRGBmediumaquamarine {66CDAA}
\def \colorRGBmediumblue {0000CD}
\def \colorRGBmediumorchid {BA55D3}
\def \colorRGBmediumpurple {9370DB}
\def \colorRGBmediumseagreen {3CB371}
\def \colorRGBmediumslateblue {7B68EE}
\def \colorRGBmediumspringgreen {00FA9A}
\def \colorRGBmediumturquoise {48D1CC}
\def \colorRGBmidnightblue {191970}
\def \colorRGBmintcream {F5FFFA}
\def \colorRGBmistyrose {FFE4E1}
\def \colorRGBmoccasin {FFE4B5}

\def \colorRGBnavajowhite {FFDEAD}
\def \colorRGBnavy {000080}
\def \colorRGBoldlace {FDF5E6}
\def \colorRGBolive {808000} 
\def \colorRGBolivedrab {6B8E23}
\def \colorRGBorange {FFA500}
\def \colorRGBorangered {FF4500}
\def \colorRGBorchid {DA70D6}

\def \colorRGBpalegoldenrod {EEE8AA}
\def \colorRGBpalegreen {98FB98}
\def \colorRGBpaleturquoise {AFEEEE}
\def \colorRGBpalevioletred {DB7093}
\def \colorRGBpapayawhip {FFEFD5}
\def \colorRGBpeachpuff {FFDAB9}
\def \colorRGBperu {CD853F}
\def \colorRGBpink {FFC0CB}
\def \colorRGBplum {DDA0DD}
\def \colorRGBpowderblue {B0E0E6}
\def \colorRGBpurple {800080}

\def \colorRGBred {FF0000}
\def \colorRGBrosybrown {BC8F8F}
\def \colorRGBroyalblue {4169E1}

\def \colorRGBsaddlebrown {8B4513}
\def \colorRGBsalmon {FA8072}
\def \colorRGBsandybrown {F4A460}
\def \colorRGBseagreen {2E8B57}
\def \colorRGBseashell {FFF5EE}
\def \colorRGBsienna {A0522D}
\def \colorRGBsilver {C0C0C0}
\def \colorRGBskyblue {87CEEB}
\def \colorRGBslateblue {6A5ACD}
\def \colorRGBslategray {708090}
\def \colorRGBsnow {FFFAFA}
\def \colorRGBspringgreen {00FF7F}
\def \colorRGBsteelblue {4682B4}

\def \colorRGBtan {D2B48C}
\def \colorRGBteal {008080}
\def \colorRGBthistle {D8BFD8}
\def \colorRGBtomato {FF6347}
\def \colorRGBturquoise {40E0D0}

\def \colorRGBviolet {EE82EE}
\def \colorRGBwheat {F5DEB3}
\def \colorRGBwhite {FFFFFF}
\def \colorRGBwhitesmoke {F5F5F5}
\def \colorRGByellow {FFFF00}
\def \colorRGByellowgreen {9ACD32}

\message {constants,} %=======================================================

\def \CONST {}
\def \CONSTABSENT {ABSENT}
\def \CONSTabsent {absent}
\def \CONSTacceptcharset {accept-charset}
\def \CONSTadobe {(Adobe)}
\def \CONSTafter {after}
\def \CONSTalias {ALIAS-}
\def \CONSTall {all}
\def \CONSTallthesame {(all the same)}
\def \CONSTalways {always}
{\catcode `\& = \CATother \gdef \CONSTampersand {&}}
\def \CONSTapostroph {'}
\def \CONSTArial {Arial}
\def \CONSTasterisk {*}
\def \CONSTasteriskslash {*/}
\def \CONSTat { at }
\def \CONSTatt {ATT}
%\edef \CONSTattstop {... = \CONSTspace \CONSTspace}
%\edef \CONSTattstopspace { ... = \CONSTspace \CONSTspace}
\def \CONSTattstop {... = { }{ }}
\def \CONSTattstopspace { ... = { }{ }}
\def \CONSTauthor {author}
\def \CONSTauto {auto}
\def \CONSTavoid {avoid}
\def \CONSTbase {base}
\def \CONSTbasefont {basefont}
\def \CONSTbefore {before}
\def \CONSTbegin {begin}
\def \CONSTblock {block}
\def \CONSTbold {bold}
\def \CONSTborderstyle {BORDERprofile}
\def \CONSTbottom {bottom}
\def \CONSTBOXcell {BOXcell}
\def \CONSTbp {bp}
\def \CONSTcanadian {Unified Canadian Aboriginal Syllabic}
\def \CONSTcc {cc}
\def \CONSTcell {cell}
\def \CONSTcenter {center}
\def \CONSTck {ck}
\def \CONSTCLASS {CLASS}
\def \CONSTclass {class}
\def \CONSTcm {cm}
\def \CONSTCMR {CMR}
\def \CONSTcmr {cmr}
\def \CONSTCODEPAGE {CODEPAGE}
\def \CONSTcodepage {codepage}
\def \CONSTcodepagenumber {CODEPAGEnumber}
\def \CONSTcolwidth {COLwidth}
\def \CONSTcomma {,}
\def \CONSTcommaquotmark {,"}
\def \CONSTcomment {comment}
\def \CONSTcommentbegin {!--}
\def \CONSTcommentend { --}
\def \CONSTcompatibility {Compatibility}
\def \CONSTconfu {CONFU}
\def \CONSTconfused {confused}
\def \CONSTconst {CONST}
\def \CONSTcontenttype {content-type}
\def \CONSTcontext {CONTEXT}
\def \CONSTcorporateuse {Corporate Use}
\def \CONSTCOURIER {COURIER}
\def \CONSTCourier {Courier}
\def \CONSTCourierNew {CourierNew}
\def \CONSTCourierNewSpace {CourierNew } % includes trailing space
\def \CONSTcp {CP}
\def \CONSTcreated {created}
\def \CONSTdate {date}
\def \CONSTdd {dd}
\def \CONSTde {de}
\def \CONSTdescription {description}
\def \CONSTdest {DEST}
\def \CONSTdepr {DEPR}
\def \CONSTdeprap {DEPRAP}
\def \CONSTdeprecated {deprecated}
\def \CONSTdirection {direction}
\def \CONSTdoctype {DOCTYPE}
\def \CONSTdot {.}
\def \CONSTdotat {.@}
\def \CONSTdotdot {..}
\def \CONSTdotdottwo {../..}
\def \CONSTdotdotthree {../../..}
\def \CONSTdotdotfour {../../../..}
\def \CONSTdotdotfive {../../../../..}
\def \CONSTdotdotsix {../../../../../..}
\def \CONSTdotdotseven {../../../../../../..}
\def \CONSTdotdoteight {../../../../../../../..}
\def \CONSTdothtm {.htm}
\def \CONSTdotjpg {.jpg} 
\def \CONSTdotjpeg {.jpeg} 
\def \CONSTdotpdf {.pdf} 
\def \CONSTdotpng {.png} 
\def \CONSTdotslash {./} 
\def \CONSTdotslashnonejpg {./none.jpg}
\def \CONSTdoublehyphen {--}
\def \CONSTdoublehyphenspace {-- }
\def \CONSTdoublespacehyphen { -- }
\def \CONSTdummy {dummy}
\def \CONSTduplicate {duplicate}
\def \CONSTem {em}
\def \CONSTex {ex}
\def \CONSTEMPTY {EMPTY}
\def \CONSTempty {empty}
\def \CONSTemsp {emsp}
\def \CONSTencoding {ENCODING-}
\def \CONSTend {end}
\def \CONSTendcomment {-->}
\def \CONSTendcommentendscript {--></script>}
\def \CONSTendmark {... = { }}
\def \CONSTendmarkdots {...{ }}
\def \CONSTendmarktwo {... = { }... = { }}
\def \CONSTendmarkequal {={ }{ }}     
\def \CONSTendobject {</object>}
\def \CONSTendscript {</script>}
\def \CONSTendtable {/table}
\def \CONSTendtd {/td}
\def \CONSTendth {/th}
\def \CONSTendtr {/tr}
\def \CONSTensp {ensp}
\def \CONSTentity {ENT}
\def \CONSTexclamation {!}
\def \CONSTextended {Extended}
\def \CONSTextension {Extension}
\def \CONSTexternalid {externalid} % Gedcom
\def \CONSTfallback {fallback}
\def \CONSTff {ff}
\def \CONSTfile {FILE}
\def \CONSTfilelc {file}
\def \CONSTfilter {filter}
\def \CONSTfontfamily {font-family}
\def \CONSTfontsize {font-size}
\def \CONSTfontstyle {font-style}
\def \CONSTfonthyphen {FONT-}
\def \CONSTform {form}
\def \CONSTframespacing {framespacing}
\def \CONSTftp {ftp}
\def \CONSTgedcomxml {GEDCOM XML 6.0}
\def \CONSTglyph {GLY}
\def \CONSTgms {GMS}
{\catcode `\# = \CATother \gdef \CONSThashmark {#}}
\def \CONSTHELVETICA {HELVETICA}
\def \CONSTHelvetica {Helvetica}
\def \CONSTHTMLirreg {HTML irregular}
\def \CONSTHTMLprop {HTML proprietary}
\def \CONSTHTMLstrict {HTML 4.01 strict}
\def \CONSTHTMLtrans {HTML 4.01 transitional}
\def \CONSTHTMLunknown {HTML unknown}
\def \CONSThttp {http}
\def \CONSThttpequiv {http-equiv} % check if needed
\def \CONSThttps {https}
\def \CONSThyphen {-}
\def \CONSThyphgmshyph {-GMS-}
\def \CONSTideograph {Ideograph}
\def \CONSTIMAGE {IMAGE}
\def \CONSTin {in}
\def \CONSTinclinebegin {vvvvvvvvvvvvv}
\def \CONSTinclineend   {^^^^^^^^^^^^^}
\def \CONSTincluded {included}
\def \CONSTinvalidunit {invalidunit}
\def \CONSTisindex {isindex}
\def \CONSTiso {ISO}
\def \CONSTitalic {italic}
\def \CONSTjpegdot {jpeg.}
\def \CONSTjpgdot {jpg.}
\def \CONSTkerning {Kerning}
\def \CONSTkeywords {keywords}
\def \CONSTkrn {KRN-}
\def \CONSTlarge {large}
\def \CONSTlarger {larger}
\def \CONSTlatin {Latin}
\def \CONSTleft {left}
\def \CONSTlineheight {line-height}
{\catcode `\# = \CATother \gdef \CONSTlessthan {<}}
\def \CONSTlevel {level}
\def \CONSTldothtm {l.htm}
\def \CONSTlll {ll}
\def \CONSTll {Ll} % Fixme: rename to \CONSTLl?
\def \CONSTlm {Lm}
\def \CONSTlo {Lo}
\def \CONSTlowsrc {Lowsrc}
\def \CONSTlost {lost}
\def \CONSTlt {Lt}
\def \CONSTltr {ltr}
\def \CONSTlu {Lu}
\def \CONSTmargin {margin}
\def \CONSTmathematic {Mathematic}
\def \CONSTmedium {medium}
\def \CONSTmenu {menu}
\def \CONSTmiddle {middle}
\def \CONSTmiscellaneous {Miscellaneous}
\def \CONSTmisnesting {misnesting}
\def \CONSTmissingwidth {missingwidth}
\def \CONSTmm {mm}
\def \CONSTmonospace {MONOSPACE}
\def \CONSTnbsp {nbsp}
\def \CONSTnest {NEST}
\def \CONSTnext {next}
\def \CONSTnn {nn}
\def \CONSTnone {none}
\def \CONSTnorepeat {no-repeat}
\def \CONSTnormal {normal}
\def \CONSTnumbereight {8}
\def \CONSTnumberfive {5}
\def \CONSTnumberfour {4}
\mef \CONSTnumberlarge = 1200 % 4
\mef \CONSTnumbermedium = 1000 % 3<-\baseFONTsize, to be scaled by 1.2
\def \CONSTnumbermone {-1}
\def \CONSTnumbermthree {-3}
\def \CONSTnumbermtwo {-2}
\def \CONSTnumbernine {9}
\def \CONSTnumberone {1}
\def \CONSTnumberpfour {+4}
\def \CONSTnumberpone {+1}
\def \CONSTnumberpthree {+3}
\def \CONSTnumberptwo {+2}
\def \CONSTnumberseven {7}
\def \CONSTnumbersix {6}
\mef \CONSTnumbersmall = 833 % 2
\def \CONSTnumberthree {3}
\def \CONSTnumbertwo {2}
\mef \CONSTnumberxlarge = 1440 % 5
\mef \CONSTnumberxsmall = 694 % 1
\mef \CONSTnumberxxlarge = 1728 % 6
\mef \CONSTnumberxxsmall = 579
\mef \CONSTnumberxxxlarge = 2074 % 7
\mef \CONSTnumberxxxsmall = 482
\mef \CONSTnumberxxxxlarge = 2488
\mef \CONSTnumberxxxxxlarge = 2986 
\def \CONSTnumberzero {0} 
\def \CONSToblique {oblique}
\def \CONSTonblur {onblur}
\def \CONSTonchange {onchange}
\def \CONSTonclick {onclick}
\def \CONSToncopy {oncopy}
\def \CONSTondblclick {ondblclick}
\def \CONSTonfocus {onfocus}
\def \CONSTonkeydown {onkeydown}
\def \CONSTonkeypress {onkeypress}
\def \CONSTonkeyup {onkeyup}
\def \CONSTonload {onload}
\def \CONSTonmousedown {onmousedown}
\def \CONSTonmousemove {onmousemove}
\def \CONSTonmouseout {onmouseout}
\def \CONSTonmouseover {onmouseover}
\def \CONSTonmouseup {onmouseup}
\def \CONSTonreset {onreset}
\def \CONSTonselect {onselect}
\def \CONSTonsubmit {onsubmit}
\def \CONSTonunload {onunload}
\def \CONSTopen {OPEN}
\def \CONSTother {other}
\def \CONSToverlap {overlap}
\def \CONSTp {p}
\def \CONSTpadding {padding}
\def \CONSTpar {\par}
\def \CONSTparam {param}
\def \CONSTpc {pc}
\def \CONSTpdfdot {pdf.}
{\catcode `\% = \CATother \gdef \CONSTpercent {%}}
\def \CONSTplain {PLAIN}
\def \CONSTpleasedonotwrite {Please do not write}
\def \CONSTpngdot {png.}
\def \CONSTpresentation {Presentation Forms}
\def \CONSTprint {print}
\def \CONSTprop {PROP}
\def \CONSTpropap {PROPAP}
\def \CONSTproppadding {PROPpadding-}
\def \CONSTproprietary {proprietary}
\def \CONSTpt {pt}
\def \CONSTpx {px}
\def \CONSTquotation {?} % Fixme: "question"!
\def \CONSTquotmark {"}
\def \CONSTref {REF}
\def \CONSTrelax {\relax}
\def \CONSTrepeatx {repeat-x}
\def \CONSTrepeaty {repeat-y}
\def \CONSTcolorrgb {colorRGB}
\def \CONSTright {right}
\def \CONSTroman {roman}
\def \CONSTrr {rr}
\def \CONSTrtl {rtl}
\def \CONSTsansserif {SANS-SERIF}
\def \CONSTscreen {screen}
\def \CONSTsemi {;}
\def \CONSTserif {SERIF}
\def \CONSTshade {shade}
\def \CONSTshy {shy}
\def \CONSTslash {/}
\def \CONSTslot {slot}
\def \CONSTsmall {small}
\def \CONSTsmaller {smaller}
\def \CONSTsolid {solid}
\def \CONSTsp {sp}
\def \CONSTspecific {SPECIFIC-}
\def \CONSTstop {STOP}
\def \CONSTstopmark {GMS-STOP}
\def \CONSTstopreference {GMS-STOP}
\def \CONSTstyle {style}
\def \CONSTSTYLE {STYLE}
\def \CONSTstylesheet {stylesheet}
\def \CONSTsummary {summary}
\def \CONSTsuperfluous {superfluous}
\def \CONSTsupplement {Supplement}
\def \CONSTsymbols {Symbols}
\def \CONSTTABLE {TABLE} % Fixme: unused?
\def \CONSTtable {table}
\def \CONSTtag {TAG}
\def \CONSTtext {text}
\def \CONSTtextalign {text-align}
\def \CONSTtextarea {textarea}
\def \CONSTtextcss {text/css}
\def \CONSTtexthtml {text/html}
\def \CONSTtextindent {text-indent}
\def \CONSTtextplain {text/plain}
\def \CONSTtextTeX {text/TeX}
\def \CONSTthatsall { ... = }% with three spaces
\def \CONSTthereshouldbe {there should be}
\def \CONSTthick {thick}
\def \CONSTthin {thin}
\def \CONSTthinsp {thinsp}
\def \CONSTtifdot {tif.}
\def \CONSTtiffdot {tiff.}
\def \CONSTTIMES {TIMES}
\def \CONSTTimes {Times}
\def \CONSTTimesNewRoman {TimesNewRoman}
\def \CONSTtop {top} 
\def \CONSTtotal {verifyWELLFORMtotal}
\def \CONSTtrue {true}
\def \CONSTtt {tt}
\def \CONSTtwocolumns {twocolumns}
\def \CONSTunclosed {unclosed}
\def \CONSTuncolored {uncolored}
\def \CONSTundecl {UNDECL}
\def \CONSTundefclass {undefclass}
\def \CONSTundefined {UNDEFINED } % with trailing space
\def \CONSTundefref {undefref}
\def \CONSTundelimited {undelimited}
\def \CONSTunknown {unknown}
\def \CONSTunlinked {unlinked}
\def \CONSTunquoted {unquoted}
\def \CONSTunrec {UNREC}
\def \CONSTunrecap {UNRECAP}
\def \CONSTunrecognized {unrecognized}
\def \CONSTunsup {UNSUP}
\def \CONSTunsupap {UNSUPAP}
\def \CONSTunsupported {unsupported}
\def \CONSTunrendered {unrendered}
\def \CONSTupskip {LINEupskip}
\def \CONSTverifyplural {verifyPLURAL}
\def \CONSTwbr {wbr}
\def \CONSTwin {WIN}
\def \CONSTwincp {WINCP}
\def \CONSTwindows {windows} 
\def \CONSTwindowsCP {CP125}
\def \CONSTx {x}
\def \CONSTX {X}
\def \CONSTXHTMLstrict {XHTML 1.0 strict}
\def \CONSTXHTMLtrans {XHTML 1.0 transitional}
\def \CONSTxlarge {x-large}
\def \CONSTxml {xml}
\def \CONSTxmllang {xml:lang}
\def \CONSTxmlns {xmlns}
\def \CONSTxmlnshtml {xmlns:html}
\def \CONSTxmlnsutility {xmlns:utility}
\def \CONSTxmlspace {xml:space}
\def \CONSTxsmall {x-small}
\def \CONSTxxlarge {xx-large}
\def \CONSTxxsmall {xx-small}
\def \CONSTzs {Zs}

% CSS: =======================================================================

% Parse style gap (a token sequence of the form 'selectors {declaration}':

\new \ifCSSadded
        
  \let \CSScontext \empty    
  \let \CSScontextbackup \empty
  
  \let \CSSdeclarations \empty 

\bgroup \CATstylegap 
\gdef \CSSget #1[%
  \let \CSSuncommented \empty
  \edef \CSSprobe [#1/*\CONSTstopmark */]%
  \expandafter \CSSgetcomment \CSSprobe \relax
  \expandafter \CSSgetdo \CSSuncommented {}\CSSgetgulp {}\relax]
\egroup

  \ldef \CSSgetcomment #1/*#2*/{%
    \edef \CSSsecond {#2}%
    \edef \CSSuncommented {\CSSuncommented #1}%
    \ifx \CSSsecond \CONSTstopmark \let \CSSnext \relax 
    \else \let \CSSnext \CSSgetcomment \fi \CSSnext}
  
  \bgroup \CATstylegap
  \gldef \CSSgetdo #1{#2}[%
    \let \CSSgetdonext \relax
    \let \GROUPbackup \empty
    \let \CSScontextbackup \empty
    \GAPcheckitvoid 
    \def \CSSselectors [#1]\edef \CSSdeclarations [#2]%
    \ifx \CSSdeclarations \empty \else \ifx \CSSselectors \empty 
      \ifx \CSSdeclarations \CONSTspace \else 
        \CSSgetdoerror \fi \fi \fi
    \ifx \CSSselectors \empty \let \CSSdeclarations \empty \else 
      \ifx \CSSselectors \CONSTspace \let \CSSdeclarations \empty \fi \fi
    \ifx \CSSdeclarations \empty \else
      \ifx \CSSselectors \CONSTdoublespacehyphen \else
        \ifx \CSSselectors \CONSTdoublehyphenspace \else
          \ifx \CSSselectors \CONSTdoublehyphen \else 
            \CSSgetdogr \fi \fi \fi \fi
    \CSSgetdonext]  
  \egroup

    \bgroup \CATstylegap
    \gdef \CSSgetdoerror [% 
      \VERIFYerrorunselected [{\CSSdeclarations}]%
      \let \CSSselectors \CONSTunknown]
    \egroup 
    
    \def \CSSgetdogr {%
      \expandafter \CSSgetdogroup \CSSselectors ,\CONSTstopmark
      \let \CSSgetdonext \CSSgetdo}
        
      \ldef \CSSgetdogroup #1,#2{%
        \edef \CSSgetdogroupsecond {#2}%
        \edef \GROUPparsetest {\GROUPbackup #1\CONSTspace}%
        \expandafter \CSSgetdogroupcontext \GROUPparsetest \CONSTstopmark
        \ifx \CSSgetdogroupsecond \CONSTstopmark \CSSgetdogroupstop
        \else \CSSgetdogrouprun \fi 
        \CSSgetdogroupnext}         
     
        \def \CSSgetdogroupcontext #1 #2{%
          \edef \CSSgetdogroupcontextfirst {#1}%
          \edef \CSScontextparsesecond {#2}%
          \ifx \CSScontextparsesecond \CONSTstopmark \CSSgetdogroupcontextstop
          \else \CSSgetdogroupcontextrun \fi 
          \CSScontextparsenext}

          \def \CSSgetdogroupcontextrun {%
            \edef \CSScontext {%
              \CSScontextbackup \CSSgetdogroupcontextfirst}%
            \ifx \CSScontext \empty \else \CSSgetdogroupcontextsel \fi
            \let \CSScontextbackup \CSScontextparsesecond
            \let \CSScontextparsenext \CSSgetdogroupcontext}
  
          \def \CSSgetdogroupcontextsel {%
            \edef \CSSgetdogroupcontextseltest {%
              \CSScontextbackup \CSSgetdogroupcontextfirst}%
            \expandafter \CSSgetdogroupcontextselector 
              \CSSgetdogroupcontextseltest \relax}
                
            \def \CSSgetdogroupcontextselector #1#2\relax {%
              \edef \CSSgetdogroupcontextselectorprobe {#1#2}%
              \ifx \CSSgetdogroupcontextselectorprobe \CSScontext \else
                \def \CSSgetdogroupcontextselectorfirst {#1}%
                \ifx \CSSgetdogroupcontextselectorfirst \CONSTdot 
                  \lowercase {\edef \CSSgetdogroupcontextselectorsecond {#2}}%
                \else \ifx \CSSgetdogroupcontextselectorfirst \CONSThashmark 
                  \lowercase {%
                    \edef \CSSgetdogroupcontextselectorsecond {ID-#2}}%
                \else \lowercase {\edef 
                  \CSSgetdogroupcontextselectorsecond {#1#2}}\fi \fi
                \ifx \CSScontext \CONSTasteriskslash \else
                  \ifx \CSScontext \empty \else 
                    \CSSgetdogroupcontextselectordo \fi \fi
                \edef \CSSgetdogroupcontextselectorlast {\csname \CONSTSTYLE 
                  \CSSgetdogroupcontextselectorsecond \endcsname}%
                \DEFsearch {\CONSTSTYLE \CSSgetdogroupcontextselectorsecond}%
                \ifDEF \CSSgetdogroupcontextselectoradd \else 
                  \CSSgetdogroupcontextselectornew \fi \fi}   

              \def \CSSgetdogroupcontextselectordo {%
                \edef \CSSgetdogroupcontextselectorsecond {%
                  \CSSgetdogroupcontextselectorsecond 
                  -\CONSTcontext -\CSScontext}}   

              \def \CSSgetdogroupcontextselectoradd {%
                \global \CSSaddedtrue % make style list resident:
                \xDef {\CONSTSTYLE \CSSgetdogroupcontextselectorsecond} {% 
                  \CSSgetdogroupcontextselectorlast ;\CONSTdummy 
                    :\CONSTempty ;\CSSdeclarations}}

              \def \CSSgetdogroupcontextselectornew {% make list resident
                \xDef {\CONSTSTYLE \CSSgetdogroupcontextselectorsecond} {%
                  \CSSdeclarations}} 
    
          \def \CSSgetdogroupcontextstop {%
            \let \CSScontextparsenext \relax
            \CSSgetdogroupcontextsel 
            \let \CSScontextbackup \empty}
            
        \def \CSSgetdogrouprun {%
          \let \GROUPbackup \CSSgetdogroupsecond
          \let \CSSgetdogroupnext \CSSgetdogroup}
  
        \def \CSSgetdogroupstop {%
          \let \CSSgetdogroupnext \relax} 
  \def \CSSgetgulp #1\relax {}
        
  \let \CSSselectors \empty 
    
% DATA: ======================================================================

% Array, compare Knuth, page 378 ("Dirty tricks: list macros"):

\net \DATAarray

\def \DATAarrayafter #1{%
  \DATAarray = \expandafter {#1}%
  \xdef #1{\the \DATAarray \the \DATAarrayentry}}

\def \DATAarraybefore #1{%
  \DATAarray = \expandafter {#1}%
  \xdef #1{\the \DATAarrayentry \the \DATAarray}}

\net \DATAarrayentry

\ldef \DATAarrayone [#1] {%
  \DATAarrayentry = {\\ [#1] }}
\ldef \DATAarraytwo [#1] [#2] {%
  \DATAarrayentry = {\\ [#1] [#2] }}
\ldef \DATAarraythree [#1] [#2] [#3] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] }}
\ldef \DATAarrayfour [#1] [#2] [#3] [#4] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] [#4] }}
\ldef \DATAarrayfive [#1] [#2] [#3] [#4] [#5] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] [#4] [#5] }}
\ldef \DATAarraysix [#1] [#2] [#3] [#4] [#5] [#6] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] [#4] [#5] [#6] }}
\ldef \DATAarrayseven [#1] [#2] [#3] [#4] [#5] [#6] [#7] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] [#4] [#5] [#6] [#7] }}
\ldef \DATAarrayeight [#1] [#2] [#3] [#4] [#5] [#6] [#7] [#8] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] [#4] [#5] [#6] [#7] [#8] }}
\ldef \DATAarraynine [#1] [#2] [#3] [#4] [#5] [#6] [#7] [#8] [#9] {%
  \DATAarrayentry = {\\ [#1] [#2] [#3] [#4] [#5] [#6] [#7] [#8] [#9] }}

% Hex numbers, compare Knuth, page 219 (modified to assemble output in a token
% register):
  
\def \DATAhex {%
  \the \DATAhexdigit}  
  
  \net \DATAhexdigit

  \DATAhexdigit = {{%
    \count 0 = \DATAhexinput
      \divide \DATAhexinput by 16 \ifnum \DATAhexinput > 0 \DATAhex \fi
      \count 2 = \DATAhexinput \multiply \count 2 by -16
    \advance \count 0 by \count 2
    \ifcase \count 0
      \DATAhexdigitappend 0\or \DATAhexdigitappend 1\or 
      \DATAhexdigitappend 2\or \DATAhexdigitappend 3\or 
      \DATAhexdigitappend 4\or \DATAhexdigitappend 5\or 
      \DATAhexdigitappend 6\or \DATAhexdigitappend 7\or
      \DATAhexdigitappend 8\or \DATAhexdigitappend 9\or 
      \DATAhexdigitappend A\or \DATAhexdigitappend B\or
      \DATAhexdigitappend C\or \DATAhexdigitappend D\or 
      \DATAhexdigitappend E\or \DATAhexdigitappend F\else
      \DATAhexdigitappend 0\relax \fi}} % ignore invalid values
    
    \def \DATAhexdigitappend #1{%
      \global \DATAhexoutput = \expandafter {\the \DATAhexoutput #1}}

\nec \DATAhexinput

\net \DATAhexoutput

% Length of string (compare Knuth, page 219):

\nec \DATAlength

\def \DATAlengthget #1{% count nonblank tokens in string #1
  \DATAlength = 0 
  \expandafter \DATAlengthparse #1\end}

  \def \DATAlengthparse #1{%
    \ifx \end #1\let \DATAlengthnext \relax \else
      \advance \DATAlength by 1
      \let \DATAlengthnext \DATAlengthparse
    \fi \DATAlengthnext}
  
% A "stack" is a data structure like {cherry/peach/apple/plum/}. Item "plum"
% is the last one that has been pushed onto it, and it would be the first to
% be popped from it; compare Wolfgang Appelt: TeX fuer Fortgeschrittene, pages
% 52 to 54.

% Type A used for chains (directories):

\ldef \DATAstackpop #1\from #2{%
  \xdef \DATAstack {#2}%
  \ifx \DATAstack \empty \let #1\empty \else
    \def \DATAstackparse ##1/##2\relax {%
      \xdef #1{##2}%
      \xdef #2{##1}}%
    \expandafter \DATAstackparse \DATAstack \relax \fi}

\ldef \DATAstackpush #1\to #2{%
  \xdef #2{#2/#1}}%  #1: item,  #2: stack

% Type B used for nested tables:

\ldef \DATAstackxpop #1\from #2{%
  \xdef \DATAstackx {#2}%
  \ifx \DATAstackx \empty \let #1\empty \else
    \def \DATAstackxparse ##1/##2\relax {%
      \xdef #1{##1}%
      \xdef #2{##2}}%
    \expandafter \DATAstackxparse \DATAstackx \relax \fi}

\def \DATAstackxpopnumber #1\from #2{% #1: count register
  \DATAstackxpop \DATAstackxprobe \from #2%
  \ifx \DATAstackxprobe \empty \def \DATAstackxprobe {0}\fi 
  \global #1 = \DATAstackxprobe 
  \edef \DATAstackxprobe {\the #1}} % dummy expand

\ldef \DATAstackxpush #1\to #2{%
  \xdef #2{#1/#2}}%  #1: item,  #2: stack

% ELEMENT: ===================================================================

\net \ELEMENT

\new \ifELEMENTblock

\def \ELEMENTblockindent {% generic
  \ifELEMENTblock
    \ifhmode %%%
      \par 
    \fi %%%
    \FLOATindentnone \global \GAPspacenowtrue \fi}      
      
\def \ELEMENTblockindentbyno {%
  \ifALIGNcenter \ELEMENTblockindentbynozero \else 
    \ifnum \NOpar = 1 \ELEMENTblockindentbynozero \else 
      \ELEMENTblockindentbynosquare \fi \fi}
           
  \def \ELEMENTblockindentbynosquare {%
    \parindent = 2\LINEheight \advance \parindent by -1ex \FLOATindent}
    
  \def \ELEMENTblockindentbynozero {% 
    \parindent = 0mm \FLOATindentnone}     

% Markup elements can be nested, and this routine checks for well-formedness;
% compare Knuth, pages 21 and 306:

\def \ELEMENTcloseinner {%
  \ifinner \message {</>}\aftergroup \ELEMENTcloseinner \endgroup \fi}

\def \ELEMENTclosenest #1{%
  \csname if\CONSTopen #1\endcsname 
    \VERIFYerrormissingendtag {\csname \CONSTconst #1\endcsname }\fi}

\def \ELEMENTcloseouter {%
  \ifnum \ELEMENTlevel > 0
    \message {</...>}\aftergroup \ELEMENTcloseouter \endgroup \fi} 
    
\let \ELEMENTcontent \empty

\def \ELEMENTcount {%
  \global \advance \verifyWELLFORMtotalelements by 1 }

\nec \ELEMENTlevel

\let \ELEMENTname \empty

\ldef \ELEMENTnew #1
  \beforestart #2\openstart #3\afterstart % start tag commands
  \beforeend #4\closeend #5\afterend {% end tag commands     
    \ELEMENTnewopen {#1}\Message {#1}%
    \gDef \CONSTconst #1 {#1}%
    \glDef \CONSTtag #1 {% define start tag
      \csname \CONSTnest #1\CONSTbegin \endcsname
      #2\message {<#1}\COLORrtl \ELEMENTcount
      \begingroup \advance \ELEMENTlevel by 1     
      \csname \CONSTopen #1\CONSTtrue \endcsname
      \def \ELEMENTname {#1}#3\message {>}}%
    \glDef \CONSTtag /#1 {% define end tag     
      \csname \CONSTnest #1\CONSTend \endcsname
      \COLORltr #4\message {<}\def \ELEMENTnewtest {#1}\message {/#1>}%
      \ifx \ELEMENTnewtest \ELEMENTname \else 
        \VERIFYerrorsuperfluous \begingroup \fi
      \COLORrtl \endgroup \COLORltr #5}}
            
\ldef \ELEMENTnewblock #1 % new 2008/06/15 - 2007/07/13
  \beforestart #2\openstart #3\initstart #4\afterstart % start tag commands
  \beforeend #5\closeend #6\afterend {% end tag commands  
    \ELEMENTnew #1
      \beforestart \GAPwritedonospacetrue 
        \GAPwrite 
        \ifhmode \ALIGNend \BIDIend \par 
        \fi #2%    
        \openstart 
          \BLOCKemptytrue %%% check this
          \MARGINtopgivenfalse \MARGINbottomgivenfalse #3%
          \ELEMENTvalueget
          \ifLINKunrendered \else 
            \ifMARGINtopgiven \vskip \MARGINtop \fi
            \BIDIbegin \fi 
          \COLORizeforeground \FONTdo #4%
        \afterstart
      \beforeend 
        \GAPwrite 
        \ifLINKunrendered \else
          \ifhmode 
            \ifGAPspacenow \hskip -\spaceskip \fi %%%
            \ALIGNend \BIDIend \par \fi
          \ifBLOCKspacer %%%
            \ifdim \pagetotal > \pagegoal \LINEupskip \else %%%
            \ifdim \pagetotal < \LINEheight \LINEupskip \fi \fi %%%
          \fi %%%
          \global \BLOCKspacerfalse %%%
          \ifMARGINbottomgiven \vskip \MARGINbottom \fi \fi
        #5\closeend #6\afterend}
        
\def \ELEMENTnewblockh #1 #2 #3 #4 #5 {%
  \ELEMENTnewblock h#1
  \beforestart
    \global \hangindent = 0mm \global \hangafter = 1
    \NOh = #1 % heading counter
    \global \advance \count #1 by 1 \MESSAGEh 
  \openstart \OPENhtrue \OUTPUTnopagecheck
    \NOparresetglobal \parindent = 0mm
    \FONTname = \FONTbold \FONTboldtrue
    \MARGINgivenfalse \SIZEgivenfalse
  \initstart
    \ifSIZEgiven \else \advance \SIZEbase by #2 \fi    
    \ifdim \pagetotal > 0.85\pagegoal \break \fi %%%
    \vbox \bgroup 
      \edef \TAGhlineheightold {\the \LINEheight}% 
      \ifLINEheightgiven \else \LINEheight = #3\LINEheight \fi
      \GAPsetstrut 
      \ifMARGINtopgiven      
        \ifdim \pagetotal = 0pt %%%
          \ifdim \MARGINtop > 0pt \vskip \topskip \fi %%% 
        \else {\dimen 7 = \pagetotal %%%
          \advance \dimen 7 by 2\LINEheight %%%
          \ifdim \dimen 7 > \pagegoal \vskip \topskip \fi }%  %%% 
        \fi %%%
      \else {%
        \LINEheight = \TAGhlineheightold \vskip #4\LINEheight}\fi
      \FONTdo %%% Fixme: avoid
      \ALIGNrespace \GAPlogtrue 
      \strut %%% check this: why explicitly?
    \afterstart    
  \beforeend 
      \ifMARGINbottomgiven \else {%
        \LINEheight = \TAGhlineheightold \vskip #5\LINEheight }\fi  
    \egroup %%%
  \closeend \nointerlineskip 
    \noecho \GAPlogfalse  
  \afterend}
         
% Heading  Empty  Scaling  Line-     Space    Space    Space
% Level:   lines: factor:  height:   overall: before:  after:
%   H1       7    2.48832  3         4        3        1
%   H2       6    2.0736   3         3        2.25     0.75    
%   H3       5    1.728    2         3        2.25     0.75    
%   H4       4    1.44     2         2        1.5      0.5   
%   H5       3    1.2      2         1        0.75     0.25 
%   H6       2    1        1         1        0.75     0.25

\def \ELEMENTnewdefa #1 #2 {%
  \ELEMENTnew #1
    \beforestart \GAPwrite
    \openstart \ELEMENTvalueget #2\afterstart 
    \beforeend \GAPwrite \closeend \afterend}          
    
\ldef \ELEMENTnewgeneric #1 {% 2007/03/09
  \lowercase {\edef \ELEMENTnewgenericfirstspace {#1 }}%
  \expandafter \ELEMENTnew \ELEMENTnewgenericfirstspace  
    \beforestart \GAPwrite
    \openstart \ELEMENTblockfalse \ELEMENTvalueget
      \ELEMENTblockindent %%%
      \ELEMENTnewgenericpseudo \CONSTbefore
      \FONTdo \COLORize \COLORforeground \afterstart 
    \beforeend \GAPwrite \ELEMENTnewgenericpseudo \CONSTafter
    \closeend \afterend}    
    
  \def \ELEMENTnewgenericpseudo #1{%
    \DEFsearch {\CONSTSTYLE \ELEMENTname :#1}%
    \ifDEF \bgroup \ELEMENTblockfalse 
      \ELEMENT = \expandafter {\ELEMENTname :#1}%   
      \ELEMENTvaluegetstyle 
      \ELEMENTblockindent
      \FONTdo \COLORize \COLORforeground
      \global \GAP = \expandafter {\ELEMENTcontent }\GAPwrite
      \egroup \fi}  
      
\def \ELEMENTnewopen #1{%
  \expandafter \ELEMENTnewopenstart
  \csname ifOPEN#1\endcsname}

\def \ELEMENTnewopenstart {%
  \csname newif\endcsname}  

\let \ELEMENTopen \empty

\def \ELEMENTvalueget {%
  \ELEMENTvaluegetstyle 
  \ifATT \ATTget \fi
  \ifPROP \PROPget \fi}

  \def \ELEMENTvaluegetstyle {%
    \DEFsearch {\CONSTSTYLE \the \ELEMENT}%
    \ifDEF \ELEMENTvaluegetstyledo \fi}

    \def \ELEMENTvaluegetstyledo {%
      \expandafter \PROPlistget \csname 
        \CONSTSTYLE \the \ELEMENT \endcsname}

% ENTITY: ====================================================================

\begingroup \CATentity

\gldef <!-- @1@2-->{\relax}   

\gldef <!ENTITY @1>{\ENTITYparse @1}

\endgroup 

\ldef \ENTITYadd #1.#2 {% add ENTITY names file to the ENTITYname list
  \ldef \ENTITYaddfirst {#1}%
  \ifx \ENTITYaddfirst \empty \else
    \long \edef \ENTITYadditem {[#1.#2] }%
    \expandafter \DATAarrayone \ENTITYadditem \DATAarrayafter \ENTITYname \fi}

\let \ENTITYname \empty

\def \ENTITYnamesload {{% load ENTITY names files found on ENTITYname list
  \immediate \openout 6 entity.lst
    \CATentity
    \def \\ [##1] {\def \ENTITYnamesloadfirst {##1}%
      \ifx \ENTITYnamesloadfirst \empty \else 
        \hyphenmessage \input \ENTITYnamesloadfirst \fi}%
    \ENTITYname
  \immediate \closeout 6 }}

\def \ENTITYnamesshow {%
  \immediate \backupwrite 18{sort < entity.lst > sortent.lst}%   
  \def \ENTITYnamesshowtest {WIN32}%
  \ifx \OS \ENTITYnamesshowtest \openin 7 = entity.lst 
  \else \openin 7 = sortent.lst \fi
    \loop \FILEcheckeof 7 \ifFILEnotended \read 7 to \ENTITYnamesshowline
      \edef \ENTITYnamesshowline {\ENTITYnamesshowline \CONSTspace}%
      \expandafter \MESSAGEentityname \ENTITYnamesshowline
    \repeat \closein 7}

\begingroup \CATentity

  \ifx \eTeXversion \undefined % parse ENTITY file double line
    \gldef \ENTITYparse
      @1            % HTML character name
      CDATA "&#@2;" % HTML character number (dec.)
      -- @3,        % Unicode character name
      U+@4          % Unicode character number (hex.)
      @5--{%        % ISO codepage etc.
        \ifnum "@4 > 255 \else 
          \immediate \backupwrite 6{@1}%
          % Set unicode reference:
          \xDef {\CONSTref @1} {@4}\fi}%
  \else
    \gldef \ENTITYparse
      @1            % HTML character name
      CDATA "&#@2;" % HTML character number (dec.)
      -- @3,        % Unicode character name
      U+@4          % Unicode character number (hex.)
      @5--{%        % ISO codepage etc.
        \UNICODEslotset {"@4}%
        \edef \ENTITYparseslot {\the \UNICODEslot slot}%
        \DEFsearch \ENTITYparseslot \ifDEF
          \UNICODEslotpointregset {"@4}%
          \UNICODEdataset -;-;-;-;-;-;-;@1;\relax
          \global \toks \UNICODEslotpointreg = 
            \expandafter {\the \UNICODEdata}%
          \immediate \backupwrite 6{@1}%
          % Set unicode reference:
          \xDef {\CONSTref @1} {@4}%
        \else \ERRmessnoslot \fi}\fi
        
\endgroup 

% FILE: ======================================================================

\def \FILEcheckeof #1{% end of file check 
  \ifeof #1\relax \FILEnotendedfalse \else \FILEnotendedtrue \fi}

\new \ifFILEexist

\new \ifFILEhtml

\let \FILEname \empty

\def \FILEnameget {%
  \URLinternetfalse 
  \expandafter \FILEnamegetprobe \FILEsource \relax
  \expandafter \URLgetinternet \FILEsource ://\relax 
  \FILEnamegetsource 
  \ifURLinternet \let \FILEnamegetrelated \relax \fi 
  \FILEnamegetrelated}   
    
  \def \FILEnamegetprobe #1#2\relax {% get file name from file FILEsource
    \def \FILEnamegetfirst {#1}%
    \ifx \FILEnamegetfirst \CONSTslash 
      \edef \FILEnameprobe {\FILEsource /}% Fixme: use leading ServerRoot
    \else \edef \FILEnameprobe {../\FILEsource /}\fi}
    
  \def \FILEnamegetrelated {%
    \let \CHAINfolderbackup \CHAINfoldercurrent
      \OPENobjecttrue 
        \let \FILEnameprobe \empty
        \expandafter \CHAINcopyrelativepath \FILEsource \to \FILEnameprobe
      \OPENobjectfalse
      \edef \FILEname {.\CHAINfoldercurrent /\FILEname}%
      \edef \FILEnameprobe {../\FILEnameprobe /}%
      \FILEnamegetsource
      \edef \FILEname {\FILEpath/\FILEname}%
    \glet \CHAINfoldercurrent \CHAINfolderbackup}
    
  \def \FILEnamegetsource {%
    \let \FILEname \empty
    \let \FILEpath \empty
    \let \FILEsourcelast \empty
    \expandafter \FILEnamegetsourceparse \FILEnameprobe \relax
    \expandafter \FILEnamegetsourceimage \FILEname .\relax}    
    
    \ldef \FILEnamegetsourceimage #1.#2\relax {% jpg if extension unsupported
      \lowercase {\def \FILEimageextensionsecond {#2}}% 
      \ifx \FILEimageextensionsecond \CONSTjpegdot \else
      \ifx \FILEimageextensionsecond \CONSTjpgdot \else 
      \ifx \FILEimageextensionsecond \CONSTpdfdot \else 
      \ifx \FILEimageextensionsecond \CONSTpngdot \else
      \edef \FILEname {#1.jpg}\fi \fi \fi \fi}     

    % Fixme: used globally:
    \def \FILEnamegetsourceparse #1/#2{% extract leading path
      \edef \FILEsourcefirst {#1}% 
      \edef \FILEsourcesecond {#2}%
      \ifx \FILEsourcesecond \CONSTrelax
        \FILEnamegetsourceparserelax
      \else \FILEnamegetsourceparsenorelax \fi 
      \FILEsourcenext}

      \def \FILEnamegetsourceparsenorelax {%
        \let \FILEsourcenext \FILEnamegetsourceparse
        \ifx \FILEname \empty 
          \let \FILEpath \FILEsourcesecond
        \else \FILEnamegetsourceparsenotempty \fi 
        \let \FILEname \FILEsourcesecond}

        \def \FILEnamegetsourceparsenotempty {%
          \ifx \FILEsourcefirst \empty \else 
            \edef \FILEpath {\FILEpath /\FILEsourcelast \FILEsourcefirst}\fi
          \edef \FILEsourcelast {\FILEsourcesecond}}

      \def \FILEnamegetsourceparserelax {%
        \let \FILEsourcenext \relax     
        \edef \FILEname {\FILEname \FILEsourcefirst}}
    
\new \ifFILEnotended 

\new \ifFILEplain

\newread \FILEplaintext

\def \FILEsearch #1{% file existence check
  \openin \FILEsearched = #1\relax
  \ifeof \FILEsearched \FILEexistfalse \else \FILEexisttrue \fi
  \closein \FILEsearched}

  \newread \FILEsearched

\def \FILEsearchimage #1.jpg#2\relax {%
  \edef \FILEsearchimagetest {#2}%
  \ifx \FILEsearchimagetest \empty \else 
    \xdef \FILEname {#1.png}%
    \FILEsearch \FILEname 
    \ifFILEexist \else \VERIFYerrorabsent \FILEname \fi \fi}
    
\new \ifFILETeX

\let \FILEthis \empty

\new \ifFILEtoomany

% FLOAT: =====================================================================

\def \FLOATindent {% new 2007/07/07; compare Knuth, pages 103, 315, 316
  \FLOATindentprevious \indent \FLOATindentnext}
  
\def \FLOATindentnone {%
  \FLOATindentprevious \noindent \FLOATindentnext}  
  
  \def \FLOATindentprevious {%
    \ifnum \prevgraf < -\hangafter
      \edef \FLOATindentnext {\prevgraf = \the \prevgraf}%
    \else \let \FLOATindentnext \empty 
      \global \hangafter = 0 
      \global \hangindent = 0pt \fi}
    
\def \FLOATingbeginother {%
  \hbox to 0mm 
  \bgroup \hskip -\TEXTindent \hskip -\hangindent
    \vbox to 0mm \bgroup \vskip -1ex }   

\def \FLOATingbeginright {%
  \global \hangindent = -\hangindent
  \hbox to 0mm \bgroup
    \hskip -\TEXTindent \hskip \hangindent 
    \hskip \hsize \hskip \LINEheight \hskip -1ex
    \vbox to 0mm \bgroup \vskip -1ex }  
        
\def \FLOATingend {%
  \vss \egroup \hss \egroup}
  
\def \FLOATpagebegin #1{% #1: dimen register % new 2007/03/01 
  \FLOATpagefreespace = \pagegoal % Fixme: use for tables too
  \advance \FLOATpagefreespace by -\pagetotal
  \ifnum \widowpenalty = 10000 %%%
    \advance \FLOATpagefreespace by -\LINEheight \fi %%%
  \xdef \FLOATpageheight {\the #1}%
  \ifdim \FLOATpagefreespace < \FLOATpageheight 
    \ifdim \FLOATpagefreespace > 0pt
      \OBEYpagebreak \parindent = 0pt \noindent 
      \global \FLOATpageextrabreaktrue \fi \fi}
    
\def \FLOATpageend {%
  \ifFLOATpageextrabreak
    \ifdim \pagetotal > \FLOATpageheight
      \global \hangafter = 1
      \global \hangindent = 0pt
      \global \FLOATpageextrabreakfalse   
    \else \FLOATpagefreespace = \FLOATpageheight
      \advance \FLOATpagefreespace by -\pagetotal
      \FLOATsizeheight \FLOATpagefreespace \fi \fi} 
      
\new \ifFLOATpageextrabreak 
    
\ned \FLOATpagefreespace

\let \FLOATpageheight \LINEheight 
      
\def \FLOATsizeheight #1{%
  \global \hangafter = -#1%
  \ifdim \LINEheight > 0mm
    \global \divide \hangafter by \LINEheight % Check this
    \global \advance \hangafter by -1
  \else \VERIFYerrornolineheight \fi}

\def \FLOATsizewidth #1{%
  \global \hangindent = #1%
  \global \advance \hangindent by -1ex
  \global \advance \hangindent by \LINEheight
  \ifdim \hangindent > \hsize \global \hangindent = \hsize \fi} 

\def \FLOATtable {%
  \ifOPENp \ifnum \TABLEnesting = 1
    \global \advance \TABLEheight by \TABLEswap
    \FLOATsizeheight \TABLEheight \fi \fi
  \let \TABLEnext \relax
  \ifOPENp \ifnum \TABLEnesting = 1 
    \let \TABLEnext \FLOATingend \fi \fi 
  \TABLEnext}   

\def \FLOATtablealign {%     
  \ifOPENp \let \TABLEalignnext \FLOATtablealigndofloat 
  \else \let \TABLEalignnext \FLOATtablealigndonotfloat \fi 
  \TABLEalignnext
  \hsize = \BOXwidth}     
  
  \def \FLOATtablealigndofloat {%
    \let \TABLEalignnext \relax
    \ifnum \TABLEnesting = 1
      \FLOATsizewidth \BOXwidth
      \ifx \TABLEalign \CONSTright 
        \let \TABLEalignnext \FLOATingbeginright 
      \else \let \TABLEalignnext \FLOATingbeginother \fi \fi
    \BOXindent = 0mm \TABLEalignnext}

  \def \FLOATtablealigndonotfloat {%
    \ALIGNleftfalse \ALIGNcenterfalse \ALIGNrightfalse
    \ifx \TABLEalign \CONSTright \advance \BOXindent by -\BOXwidth \else
      \ifx \TABLEalign \CONSTcenter \advance \BOXindent by -\BOXwidth
        \divide \BOXindent by 2 
      \else \BOXindent = 0mm \fi \fi
    \advance \BOXindent by -\BORDER}

% FONT: ======================================================================

\def \FONTacrobatcheck {%
  \FONTfamily = \expandafter {\FONTfamilyparsetest}%
  \ifx \FONTfamilyparsetest \CONSTArial 
    \FONTacrobatset \CONSTHelvetica \CONSTHELVETICA
  \else \ifx \FONTfamilyparsetest \CONSTCourierNew
    \FONTacrobatset \CONSTCourier \CONSTCOURIER
  \else \ifx \FONTfamilyparsetest \CONSTCourierNewSpace %%%
    \FONTacrobatset \CONSTCourier \CONSTCOURIER %%%
  \else \ifx \FONTfamilyparsetest \CONSTTimesNewRoman 
    \FONTacrobatset \CONSTTimes \CONSTTIMES % Fixme: check space too
  \fi \fi \fi \fi}

\def \FONTacrobatset #1#2{%
  \FONTfamily = \expandafter {#1}%
  \edef \FONTfamilyuc {#2}%
  \FONTfamilymatchdo \FONTchoosedo}
  
\net \FONTbase
\net \FONTbaseitalic

\net \FONTbold 
\new \ifFONTbold 
\net \FONTbolditalic 

\def \FONTchangename {%
  \FONTmodechange \COLORizeforeground}
  
\def \FONTchoose {%
  \FONTchooseresettrue % Fixme: backup old font if reset should be necessary
  \FONTfamilyget \FONTchoosedo
  \ifFONTdefault \FONTchoosedefault \else \FONTchoosereset \fi
  \FONTname = \FONTbase}

  \def \FONTchoosedefault {%
    \CODEPAGEplaintrue
    \def \FONTfamilyuc {CMR}%
    \FONTfamily = {cmr}%
    \FONTbase = {cmr10}%
    \FONTbaseitalic = {cmti10}%
    \FONTbold = {cmbx10}%
    \FONTbolditalic = {cmbx10}}
    
  \def \FONTchoosedefine #1#2{%
    \csname \CONSTfonthyphen \CODEPAGE -\FONTfamilyuc -#1-#2\endcsname}
    
  \def \FONTchoosedo {% use fill-up hierarchy if some font faces are missing
    \FONTchoosedoface 00\FONTchoosedofacebase
    \FONTchoosedoface 01\FONTchoosedofacebaseitalic
    \FONTchoosedoface 10\FONTchoosedofacebold
    \FONTchoosedoface 11\FONTchoosedofacebolditalic}

    \def \FONTchoosedoface #1#2#3{%
      \DEFsearch {\CONSTfonthyphen \CODEPAGE -\FONTfamilyuc -#1-#2}%
      \ifDEF #3\fi}
  
    \def \FONTchoosedofacebase {%
      \FONTbase = {\FONTchoosedefine 00}\FONTchooseresetfalse
      \FONTbaseitalic = \FONTbase 
      \FONTbold = \FONTbase
      \FONTbolditalic = \FONTbase}

    \def \FONTchoosedofacebaseitalic {%
      \FONTbaseitalic = {\FONTchoosedefine 01}\FONTchooseresetfalse
      \FONTbolditalic = \FONTbaseitalic
      \FONTbold = \FONTbaseitalic}

    \def \FONTchoosedofacebold {%
      \FONTbold = {\FONTchoosedefine 10}\FONTchooseresetfalse}

    \def \FONTchoosedofacebolditalic {%
      \FONTbolditalic = {\FONTchoosedefine 11}\FONTchooseresetfalse}
      
  \new \ifFONTchoosereset

  \def \FONTchoosereset {%
    \ifFONTchoosereset \ifCODEPAGEplain \else 
      \VERIFYerrorfontreset \FONTfamilyuc \FONTchoosedefault \fi \fi}

% Fixme: Use integer font size (in pt) for CM fonts (DVI output compatibility) 

\def \FONTcmital {%
  \font \FONT = cmti10 at \SIZEcurrent \FONT}

\def \FONTcmmath {%
  \font \FONT = cmmi10 at \SIZEcurrent \FONT}

\def \FONTcmsmall {%
  \ifFONTitalic
    \ifFONTbold \font \FONT = cmbx10 at .667\SIZEcurrent \else
      \font \FONT = cmti10 at .667\SIZEcurrent \fi
  \else \ifFONTbold \font \FONT = cmbx10 at .667\SIZEcurrent \else
      \font \FONT = cmr10 at .667\SIZEcurrent \fi \fi \FONT}   

\def \FONTcmsmalltype {%
  \font \FONT = cmtt10 at 0.667\SIZEcurrent \FONT}

\def \FONTcmsymb {%
  \font \FONT = cmsy10 at \SIZEcurrent \FONT} 

\def \FONTcmtext {% Fixme: do font-size-adjust?
  \ifFONTitalic
    \ifFONTbold \font \FONT = cmbx10 at \SIZEcurrent \else % not italic
      \font \FONT = cmti10 at \SIZEcurrent \fi
  \else \ifFONTbold \font \FONT = cmbx10 at \SIZEcurrent \else
      \font \FONT = cmr10 at \SIZEcurrent \fi \fi \FONT}

\def \FONTcmtype {%
  \font \FONT = cmtt10 at \SIZEcurrent \FONT} 

\new \ifFONTdecoration

\new \ifFONTdefault

\def \FONTdo {%
  \ifdim \SIZE > 0mm
    \SIZEcurrent = \SIZE
    \ifFONTsizeadjust \FONTsizeadjust \fi
    \SIZEmagnify \FONTnametestget
    \ifx \FONTnametest \empty \FONTrescue \fi
    \font \FONT = \FONTnametest \CONSTat \SIZEcurrent \FONT
    \ifnum \KERNING > 0 \ifKERNINGdone \else \ifALIGNcenter \else 
      \KERNINGdo \fi \fi \fi
    \ifALIGNcenter \ALIGNrespace \else
      \ifALIGNleft \ALIGNrespace \else
        \ifALIGNright \ALIGNrespace \fi \fi \fi
  \else \VERIFYerrorinvalidfontsize \fi}       

\def \FONTdoinner {%
  \ifOPENtd \OPENfontinnertrue \else 
    \ifOPENth \OPENfontinnertrue \else
      \ifOPENp \OPENfontinnertrue \else 
        \OPENfontinnerfalse \fi \fi \fi}
        
\def \FONTdomono {%
  \FONTfamily = \FONTmono \FONTchoose \FONTdo}
  
\def \FONTfallback {\FONTfallbackserif}

\edef \FONTfallbackmonospace {\the \FONTmonospace} 

\def \FONTfallbackresetcmr {%
  \let \FONTfallback \CONSTcmr
  \let \FONTfallbackuc \CONSTCMR
  \ifx \FONTfamilymatchuc \empty \FONTdefaulttrue \fi}

\def \FONTfallbackresetmonospace {%
  \let \FONTfallback \FONTfallbacksmonospace
  \let \FONTfallbackuc \FONTfallbackmonospaceuc}

\def \FONTfallbackresetsansserif {% 
  \let \FONTfallback \FONTfallbacksansserif
  \let \FONTfallbackuc \FONTfallbacksansserifuc}

\def \FONTfallbackresetserif {% 
  \let \FONTfallback \FONTfallbackserif
  \let \FONTfallbackuc \FONTfallbackserifuc}
  
\edef \FONTfallbacksansserif {\the \FONTsansserif}

\edef \FONTfallbackserif {\the \FONTserif}

\def \FONTfallbackset {%
  \expandafter \FONTfallbacksetmonospace \FONTfallbackmonospace \relax
  \expandafter \FONTfallbacksetsansserif \FONTfallbacksansserif \relax
  \expandafter \FONTfallbacksetserif \FONTfallbackserif \relax} 
  
  \def \FONTfallbacksetmonospace #1\relax {%
    \uppercase {\xdef \FONTfallbackmonospaceuc {#1}}}

  \def \FONTfallbacksetsansserif #1\relax {%
    \uppercase {\xdef \FONTfallbacksansserifuc {#1}}}

  \def \FONTfallbacksetserif #1\relax {%
    \uppercase {\xdef \FONTfallbackserifuc {#1}}} 
  
\def \FONTfallbackuc {\FONTfallbackserifuc}

\net \FONTfamily
\net \FONTfamilybackup  

\def \FONTfamilyget {%
  \let \FONTfallback \FONTfallbackserif
  \let \FONTfallbackuc \FONTfallbackserifuc
  \let \FONTfamilymatchuc \empty
  \edef \FONTfamilygettest {\the \FONTfamily}%
  \ifx \FONTfamilygettest \empty \else
    \expandafter \FONTfamilyparse \the \FONTfamily,,,\fi   
  \ifFONTdefault \let \FONTfamilymatchuc \CONSTCMR \fi
  \ifx \FONTfamilymatchuc \empty \FONTfamilygetdo \fi 
  \let \FONTfamilyuc \FONTfamilymatchuc
  \ifx \FONTfamilyuc \empty \let \FONTfamilyuc \CONSTCMR \fi}

  \def \FONTfamilygetdo {%
    \FONTchooseresettrue \FONTdefaultfalse
    \edef \FONTfamilyuc {\the \FONTfamily}% 
    \ifCODEPAGEplain \else \FONTfamilygetdoit \fi}

    \def \FONTfamilygetdoit {%
      \edef \FONTfamilylist {\the \FONTfamily}%
      \edef \FONTfamilyparseprobe {\the \FONTfamily \CONSTspace}%
      \expandafter \FONTfamilycheckspaces \FONTfamilyparseprobe \relax
      \ifx \FONTfamilyparseprobe \FONTfamilyparsetest
        \expandafter \FONTfamilycheckquotes \FONTfamilyparseprobe ""\relax
        \ifx \FONTfamilyparseprobe \FONTfamilyparsetest 
          \expandafter \expandafter \expandafter
            \FONTnoneforcodepage \expandafter {\FONTfamilylist}%        
        \else \FONTacrobatcheck \fi
      \else \FONTacrobatcheck \fi} %%%  

      \def \FONTfamilycheckquotes #1"#2"#3\relax {%
        \def \FONTfamilycheckquotessecond {#2}%
        \ifx \FONTfamilycheckquotessecond \empty \else 
          \edef \FONTfamilyparsetest {#2}\fi}
      
      \def \FONTfamilycheckspaces #1 #2\relax {%
        \def \FONTfamilycheckspacessecond {#2}%
        \edef \FONTfamilyparsetest {#1#2}%
        \ifx \FONTfamilycheckspacessecond \empty \else 
          \ifx \FONTfamilycheckspacessecond \CONSTspace
            \edef \FONTfamilyparsetest {#1}\fi \fi}   

\new \ifFONTfamilygiven

\let \FONTfamilylist \empty

\let \FONTfamilymatchuc \empty

\def \FONTfamilymatchdo {%
  \DEFsearch {\CONSTfonthyphen \CODEPAGE -\FONTfamilyuc -0-0}\ifDEF 
    \let \FONTfamilymatchuc \FONTfamilyuc \fi} 

\def \FONTfamilyparse #1#2,{% get uppercase font family name from list
  \edef \FONTfamilyparsetest {#2}% 
  \uppercase {\edef \FONTfamilyparsetestuc {#1#2}}%
  \ifx \FONTfamilyparsetestuc \CONSTcomma 
    \let \FONTfamilyparsenext \relax 
  \else
    \ifx \FONTfamilymatchuc \empty
      \let \FONTfamilyuc \FONTfamilyparsetestuc
      \let \FONTfamilyparsenext \FONTfamilyparse
      \ifx \FONTfamilyuc \CONSTmonospace \FONTfallbackresetmonospace
        \FONTfamily = \FONTmonospace \fi
      \ifx \FONTfamilyuc \CONSTsansserif \FONTfallbackresetsansserif
        \FONTfamily = \FONTsansserif \fi
      \ifx \FONTfamilyuc \CONSTserif \FONTfallbackresetserif
        \FONTfamily = \FONTserif \fi
      \ifx \FONTfamilyuc \CONSTCMR \FONTfallbackresetcmr
        \FONTfamily = {cmr}\fi
      \ifx \FONTfamilymatchuc \empty \FONTfamilymatchdo \fi   
      \ifx \FONTfamilyparsetest \empty 
        \let \FONTfamilyparsenext \relax \fi \fi \fi \FONTfamilyparsenext}
        
\def \FONTfamilyset {%
  \FONTfamily = \VALUE % Fixme: \FONTsizecheck
  \FONTfamilygiventrue \FONTchoose \FONTdo}

\let \FONTfamilyuc \empty
    
\new \ifFONTitalic

\net \FONTname 

  \let \FONTnametest \empty

  \def \FONTnametestget {%
    \uppercase {\edef \FONTnametest {\the \FONTname}}}
  
  \def \FONTnoneforcodepage #1{%
    \def \FONTnoneforcodepagefirst {#1}%
    \ifx \FONTnoneforcodepagefirst \empty \else
      \VERIFYerrornofontforCP {#1}% Fixme: move to error.tex, pre-expand
      \ifx \CODEPAGE \GMScodepage \else
        \message {! Using font for default \CONSTcodepage.}\fi \fi 
    \let \CODEPAGE \GMScodepage
    \CODEPAGEgetdefaultname
    \let \FONTfallback \FONTfallbackserif
    \let \FONTfallbackuc \FONTfallbackserifuc
    \let \FONTfamilymatchuc \FONTfallbackuc}

\def \FONTmodechange {%
  \ifFONTbold \FONTmodechangebold \else \FONTmodechangebase \fi
  \KERNINGdonefalse %%% Check this: time bandit?
  \FONTdo}
  
  \def \FONTmodechangebold {%    
    \ifFONTitalic \FONTname = \FONTbolditalic \else \FONTname = \FONTbold \fi}
    
  \def \FONTmodechangebase {%    
    \ifFONTitalic \FONTname = \FONTbaseitalic \else \FONTname = \FONTbase \fi}
        
\def \FONTmodestyle {%
  \VALUEsetlowercase \FONTmodestyletest
  \ifx \FONTmodestyletest \CONSTnormal \FONTitalicfalse \else 
    \ifx \FONTmodestyletest \CONSTitalic \FONTitalictrue \else
      \ifx \FONTmodestyletest \CONSToblique \FONTitalictrue \else
        \VERIFYerrorfontstyle \fi \fi \fi
  \FONTmodechange}
  
\def \FONTmodeweight {%
  \VALUEsetlowercase \FONTmodeweighttest
  \ifx \FONTmodeweighttest \CONSTnormal \FONTboldfalse \else
    \ifx \FONTmodeweighttest \CONSTbold \FONTboldtrue \else
      \VERIFYerrorfontweight \fi \fi
  \FONTmodechange}
  
\net \FONTmono

\net \FONTpageno

\def \FONTrescue {%
  \FONTcmtext \FONTname = {cmr10}%
  \FONTnametestget \VERIFYerrorfontfalse}    

% Unless font-size-adjust is set to "none", the font shall be scaled such that
% its x-height becomes half the given font-size value:
% fontxheightadjusted := 0.5 fontsize                                2
%                                    fontxheightadjusted     fontsize
% => fontsizeadjusted  =  fontsize * ------------------- = -------------
%                                        fontxheight       2 fontxheight
% Dimensions are represented by integer numbers (Knuth page 118).  In order to
% avoid register overflow, they must be divided by e. g. 1000 before they can
% be multiplied.
%        72
% 1mm = ---- pt = 2.8346 * 65536sp = 185771sp
%       25.4
% This should be done if font-family, font-size or line-height have been
% changed.

\new \ifFONTsizeadjust 

\def \FONTsizeadjust {%
  \FONTnametestget
  \ifx \FONTnametest \empty \FONTrescue \fi 
  \font \FONT = \FONTnametest \CONSTat \SIZE \FONT
  \FONTxheighttempo = \fontdimen 5 \FONT
    \divide \FONTxheighttempo by \CONSTnumbermedium
  \SIZEtempo = \SIZE % conversion to sp %%% Fixme: rename
    \divide \SIZEtempo by \CONSTnumbermedium
  \SIZEtempotwo = \SIZEtempo
    \multiply \SIZEtempo by \SIZEtempotwo
  \divide \SIZEtempo by \FONTxheighttempo
  \multiply \SIZEtempo by 500
  \SIZEcurrent = \SIZEtempo sp }
  
\def \FONTsizeadjustset {%
  \VALUElowercaseget
  \ifx \VALUElowercase \CONSTnone \FONTsizeadjustfalse \fi}
  
\def \SIZEsmaller {%
  \SIZEbasesmaller \COLORizeforeground \FONTdo}  
          
\def \FONTswitchspan {%
  \KERNINGdonefalse \COLORizeforeground \FONTchoose \FONTmodechange \FONTdo}

\def \FONTswitchsubbegin {%
  \hbox \bgroup \lower 0.5ex
    \hbox \bgroup \SIZEsmaller}   
\def \FONTswitchsubend {%
  \egroup \egroup}

\def \FONTswitchsupbegin {%
  \hbox \bgroup \raise 0.5ex
    \hbox \bgroup \SIZEsmaller}   
\let \FONTswitchsupend \FONTswitchsubend 
  
\def \FONTunderline #1{%
  \ifFONTdecoration
    \hbox {\raise 0ex \tlap {%
      \vskip 2.5ex \hrule height 0.1ex \vss \hbox {#1}}}%
  \else #1\fi}
    
\nec \FONTxheighttempo
  
% GAP: =======================================================================

\net \GAP

\ldef \GAPcheck #1{#1}% discard leading whitespace

\def \GAPcheckfilled {%
  \ifx \GAPcontent \empty \global \GAPemptytrue  %%%
    \global \GAPfilledfalse
  \else \global \GAPemptyfalse  %%%
    \global \GAPfilledtrue \fi
  \ifx \GAPcontent \CONSTspace \global \GAPfilledfalse \fi}

\def \GAPchecklog {%
  \ifGAPlog \message {\GAPcontent}\fi}

\def \GAPcheckobey {%
  \ifGAPobey \OBEYnormalspacesandlines \fi}      

\def \GAPcheckitvoid {%
  \let \GAPcheck \empty}

\def \GAPcheckitopener {\GAPcheck}% Check this

\def \GAPclear {%
  \global \GAP = {}}
  
\def \GAPdisplay {%
  \VALUElowercaseget  
  \ifx \VALUElowercase \CONSTnone
    \GAPclear \GAPwriteomit \LINKunrenderedtrue 
  \else \GAPwritereset 
    \ifx \VALUElowercase \CONSTblock \ELEMENTblocktrue \fi %%%  
  \fi}
  
\def \GAPdisplayp {%
  \VALUElowercaseget \GAPclear
  \ifx \VALUElowercase \CONSTnone \GAPwriteomit \LINEupskip
    \ifnum \NOpar = 1 \NOparresetglobal \fi
  \else \GAPwritereset \fi}

\new \ifGAPempty % GAP is "empty", if it does not even contain one space
\new \ifGAPfilled % GAP is "not filled", if it only contains one space

\bgroup \CATactivelessthan  
  \gldef \GAPget #1<{%
    \xdef \GAPcontent {#1}%
    \GAPcheckfilled 
    \ifGAPfilled \ifx \GAPcontent \CONSTendcomment
      \tagCOMMENTfalse \tagCOMMENTbegunfalse \fi \fi
    \tagCOMMENTend \GAPcontent
    \GAPchecklog \GAPcheckobey \GAPset {#1}%
    \CATotherlessthan \TAGget}
\egroup

\new \ifGAPlog
\new \ifGAPnostruts
\new \ifGAPobey
\new \ifGAPparsedstyle

\net \GAPsegment

\ldef \GAPsegmentappend #1{%
  \global \GAPsegment = \expandafter {\the \GAPsegment #1}}
        
\ldef \GAPset #1{%
  \global \GAP = {#1}}  
  
\def \GAPsetstrut {% set strut box (compare Knuth, page 353)
  \setbox \strutbox = \hbox {% Fixme: evaluate font dimensions for baseline
    \vrule height 0.7083\LINEheight depth 0.2917\LINEheight width 0pt }}
%%% \vrule height 0.7\LINEheight depth 0.3\LINEheight width 0.1pt }} %%%

\new \ifGAPspacelast
\new \ifGAPspacenow
\new \ifGAPstrike

\edef \BLOCKtest {\CONSTampersand nbsp;} %% Fixme: rename; handle <p> </p> too
\new \ifBLOCKempty %%%
\new \ifBLOCKspacer %%%
               
\def \GAPwrite {% write content between tags
  \let \next \relax
  \ifLINKunrendered \else 
    \edef \GAPtest {\the \GAP}% 
    \GAPfilledfalse
    \ifx \GAPtest \empty \else 
      \ifBLOCKempty % Fixme: outsource
        \ifx \GAPtest \BLOCKtest
          \GAPfilledfalse 
          \global \BLOCKspacertrue 
        \else \GAPfilledtrue \fi
        \BLOCKemptyfalse %%%
      \else \GAPfilledtrue \fi 
      \let \next \GAPwriteword %%%
    \fi \fi \next}
        
\let \GAPwritebackup \GAPwrite
        
  \new \ifGAPwritedonospace %%%
    
  \def \GAPwritedostrut {% 
    \ifhmode \ifGAPnostruts \else \strut \fi \fi}    
      
  \def \GAPwriteword {% 2007/03/23 - 2007/05/09
    \bgroup 
      \GAPwritedostrut \REFERENCEget
      \ifGAPspacenow \global \GAPspacelasttrue 
      \else \global \GAPspacelastfalse \fi
      \ifx \GAPtest \CONSTspace \global \GAPspacenowtrue 
      \else \global \GAPspacenowfalse \fi   
      \ifGAPspacelast \ifGAPspacenow \GAPclear \else 
        \expandafter \GAPwritewordgulp \the \GAP \empty \relax \fi \fi
      \edef \GAPwritewordtest {\the \GAP \CONSTspace }%  
      \expandafter \GAPwritewordget \GAPwritewordtest \relaxx   
      \GAPwritedostrut
    \egroup \GAPclear} 
  
    \def \GAPwritewordget #1 #2\relaxx {% individual stop mark required
      \edef \GAPwritewordgetfirst {#1}%
      \edef \GAPwritewordgetsecond {#2}%
      \let \GAPwritewordgetnext \relax
      \ifx \GAPwritewordgetsecond \empty 
        \GAPwritewordgetout {#1}\empty
        \global \GAPwritedonospacefalse
      \else \GAPwritewordgetbegin \fi
      \ifx \GAPwritewordgetfirst \empty 
        \ifx \GAPwritewordgetsecond \empty     
          \let \GAPwritewordgetnext \relax    
        \else \ifx \GAPwritewordgetsecond \CONSTspace
          \let \GAPwritewordgetnext \relax \fi \fi \fi
      \GAPwritewordgetnext}    
      
      \def \GAPwritewordgetbegin {%
        \ifGAPwritedonospace 
          \ifx \GAPtest \CONSTspace \else 
            \GAPwritewordgetout \GAPwritewordgetfirst \CONSTspace \fi 
          \global \GAPwritedonospacefalse           
        \else \GAPwritewordgetout \GAPwritewordgetfirst \CONSTspace \fi
        \ifx \GAPwritewordgetsecond \CONSTspace \global \GAPspacenowtrue 
        \else \global \GAPspacenowfalse
          \let \GAPwritewordgetnext \GAPwritewordgetmore \fi}
      
      \def \GAPwritewordgetmore {%
        \expandafter \GAPwritewordget \GAPwritewordgetsecond \relaxx} 
        
      \def \GAPwritewordgetout #1#2{% Fixme: nest strike and bgcolor
        \ifCOLORbgspan \GAPwritewordgetoutbgcolor {#1}{#2}\else 
          \ifGAPstrike \GAPwritewordgetoutstrike {#1}{#2}\else #1#2\fi \fi}
    
        \def \GAPwritewordgetoutbgcolor #1#2{% 
          \ifOPENpre #1#2\else \ifOPENdiv #1#2\else
            \hbox {\strut
              \COLORize \COLORbackground
              \raise 1.45ex \vbox to 0pt {\vskip -0.1ex \hrule height 2ex \vss 
                \hbox {\COLORize \COLORforeground \strut #1}\vss}}#2\fi \fi}

        \def \GAPwritewordgetoutstrike #1#2{% 
          \ifFONTdecoration
            \hbox {\strut 
              \raise 0.4ex \blap {\vskip -0.25ex \hrule height 0.15ex \vss
                \hbox {\strut #1}}}#2\else #1#2\fi}                
            
    \def \GAPwritewordgulp #1#2\relax {%
      \global \GAP = {#1#2}}
                  
\def \GAPwriteorstrut {%
  \ifGAPfilled \GAPwrite \else \strut \fi}
  
\def \GAPwritereset {%
  \let \GAPwrite \GAPwritebackup}   

\def \GAPwriteomit {%
  \let \GAPwrite \relax}
  
% GLYPH: =====================================================================

% Reference: http://partners.adobe.com/asn/developer/type/glyphlist.txt

% Characters not listed in glyph lists (*.gly) are given unicode numbers as
% glyph names in encoding files (*.enc).

\let \GLYPH \empty 

\ldef \GLYPHadd #1.#2 {% add glyph name file to the GLYPH list
  \def \GLYPHaddfirst {#1}% 
  \ifx \GLYPHaddfirst \empty \else
    \edef \GLYPHadditem {[#1] }%
    \expandafter \DATAarrayone \GLYPHadditem \DATAarrayafter \GLYPH
  \fi}

\bgroup \CATcommenthashmark \CATparameterat 
  \gldef \GLYPHload @1{{% Glyph name list 
    \catcode `\# = \CATcomment
    \message {(@1.gly).}% 
    \openin 1 = @1.gly
      \loop
        \FILEcheckeof 1 \ifFILEnotended \read 1 to \GLYPHloadline
        \expandafter \GLYPHparseline \GLYPHloadline ; \relax
      \repeat
    \closein 1 }}
\egroup

\def \GLYPHnamesload {% read all glyph name files found on the GLYPH list
  \def \\ [##1] {%
    \def \GLYPHnamesloadfirst {##1}% 
    \ifx \GLYPHnamesloadfirst \empty \else 
      \GLYPHload \GLYPHnamesloadfirst \fi}%
  \GLYPH}

\bgroup \CATcommenthashmark \CATparameterat 
  \gldef \GLYPHparseline % define character names and codes
    @1;% Glyph name (upper- and lowercase letters, digits)
    @2 % Standard Unicode Value or CUS UV (4 uppercase hexadecimal digits)
    @3%
  \relax {%
    \edef \GLYPHparselinesecond {@2}%
    \ifx \GLYPHparselinesecond \CONSTpar \else
      \ifx \GLYPHparselinesecond \empty \else
        \UNICODEslotset {"@2}%
        \edef \myslot {\the \UNICODEslot slot}%
        \DEFsearch \myslot \ifDEF
          \UNICODEslotpointregset {"@2}%
          \UNICODEdata = \expandafter {\the \toks \UNICODEslotpointreg}%
          \edef \testdata {\the \UNICODEdata}%
          \ifx \testdata \empty \MESSAGEnoglyphdata \else
            \UNICODEdataset -;-;-;-;-;-;-;-;@1\relax
            \global \toks \UNICODEslotpointreg = 
              \expandafter {\the \UNICODEdata}%
          \fi \else \MESSAGEnoslot {@2}\fi \fi \fi} 
\egroup
   
% IMAGE: =====================================================================

\new \ifIMAGEabsent %%%

\let \IMAGEalt \empty  

\neb \IMAGEbox

\def \IMAGEcell {%
  \hskip -\TEXTindent \hbox {\vbox {%
    \BOXfillertop \IMAGErunput \BOXfillerbottom
    \vskip -0.2917\LINEheight}}}% factor see \GAPsetstrut

\ned \IMAGEheight

\def \IMAGEinit {%
  \let \IMAGEalign \empty
  \let \IMAGEalt \CONSTnone
  \let \FILEname \empty
  \let \FILEsource \empty
  \let \IMAGEvalign \empty
  \IMAGEheight = 0mm \IMAGEwidth = 0mm
  \IMAGEmarginbottom = 0mm \IMAGEmargintop = 0mm }

\nec \IMAGElines

\ned \IMAGEmarginbottom
\ned \IMAGEmarginleft
\ned \IMAGEmarginright
\ned \IMAGEmargintop

\nec \IMAGEnumber

\nec \IMAGEresolution

\def \IMAGErun {% 
  \global \IMAGEabsentfalse %%%
  \ifLINKunrendered \else
    \verifyWELLFORMtotalfileadvance \ifFILEtoomany \LINKunrenderedtrue \fi \fi
  \ifLINKunrendered \else
    \ifOPENfloatsuppress \let \IMAGErunfloat \IMAGErunput \fi
    \ifx \IMAGEalt \CONSTnone \VERIFYerrorempty \CONSTalt
      \let \IMAGEalt \empty \fi       
    \ifx \URLhref \empty \else \let \FILEsource \URLhref \fi %%%
    \ifx \FILEsource \empty \VERIFYerrorempty \CONSTsrc
      \ifx \IMAGEalt \empty \else 
        \if \IMAGEalt \relax \else [\IMAGEalt] \fi \fi 
    \else \FILEnameget 
      \FILEsearch \FILEname 
      \ifFILEexist \IMAGErundo
      \else \expandafter \FILEsearchimage \FILEname .jpg\relax
        \ifFILEexist \IMAGErundo \else \VERIFYerrorabsent \FILEname 
          \global \IMAGEabsenttrue %%%
          \ifx \IMAGEalt \empty \else
            \if \IMAGEalt \relax \else [\IMAGEalt] \fi \fi \fi \fi \fi
    \ifOPENtd \ifdim \IMAGEheight > \BOXheightswapped
      \global \BOXheightswapped = \IMAGEheight \fi \fi
      \NOparresetglobal \fi}

  \def \IMAGErundo {% 
    \IMAGEscale
    \ifx \IMAGEalign \CONSTbottom \let \IMAGEalign \empty \else
      \ifx \IMAGEalign \CONSTmiddle \let \IMAGEalign \empty
        \VERIFYerrorunsuppattprop {\CONSTalign \CONSTspace = "\CONSTmiddle"}%
        \else \ifx \IMAGEalign \CONSTtop \let \IMAGEalign \empty
          \VERIFYerrorunsuppattprop {\CONSTalign 
            \CONSTspace = "\CONSTtop"}\fi \fi \fi
    \ifx \IMAGEalign \empty 
      \ifnum \NOpar > 1 \ifOPENa \else
        \ifhmode \par \LINEupskip \fi
        \vskip 1ex \fi \fi
      \hskip -\parindent
      \ifOPENtd \IMAGEcell \else \IMAGErunput \fi
    \else
      \ifOPENtd \IMAGEcell \else % Fixme: doesn't float
        \ifOPENp 
          \IMAGErunfloat \else
          \ifOPENh \IMAGErunput \else 
            \ifOPENli \IMAGErunfloat \else 
              \IMAGErundocenter \fi \fi \fi \fi \fi}
                           
    \def \IMAGErundocenter {%
      \ifdim \BOXheight > \IMAGEheight
        \hbox to \BOXwidth {%
          \hss \vbox to \BOXheight {\vss \IMAGErunput \vss }\hss}%
      \else \hbox to \BOXwidth {\hss \vbox {\IMAGErunput }\hss }\fi}
      
  \def \IMAGErunfloat {% 
    \advance \IMAGEheight by \IMAGEmarginbottom
    \advance \IMAGEheight by \IMAGEmargintop  
    \FLOATpagebegin \IMAGEheight %%%
    \FLOATsizewidth \IMAGEwidth \FLOATsizeheight \IMAGEheight
    \advance \IMAGEheight by -\IMAGEmarginbottom
    \advance \IMAGEheight by -\IMAGEmargintop  
    \ifx \IMAGEalign \CONSTright \FLOATingbeginright \else
      \ifx \IMAGEalign \CONSTleft \FLOATingbeginother \else 
        \FLOATingbeginother \fi \fi
    \IMAGErunput \FLOATingend}
            
  \def \IMAGErunput {%
    \ifnum \IMAGEnumber > 0
      \ifvmode \IMAGErunputdo
      \else \vbox {\IMAGErunputdo}\fi
    \else \VERIFYerrorunloadable \fi}  
    
    \def \IMAGErunputdo {%
      \vskip \IMAGEmargintop 
      \pdfrefximage \IMAGEnumber 
      \vskip \IMAGEmarginbottom}    
    \ifx \pdfximage \undefined \let \IMAGErunputdo \relax \fi 

\def \IMAGEscale {%
  \ifdim \IMAGEwidth = 0mm
    \ifdim \IMAGEheight = 0mm
      \IMAGEscaledo \IMAGEscalegetzero 
    \else % do not scale if just image height is given:
      \IMAGEscaleput \IMAGEheight \empty \fi 
  \else \IMAGEscaledo \IMAGEscalegetwidth \fi}
  
  \def \IMAGEscaledo #1{%
    \IMAGEtest \empty #1\IMAGEscaleput \IMAGEheight \IMAGEwidth}
    
  \def \IMAGEscaleexec {%
    \setbox \IMAGEbox = \hbox {\pdfrefximage \pdflastximage}%
    \IMAGEwidth = \wd \IMAGEbox 
    \IMAGEheight = \ht \IMAGEbox}
    \ifx \pdfximage \undefined \let \IMAGEscaleexec \relax \fi 
      
  \def \IMAGEscalegetwidth {%
    \ifdim \IMAGEheight = 0mm 
      \pdfximage width \IMAGEwidth {\FILEname}%
    \else \pdfximage height \IMAGEheight width \IMAGEwidth {\FILEname}\fi 
    \IMAGEscaleexec \IMAGEscalegetwidthfit}    
    \ifx \pdfximage \undefined \let \IMAGEscalegetwidth \relax \fi 
  
    % Make \IMAGEheight a multiple of \LINEheight (+1ex): 
    \def \IMAGEscalegetwidthfit {%
      \ifOPENtd \else \ifOPENth \else 
        \ifdim \LINEheight > 0mm
          \IMAGEscalegetwidthfitdo \fi \fi \fi}

      \def \IMAGEscalegetwidthfitdo {%
        \IMAGElines = -1
        \loop \ifdim \IMAGEheight > 0mm
          \advance \IMAGElines by 1
          \advance \IMAGEheight by -\LINEheight
        \repeat \IMAGEheight = \LINEheight
        \multiply \IMAGEheight by \IMAGElines
        \advance \IMAGEheight by 1ex }      
  
  \def \IMAGEscalegetzero {%
    \IMAGEsizedefault \pdfximage {\FILEname}\IMAGEscaleexec}
    \ifx \pdfximage \undefined \let \IMAGEscalegetzero \relax \fi 

  \def \IMAGEscaleput #1#2{%
    \edef \IMAGErunputheight {#1}%
    \edef \IMAGErunputwidth {#2}%
    \IMAGEtest \IMAGEscaleputnew \IMAGEscaleputold}

    \def \IMAGEscaleputnew {%
      \IMAGEnumber \expandafter = \csname \CONSTIMAGE \FILEname \endcsname
      \edef \test {\the \IMAGEnumber}}% dummy expand required  

    \def \IMAGEscaleputold {%
      \ifx \IMAGErunputheight \empty
        \IMAGEscaleputoldnoheight \else \IMAGEscaleputoldheight \fi
      % Fixme: Must images used multiple times have the same size?
      \xDef {\CONSTIMAGE \FILEname} {\the \pdflastximage}%
      \IMAGEnumber = \pdflastximage}
    \ifx \pdfximage \undefined \let \IMAGEscaleputold \relax \fi  

      \def \IMAGEscaleputoldheight {%         
       \ifx \IMAGErunputwidth \empty 
         \pdfximage height \IMAGErunputheight {\FILEname}%
       \else \pdfximage height \IMAGErunputheight
          width \IMAGErunputwidth {\FILEname}\fi}

      \def \IMAGEscaleputoldnoheight {%
        \ifx \IMAGErunputwidth \empty \pdfximage {\FILEname}%
        \else \pdfximage width \IMAGErunputwidth {\FILEname}\fi}  
        
\def \IMAGEsizedefault {%
  \IMAGEsizedefaultresolution} 

  \def \IMAGEsizedefaultresolution {% by default open image at 72dpi:
    \pdfimageresolution = \IMAGEresolution}
    \ifx \pdfximage \undefined \let \IMAGEsizedefaultresolution \relax \fi 
    
\def \IMAGEtest #1#2{%
  \DEFsearch {\CONSTIMAGE \FILEname }\ifDEF #1\else #2\fi}

\ned \IMAGEwidth

% KERNING: ===================================================================

% Fixme: Whole paragraph in italics should be kerned

\nec \KERNING

\new \ifKERNING 

\def \KERNINGcheck {\pdfprotrudechars = \KERNING}
  \ifx \pdfprotrudechars \undefined \let \KERNINGcheck \relax \fi    

\def \KERNINGcheckback {\pdfprotrudechars = 0 }
  \ifx \pdfprotrudechars \undefined \let \KERNINGcheckback \relax \fi    

\nec \KERNINGcode

\def \KERNINGdo {% load the kerning table that corresponds to the current font
  \def \\ [##1] [##2] [##3] {%
    \lpcode \FONT "##1 = ##2 \rpcode \FONT "##1 = ##3 }%
  \ifFONTitalic \let \KERNINGdovariant \CONSTitalic
    \else \let \KERNINGdovariant \CONSTroman \fi      
  \DEFsearch {\CONSTkrn \CODEPAGE -\FONTfamilyuc -\KERNINGdovariant}\ifDEF
    \csname \CONSTkrn \CODEPAGE -\FONTfamilyuc -\KERNINGdovariant \endcsname
    \KERNINGdonetrue \fi}
          
\new \ifKERNINGdone

\def \KERNINGget {{% read kerning tables that can be found on the list
  \def \\ [##1] {%
    \def \first {##1}%
    \uppercase {\edef \First {##1}}%
    \ifx \first \empty \else
      \FONTfamily = {##1}% can be corrected by font-family entry in *.krn file
      \KERNINGgetload \fi}%
    \KERNINGtables}}

  % Read kerning table that corresponds to the current font family:
  \def \KERNINGgetload {{%
    \ifx \lpcode \undefined \else
      \let \KERNINGgetloadprobe \empty 
      \message {(\the \FONTfamily.krn)}%
      \openin 2 = \the \FONTfamily.krn 
      \loop \KERNINGgetloaddo \repeat 
      \closein 2 \fi}}

    \def \KERNINGgetloaddo {%
      \FILEcheckeof 2
      \ifFILEnotended 
         \read 2 to \KERNINGgetloadline
         \expandafter \KERNINGgetloaddoparse \KERNINGgetloadline ;;;;;\relax}

      \ldef \KERNINGgetloaddoparse % read a line from kerning table
        #1;% ord. number (hex.)
        #2;% rom. lpcode (or font-family or codepage)
        #3;% rom. rpcode
        #4;% itl. lpcode
        #5;% itl. rpcode
        #6\relax {% efcode
        \def \KERNINGgetloaddoparseone {#1}%
        \uppercase {\def \KERNINGgetloaddoparsetwo {#2}}%
        \ifx \KERNINGgetloaddoparseone \CONSTpar \else 
          \ifx \KERNINGgetloaddoparseone \empty \else
            \ifx \KERNINGgetloaddoparseone \CONSTfontfamily
             \KERNINGgetloaddoparsefamily 
            \else \KERNINGgetloaddoparsevariant {#1}{#2}{#3}\CONSTroman
              \KERNINGgetloaddoparsevariant {#1}{#4}{#5}\CONSTitalic 
        \fi \fi \fi}

        \def \KERNINGgetloaddoparsefamily {%
          % Correct font family, which had been taken from kerning file name:
          \FONTfamily = \expandafter {\KERNINGgetloaddoparsetwo}%
          \message {- \the \FONTfamily.}%
          % Define kerning table marker: 
          \uppercase {\xDef \CONSTkrn \CODEPAGE -\the \FONTfamily - {%
            \message {\CONSTkerning}}}}     

        % add kerning data of roman or italic font variant:
        \def \KERNINGgetloaddoparsevariant 
          #1% ord. number % to kerning factors array
          #2% lpcode
          #3% rpcode
          #4{% variant
          \KERNINGcode = #2
          \advance \KERNINGcode by #3
          \ifnum \KERNINGcode > 0 
            \DATAarraythree [#1] [#2] [#3] 
              \DATAarrayafter \KERNINGgetloadprobe
            \uppercase {\xDef \CONSTkrn \CODEPAGE -\the \FONTfamily -#4 {%
              \the \DATAarray \the \DATAarrayentry}}\fi}
          
\bgroup \CATothertilde
\gldef \KERNINGparseline #1(#2.#3)#4\relax {% add data to kerning table list
  \def \KERNINGPARSElinesecond {#2}% 
  \ifx \KERNINGPARSElinesecond \empty \else
    \lowercase {\edef \KERNINGPARSElineitem {[#2] }}% 
    \expandafter \DATAarrayone \KERNINGPARSElineitem 
      \DATAarrayafter \KERNINGtables \fi}
\egroup  

\def \KERNINGshow {% show kerning table marker defined for current font family
  \csname \CONSTkrn \CODEPAGE -\FONTfamilyuc -\endcsname}%

\let \KERNINGtables \empty

% LANGUAGE: ==================================================================

\def \LANGUAGEabbreviation {en-US}

\def \LANGUAGEadd #1.#2 {% add pattern files, delimited by whitespace,
  \def \LANGUAGEaddsecond {#1}% to HYPHtables list
  \ifx \LANGUAGEaddsecond \empty \else 
    \LANGUAGEaddparse #1--\relax
    \advance \language by 1
    \lowercase {\edef \LANGUAGEadditem {%
      [\the \language] % 1. language number
      [\LANGUAGEName] % 2. language name
      [\LANGUAGEExt] }} % 3. language extension
    \expandafter \DATAarraythree \LANGUAGEadditem
      \DATAarrayafter \HYPHENtables \fi}
      
  \ldef \LANGUAGEaddparse #1-#2-#3\relax {% get language name abbreviation(s)
    \def \LANGUAGEName {#1}% from hyphenation pattern file name
    \def \LANGUAGEExt {#2}}   

\def \LANGUAGEchangedetect #1{%
  \xdef \LANGUAGEold {\LANGUAGEabbreviation}#1%
  \xdef \LANGUAGEnew {\LANGUAGEabbreviation}}

\let \LANGUAGEext \empty

\def \LANGUAGEgerman {%
  \ifx \LANGUAGEabbreviation \CONSTde \LANGUAGEgermando \fi}

  \def \LANGUAGEgermando {% required for traditional German hyphenation:
    \ifx \GAPcontent \CONSTck \LANGUAGEgermandospecial \empty {k-}k{ck}\fi
    \ifx \GAPcontent \CONSTff \LANGUAGEgermandospecial {ff}-f\empty \fi
    \ifx \GAPcontent \CONSTlll \LANGUAGEgermandospecial {ll}-l\empty \fi
    \ifx \GAPcontent \CONSTmm \LANGUAGEgermandospecial {mm}-m\empty \fi
    \ifx \GAPcontent \CONSTnn \LANGUAGEgermandospecial {nn}-n\empty \fi
    \ifx \GAPcontent \CONSTpp \LANGUAGEgermandospecial {pp}-p\empty \fi
    \ifx \GAPcontent \CONSTrr \LANGUAGEgermandospecial {rr}-r\empty \fi
    \ifx \GAPcontent \CONSTtt \LANGUAGEgermandospecial {tt}-t\empty \fi}
    
    \def \LANGUAGEgermandospecial #1#2#3#4{% see Knuth, pages 95, 96, 314
      \global \GAP = {#1\discretionary {#2}{#3}{#4}}}

\def \LANGUAGEloadpatterns {{%
  \language = -1
  \def \\ [##1] [##2] [##3] {% language number, name, and extension
    \def \LANGUAGEloadpatternsthird {##3}% 
    \language = ##1%
    \ifx \LANGUAGEloadpatternsthird \empty \input ##2.tex 
    \else \input ##2-##3.tex \fi}%
  \HYPHENtables}}

\let \LANGUAGEname \empty

\def \LANGUAGEset {%
  \expandafter \LANGUAGEsetparse \LANGUAGEabbreviation \relax %%%
  \def \\ [##1] [##2] [##3] {% Fixme: replace list with direct call
    \def \LANGUAGEsetsecond {##2}\def \LANGUAGEsetsecondthird {##2-##3}%
    \ifx \LANGUAGElc \LANGUAGEsetsecondthird \language = ##1 \else 
      \ifx \LANGUAGElc \LANGUAGEsetsecond \language = ##1 \fi \fi}%
  \HYPHENtables}
  
  \def \LANGUAGEsetparse #1\relax {%
    \lowercase {\edef \LANGUAGElc {#1}}}
    
% LINK: ======================================================================

\def \LINKexec {%
  \ifx \LINKrel \CONSTnext 
    \ifOPENobject \else
      \glet \CHAINhref \URLhref \fi
    \MESSAGElinknext
  \else \ifx \LINKrel \CONSTstylesheet   
    \ifx \LINKtype \CONSTtextcss \SHEETstyleclear \SHEETload \else
      \ifx \LINKtype \empty 
        \VERIFYerrornostylesheettype \SHEETstyleclear \SHEETload
  \fi \fi \fi \fi \SHEETnext}

\let \LINKid \empty  

\def \LINKinit {%
  \let \CHAINhref \empty 
  \glet \URLhref \empty
  \let \LINKmedia \empty
  \let \LINKrel \empty 
  \let \LINKtype \empty 
  \let \SHEETnext \relax}
  
\let \LINKname \empty
  
\new \ifLINKunlinked
\new \ifLINKunrendered      
  
% LIST: ======================================================================

\def \LISTleftmarginset {%  
  \advance \leftskip by 2\LINEheight % default indent is 2\LINEheight -1ex
  \advance \leftskip by -1ex }

\def \LISTleftmarginsetdt {% 
  \advance \leftskip by \LINEheight 
  \advance \leftskip by -0.5ex}

\def \LISTmark {%
  \ifLINKunrendered \else
    \ifOPENul \LISTmarkul \else \ifOPENol \LISTmarkol
      \else \VERIFYerrormissingulol \fi \fi 
    \NOpar = 0 \COLORizeforeground \fi}
    
  \def \LISTmarkol {%
    \hskip -\LINEheight \hskip 1ex
    \llap {\the \NOli}\rlap .%
    \hskip \LINEheight \hskip -1ex }
    
  \def \LISTmarkul {%
    \hskip -\LINEheight
   {\COLORize \COLORlistdot
    \vrule height 1ex depth 0mm width 1ex }%
    \hskip \LINEheight \hskip -1ex }

\def \LISTnoddlastsetglobal {%
  \global \NOddlast = \verifyWELLFORMtotalelements}

\def \LISTnolastsetglobal {%
  \global \NOlilast = \verifyWELLFORMtotalelements}  

\def \LISTnoadvance {%
  \advance \NOli by 1 }

\def \LISTnostart {%
  \NOli = 1 } 

\def \LISTpenalty {%
  \penalty -500 }
  
% MAP: =======================================================================
  
% Create: \Def ALIAS-<PostScript typeface name> {<TeX typeface file name>}
\def \MAPadd #1 (#2){%
  \edef \MAPaddfirst {#1}\edef \MAPaddsecond {#2}%
  \uppercase {\edef \MAPaddseconduc {#2}}%
  \ifx \MAPaddfirst \empty \VERIFYerrornofamilydefined {#2}\else
    \ifx \MAPaddsecond \empty \else 
      \Def {\CONSTalias \MAPaddseconduc} {#1}\fi \fi}   

% Create: \Def ALIAS-<PostScript font-family name> {<HTML font-family name>}
\def \MAPaddalias #1 (#2){%
  \Def \CONSTalias #2 {#1}}

% Create: \Def ALIAS-<Font-specific encoding> {<official encoding>}
\def \MAPaddencoding #1 (#2){%
  \uppercase {\Def \CONSTencoding #1 {#2}}}

\def \MAPaddfamily #1 (#2, #3, #4, #5){%
  \MAPadd #1 (#2)\MAPadd #1-Italic (#3)%
  \MAPadd #1-Bold (#4)\MAPadd #1-BoldItalic (#5)}

\def \MAPaddfamilystd #1 (#2){%
  \MAPadd #1 (#2)\MAPadd #1-Italic (#2i)%
  \MAPadd #1-Bold (#2bd)\MAPadd #1-BoldItalic (#2bi)}

\def \MAPaddfamilyuni #1 (#2 #3){%
  \MAPadd #1 (#2#3)\MAPadd #1-Italic (#2i#3)%
  \MAPadd #1-Bold (#2bd#3)\MAPadd #1-BoldItalic (#2bi#3)}

\def \MAPaddmates #1 (#2, #3){%
  \MAPadd #1 (#2)\MAPadd #1-Bold (#3)}

\def \MAPaddpair #1 (#2, #3){%
  \MAPadd #1 (#2)\MAPadd #1-Italic (#3)}

% Create: \Def SPECIFIC-<HTML font-family name> 
\def \MAPaddspecific #1 {%
  \uppercase {\Def {\CONSTspecific #1} {}}} 
           
% Append new family to PostScript names list:
\def \MAPfamilyappend #1\relax {% 
  \ifx \POSTfamilies \empty \DATAarrayone [#1] \DATAarrayafter \POSTfamilies 
  \else \edef \MAPfamilyappendfirst {#1}%
    \let \MAPfamilyappendmatch \empty
    \def \\ [##1] {\edef \MAPfamilyappendtest {##1}%
      \ifx \MAPfamilyappendfirst \MAPfamilyappendtest 
        \let \MAPfamilyappendmatch \relax \fi}%
    \POSTfamilies
    \ifx \MAPfamilyappendmatch \empty 
      \DATAarrayone [#1] \DATAarrayafter \POSTfamilies \fi \fi
  \uppercase {\xdef \MAPisfamily {#1}}}
    
\uppercase {\def \MAPfamilyparse #1-#2STOP{%
  \DEFsearch {ALIAS-#1}\ifDEF
    \edef \MAPfamilyalias {\csname ALIAS-#1\endcsname}%
    \expandafter \MAPfamilyappend \MAPfamilyalias \relax \fi
  \MAPfamilyappend #1\relax}}
    
\def \MAPfamilyshow {%
  \def \\ [##1] {\immediate \backupwrite 4{##1}}%
  \immediate \openout 4 font.lst
  \POSTfamilies \immediate \closeout 4
  \immediate \backupwrite 18{sort < font.lst > sortfont.lst}%
  \def \MAPfamilyshowtest {WIN32}%
  \ifx \OS \MAPfamilyshowtest \openin 5 = font.lst 
  \else \openin 5 = sortfont.lst \fi
    \loop \FILEcheckeof 5 \ifFILEnotended \read 5 to \MAPfamilyshowline
      \edef \MAPfamilyshowline {\MAPfamilyshowline \CONSTspace}%
      \expandafter \MAPfamilyshowdo \MAPfamilyshowline
    \repeat \closein 5 }

  \ldef \MAPfamilyshowdo #1#2 {%
    \def \MAPfamilyshowdosecond {#2}%
    \ifx \MAPfamilyshowdosecond \empty \else \message {#1#2.}\fi}    
  
\def \MAPload {% evaluate font.map:
  \openin 1 = font.map
  \loop \FILEcheckeof 1
    \ifFILEnotended \read 1 to \MAPloadline 
    \expandafter \MAPloadparse \MAPloadline GMS GMS <nix.enc-STOP
  \repeat \closein 1
  \edef \MAPisbold {0}%
  \edef \MAPisitalic {0}}  
  
  \ldef \MAPloadparse #1#2 #3 #4<#5.enc#6STOP{% get font face name 
    \uppercase {\def \MAPloadparseseconduc {#2}}% Font file
    \def \MAPloadparsethird {#3}% PostScript font name
    \uppercase {\def \MAPloadparsefifth {#5}}% Encoding file base name 
    \ifx \MAPloadparsethird \CONSTgms \else
      % Get font style:
      \edef \MAPisfamily {unknown}%
      \edef \MAPisbold {0}%
      \edef \MAPisitalic {0}%
      \DEFsearch {\CONSTalias \MAPloadparseseconduc}\ifDEF 
        \edef \MAPloadparsethird {%
          \csname \CONSTalias \MAPloadparseseconduc \endcsname }\fi
      \expandafter \MAPfamilyparse \MAPloadparsethird-GMS-STOP%
      \expandafter \MAPloadparsebold \MAPloadparsethird Bold-GMS-STOP%
      \expandafter \MAPloadparsedemi \MAPloadparsethird Demi-GMS-STOP%
    \expandafter \MAPloadparseitalic \MAPloadparsethird Ital-GMS-STOP%
    \expandafter \MAPloadparseoblique \MAPloadparsethird Obl-GMS-STOP%
    \expandafter \MAPloadparseblack \MAPloadparsethird Black-GMS-STOP%
      % Define fonts:
      % Access fonts with specific encoding via equivalent encoding:
      \uppercase {\def \MAPloadparseuencoding {#5}}%
      \DEFsearch {\CONSTencoding \MAPloadparseuencoding}\ifDEF 
        \edef \MAPloadparsefifth {%
          \csname \CONSTencoding \MAPloadparseuencoding \endcsname}\fi
      \xDef {FONT-\MAPloadparsefifth
        -\MAPisfamily-\MAPisbold-\MAPisitalic} {#2}%
      % Handle fonts with specific encodings
      % as if they were \CODEPAGE-encoded:
      \uppercase {\def \FONTfamilyuc {#3}}%
      \DEFsearch {\CONSTspecific \FONTfamilyuc}\ifDEF 
        \xDef {FONT-\CODEPAGE-\MAPisfamily-\MAPisbold-\MAPisitalic} {#2}%
    \fi \fi}

    \def \MAPloadparseblack #1Black#2STOP{% prevents e.g. "Arial" fonts 
      \def \Blacksecond {#2}% from being covered by "Arial-Black"
      \ifx \Blacksecond \CONSThyphgmshyph \else 
        \xdef \MAPisfamily {\MAPisfamily BLACK}\fi}
        % Otherwise this definition is needed to correct Arial-Black (ariblk):
        % \xDef {FONT-\GMScodepage-ARIAL-0-0} {arial}% 

    \def \MAPloadparsebold #1Bold#2STOP{%
      \def \MAPloadparseboldsecond {#2}%
      \ifx \MAPloadparseboldsecond \CONSThyphgmshyph 
      \else \edef \MAPisbold {1}\fi}

    \def \MAPloadparsedemi #1Demi#2STOP{%
      \def \MAPloadparsedemisecond {#2}%
      \ifx \MAPloadparsedemisecond \CONSThyphgmshyph 
      \else \edef \MAPisbold {1}\fi}
  
    \def \MAPloadparseitalic #1Ital#2STOP{%
      \def \MAPloadparseitalsecond {#2}%
      \ifx \MAPloadparseitalsecond \CONSThyphgmshyph 
      \else \edef \MAPisitalic {1}\fi}

    \def \MAPloadparseoblique #1Obl#2STOP{%
      \def \MAPloadparseoblsecond {#2}%
      \ifx \MAPloadparseoblsecond \CONSThyphgmshyph 
      \else \edef \MAPisitalic {1}\fi}
            
% MARGIN: ====================================================================

\ned \MARGIN 
\ned \MARGINbottom
\ned \MARGINleft
\ned \MARGINpageno % check this
\ned \MARGINright
\ned \MARGINtop
 
\new \ifMARGINbottomgiven 
  
\new \ifMARGINgiven

% Fixme: same for 'background', 'padding', 'border' properties:  
\def \MARGINset {%
  \edef \test {\the \VALUE \CONSTspace}%
  \expandafter \MARGINsetdo \test - - - - -\relax}
  
  \def \MARGINsetdo #1 #2 #3 #4 #5\relax {%
    \def \first {#1}\def \second {#2}%
    \def \third {#3}\def \fourth {#4}%
    \ifx \first \CONSThyphen \else
      \VALUE = {#1}\VALUEdimenset \MARGINtop \vsize
      \MARGINright = \MARGINtop \MARGINleft = \MARGINtop
      \MARGINbottom = \MARGINtop \MARGIN = \MARGINtop
      \ifx \second \CONSThyphen \else
        \VALUE = {#1}\VALUEdimenset \MARGINtop \vsize
        \VALUE = {#2}\VALUEdimenset \MARGINright \hsize
        \MARGINbottom = \MARGINtop
        \MARGINleft = \MARGINright
        \ifx \third \CONSThyphen \else
          \ifx \fourth \CONSThyphen \else
            \VALUE = {#1}\VALUEdimenset \MARGINtop \vsize
            \VALUE = {#2}\VALUEdimenset \MARGINright \hsize
            \VALUE = {#3}\VALUEdimenset \MARGINbottom \vsize
            \VALUE = {#4}\VALUEdimenset \MARGINleft \hsize
    \fi \fi \fi \fi \MARGINgiventrue}
  
\new \ifMARGINtopgiven

% MESSAGE: ===================================================================

\def \MESSAGEbase {\message {<\CONSTbase}}
\def \MESSAGEbaseend {\Message {/\CONSTbase}}

\def \MESSAGEbasefont {\message {<\CONSTbasefont}}

\def \MESSAGEbr {\message {<br}}

\def \MESSAGEcol {%
  \ifOPENcolgroup \else \ifnum \NOcol = 1 \noecho \fi \fi
  \message {<col \the \NOcol}}

\def \MESSAGEcolspan {\message {\SPANcol}}

\def \MESSAGEcodepageerror #1{\message {! Cannot add codepage #1.}}
\def \MESSAGEcodepagelanguage {%
  \ifx \CODEPAGEhtml \undefined \else \message {\CODEPAGEhtml }\fi
  \message {\LANGUAGEabbreviation}}

\def \MESSAGEdefaultfont {%
  \message {Using default font \FONTfallbackserifthe}}

\def \MESSAGEdot{\message {.}} 

\def \MESSAGEendemptytag {\message {/>}} 

\ldef \MESSAGEentityname #1#2 {% display sorted list of entity names
  \def \MESSAGEentitynamesecond {#2}%
  \ifx \MESSAGEentitynamesecond \empty \else
    \message {\CONSTampersand#1#2;}\fi}
    
\def \MESSAGEfalsified {\message {falsified}}

\def \MESSAGEfontfamily {\message {\FONTfamilyuc}}

\def \MESSAGEformbegin {\message {<\CONSTform>}}   
\def \MESSAGEformend {\message {</\CONSTform>}}

\def \MESSAGEgt {\message {>}}

\def \MESSAGEhresethno #1{%
  \ifnum \count #1 > 0 \edef \test {\test .\the \count #1}%
  \else \edef \extra {--\extra}\fi}

\def \MESSAGEh {% Reset lower order heading counters:
  \loop \ifnum \NOh < 6
    \advance \NOh by 1 \global \count \NOh = 0 \repeat
  \edef \test {\the \count 1}% Show heading number:
  \let \extra \empty
  \MESSAGEhresethno 2 \MESSAGEhresethno 3 \MESSAGEhresethno 4
  \MESSAGEhresethno 5 \MESSAGEhresethno 6
  \echo {-- \test \CONSTspace \extra \CONSTline
    \CONSTline \CONSTline \CONSTline \CONSTline ---}}

\def \MESSAGEhr {\message {<hr}}

\def \MESSAGEhtml {%
  \ifOPENobject \else \ifnum \NOinput = 1
    \GMSwelcome \GMSbeginabout
    \message {\CONSTlongline \CONSTline \CONSThalfline}\fi \fi}

\def \MESSAGEhyphen {\message {-}} 

\def \MESSAGEinclinebegin {%
  \echo {\CONSTinclinebegin \CONSTinclinebegin \CONSTinclinebegin
    \CONSTinclinebegin \CONSTinclinebegin \CONSTinclinebegin}}  
\def \MESSAGEinclinebeginobject {%
  \ifLINKunrendered \else \ifFILEhtml 
    \MESSAGEinclinebegin \message {<}\fi \fi}
\def \MESSAGEinclineend {%
  \echo {\CONSTinclineend  \CONSTinclineend \CONSTinclineend
    \CONSTinclineend \CONSTinclineend \CONSTinclineend}}
\def \MESSAGEinclineendobject {%
  \ifLINKunrendered \else \ifFILEhtml 
    \message {>}\MESSAGEinclineend \fi \fi}

\def \MESSAGEimg {\message {<img}}

\def \MESSAGEinput {\message {<input}}

\def \MESSAGEkerning {\ifKERNING \message {Kerning}\fi}

\def \MESSAGEli {\MESSAGEhyphen \message \expandafter {\the \NOli)}}

\def \MESSAGElink {\message {<link}}   
\def \MESSAGElinknext {\message {\CONSTnext: "\CHAINhref"}}

\def \MESSAGElt {\message {<}}

\def \MESSAGEmenubegin {\Message {\CONSTmenu}}   
\def \MESSAGEmenuend {\message {=}\Message {/\CONSTmenu}}  
\def \MESSAGEmenuisul {\message {=}\TAGul}

\def \MESSAGEmeta {\message {<meta}}

\bgroup \CATparameterat \CATotherhashmark \CATotherampersand
  \gdef \MESSAGEnochar % no character with that unicode number
    @1{% Standard Unicode Value, decimal 
      \DATAhexinput = @1\DATAhexoutput = {}\DATAhex
      \edef \DATAhexslot {\the \DATAhexoutput}%
      \message {! Unknown &#@1;/&#0x\DATAhexslot; character.}}
\egroup

\def \MESSAGEnoglyphdata {\message {! No data for U+\GLYPHparselinesecond.}}

\def \MESSAGEnone {\message {none}}

\def \MESSAGEnoslot #1{% Standard Unicode Value (slot base), decimal
  \xdef \missingslot {\the \UNICODEslot missing}%
  \DEFsearch \missingslot \ifDEF \else
    \DATAhexinput = \UNICODEslot \DATAhexoutput = {}\DATAhex
    \edef \DATAhexslot {\the \DATAhexoutput}%
    \message {! Undefined unicode row \DATAhexslot.}   
  \fi \xDef \the \UNICODEslot missing {#1}}%

\def \MESSAGEnotexcharacter #1{\message {! No TeX character #1.}}

\def \MESSAGEnotstrict {\message {! Not strict.}}
\def \MESSAGEnotstrictatt #1{\message {! Not strict: #1.}} 

\def \MESSAGEobjecthtml {\message {html}}
\def \MESSAGEobjectplain {\message {plain}}
\def \MESSAGEobjectTeX {\message {TeX}}

\def \MESSAGEplausible {\message {plausible}}

\def \MESSAGEproprietary {\message {! Proprietary.}}   

\def \MESSAGEtableline {{\noecho
  \advance \TABLEnesting by 1 
  \ifnum \TABLEnesting > 1 \message {\CONSTline \CONSTline }%
  \else \message {\CONSTLINE \CONSTLINE }\fi
  \loop \ifnum \TABLEnesting > 1 \message {|==}%
    \advance \TABLEnesting by -1 \repeat}} 

\def \MESSAGEtablenest {{%
  \message {\the \NOtable}%
  \advance \TABLEnesting by 1 
  \ifnum \TABLEnesting > 1
    \message {\CONSTlevel \CONSTspace \the \TABLEnesting}\fi}}

\def \MESSAGEtdcol {\message {\the \NOcol}} 
\def \MESSAGEtdhyphen {\ifnum \NOcol > 1 \MESSAGEhyphen \fi}
\def \MESSAGEtdlanguage {%
  \ifx \LANGUAGEold \LANGUAGEnew \else \message {\LANGUAGEnew }\fi}

\def \MESSAGEtrline {\noecho
  \ifnum \TABLEnesting > 1 \message {\CONSThalfline}%
  \else \message {\CONSThalfLINE }\fi}   
\def \MESSAGEtrnorow {\message {\the \NOrow}}

\def \MESSAGEunicodedefined #1{%
  \edef \MESSAGEunicodedefinedfirst {#1}%
  \DEFsearch \MESSAGEunicodedefinedfirst \ifDEF
    \edef \MESSAGEdefinedsecond {\csname #1\endcsname}%
    \message {\MESSAGEdefinedsecond}\fi}

\def \MESSAGEunrecognized {\message {unrecognized}}

\def \MESSAGEunverified {\message {unverified}}

\def \MESSAGEvalue {%
  \VALUEset \test
  \ifx \test \empty \else \message {"\test"}\fi}   

\def \MESSAGEverified {\message {verified}}

\def \MESSAGEwbr {\Message {\CONSTwbr}} 

% META: ======================================================================

\def \METAget {%
  \METAgetinfo
  \ifx \metahttpequiv \CONSTcontenttype
    \expandafter \METAgetinfocontenttype \metacontent \relax \fi}
  \ifx \pdfinfo \undefined \let \METAget \relax \fi 
    
  \def \METAgetinfo {%
    \ifx \metaname \CONSTauthor 
      \pdfinfo {/Author (\metacontent) }%
    \else 
      \edef \MetaContent {\metacontent _STOP_}%
      \edef \MetaContenttwo {\metacontent ---\relax}%
      \ifx \metaname \CONSTcreated 
        \expandafter \METAgetinfocreation \MetaContenttwo 
      \else \ifx \metaname \CONSTdate 
        \expandafter \METAgetinfomodification \MetaContenttwo 
      \else \ifx \metaname \CONSTdescription 
        \pdfinfo {/Subject (\metacontent) }%
      \else \ifx \metaname \CONSTkeywords 
        \pdfinfo {/Keywords (\metacontent) }%
      \fi \fi \fi \fi \fi}
    \ifx \pdfinfo \undefined \let \METAgetinfo \relax \fi 
      
    \ldef \METAgetinfocontenttype #1;#2charset#3=#4\relax {%
      \edef \first {#1}%
      \edef \second {#2}%
      \edef \third {#3}%
      \lowercase {\edef \fourth {#4}}%
      \ifx \second \CONSTspace \else \VERIFYerrormetaonespace \second \fi
      \ifx \third \empty \else \VERIFYerrormetanospace \third \fi
      \ifx \first \CONSTtexthtml
        \let \CODEPAGE \empty
        \let \CODEPAGEhtml \empty
        \CODEPAGEget #4\relax
        \ifx \CODEPAGE \empty \CODEPAGEgetiso #4\relax \fi
        \ifx \CODEPAGE \empty \DATAlengthget {#4}%
          \ifnum \DATAlength > 8 \CODEPAGEgetwindows #4\relax \fi \fi
        \DEFsearch {\CONSTCODEPAGE \fourth }\ifDEF
          \csname \CONSTCODEPAGE \fourth \endcsname \fi % get alias
        \ifx \CODEPAGE \empty 
          \xdef \CODEPAGE {#4}\xdef \CODEPAGEhtml {#4}\fi \fi}

    \def \METAgetinfocreation #1-#2-#3-#4\relax {%
      \edef \first {#1}\edef \second {#2}\edef \third {#3}%
      \ifx \first \empty \VERIFYerrormisformeddate \else 
        \ifx \second \empty \VERIFYerrormisformeddate \else 
          \ifx \third \empty \VERIFYerrormisformeddate \else
            \pdfinfo {/CreationDate (D:#1#2#3000000) }\fi \fi \fi}
        
    \def \METAgetinfomodification #1-#2-#3-#4\relax {%
      \edef \first {#1}\edef \second {#2}\edef \third {#3}%
      \ifx \first \empty \VERIFYerrormisformeddate \else 
        \ifx \second \empty \VERIFYerrormisformeddate \else 
          \ifx \third \empty \VERIFYerrormisformeddate \else
            \pdfinfo {/ModDate (D:#1#2#3000000) }\fi \fi \fi}
            
\def \METAgettitle {%
  \expandafter \METAgettitleparse \the \GAP \empty \relax} 
  \ldef \METAgettitleparse #1\relax {%
    \edef \mytitle {#1}%
    \pdfinfo {/Title (\mytitle) }}  
  \ifx \pdfinfo \undefined \let \METAgettitle \relax \fi 
    
\def \METAinit {%
  \let \metacontent \empty 
  \let \metaname \empty
  \let \metahttpequiv \empty}

\def \METApdfinfocreator {%
  \pdfinfo {/Creator (\GMSname \CONSTspace
    \GMSversion \CONSTspace - \GMSdomain) }}
  \ifx \pdfinfo \undefined \let \METApdfinfocreator \relax \fi

\def \METApdfcatalogmenu {%
  \pdfcatalog {/ViewerPreferences <<
    /HideToolbar false /HideMenubar false /HideWindowUI false
    /FitWindow true /CenterWindow true >> }}   
  \ifx \pdfinfo \undefined \let \METApdfcatalogmenu \relax \fi
  
% NEST: ======================================================================

\def \NESTabegin {%
  \ifOPENfont \OPENfontoutertrue \else \OPENfontouterfalse \fi
  \ELEMENTclosenest \CONSTa}   
\def \NESTaend {%
  \ifOPENfontouter \else \ELEMENTclosenest \CONSTfont \fi}

\def \NESTaddressbegin {%
  \ifOPENobject \else \ELEMENTclosenest \CONSTp \fi}

\def \NESTblockquotebegin {\ELEMENTclosenest \CONSTp}   
\def \NESTblockquoteend {\ELEMENTclosenest \CONSTp}

\def \NESTbodybegin {%
  \ELEMENTclosenest \CONSThead \ELEMENTclosenest \CONSThead} % yes, twice!
\def \NESTbodyend {%
  \ifOPENobject \else 
    \ELEMENTclosenest \CONSTp
    \ELEMENTclosenest \CONSTscript
    \ELEMENTclosenest \CONSTtd
    \ELEMENTclosenest \CONSTth
    \ELEMENTclosenest \CONSTtr
    \ELEMENTclosenest \CONSTtbody
    \ELEMENTclosenest \CONSTtable
    \ELEMENTclosenest \CONSTform
    \ifOPENparinner \VERIFYerrormissingendtag \CONSTp \fi %%%
    \MESSAGEhyphen \fi}

\def \NESTcenterbegin {\ELEMENTclosenest \CONSTp}

\def \NESTcolgroupbegin {\ELEMENTclosenest \CONSTcolgroup}

\def \NESTddbegin {%
  \ELEMENTclosenest \CONSTp
  \ELEMENTclosenest \CONSTdt
  \ELEMENTclosenest \CONSTdd}   
\def \NESTddend {\ELEMENTclosenest \CONSTp}

\def \NESTdivbegin {%
  \ELEMENTclosenest \CONSTfont
  \ifOPENobject \else \ELEMENTclosenest \CONSTp \fi}   
\def \NESTdivend {%
  \ELEMENTclosenest \CONSTfont
  \ifOPENp \VERIFYerrormissingendtag \CONSTp \GAPfilledfalse \fi
  \ELEMENTclosenest \CONSTlabel}

\def \NESTdlbegin {\ELEMENTclosenest \CONSTp}   
\def \NESTdlend {% 
  \ELEMENTclosenest \CONSTp
  \ELEMENTclosenest \CONSTdt
  \ELEMENTclosenest \CONSTdd}

\def \NESTdtbegin {%
  \ELEMENTclosenest \CONSTdt
  \ELEMENTclosenest \CONSTdd}

\def \NESTformbegin {%
  \ELEMENTclosenest \CONSTp
  \ELEMENTclosenest \CONSTform}   
\def \NESTformend {\ELEMENTclosenest \CONSTselect}

\def \NESThbegin {%
  \ELEMENTclosenest \CONSTfont
  \ifOPENobject \else \ELEMENTclosenest \CONSTp \fi
  \ifOPENparinner \VERIFYerrormissingendtag \CONSTp \fi}   
\def \NESThend {\ELEMENTclosenest \CONSTfont}

\def \NESTheadbegin {%
  \ifOPENhead \ifOPENbody \else \VERIFYerrormissingendtag \CONSThead \fi \fi}
\def \NESTheadend {%
  \ifOPENstyle \VERIFYerrormissingendtag \CONSTstyle \fi}

\def \NESThtmlend {\ELEMENTclosenest \CONSThead}

\def \NESTlibegin {%
  \ELEMENTclosenest \CONSTli
  \ELEMENTclosenest \CONSTp}   
\def \NESTliend {\ELEMENTclosenest \CONSTp}

\def \NESTlinkbegin {\ELEMENTclosenest \CONSTstyle}

\def \NESTmapend {\ELEMENTclosenest \CONSTp}

\def \NESTmetabegin {\ELEMENTclosenest \CONSTstyle}

\def \NESTnobrend {\ELEMENTclosenest \CONSTfont}

\def \NESTolbegin {\ELEMENTclosenest \CONSTp}   
\def \NESTolend {%
  \ELEMENTclosenest \CONSTp
  \ELEMENTclosenest \CONSTli}
  
\def \NESToprgroupend {\ELEMENTclosenest \CONSToption}

\def \NESToptionbegin {\ELEMENTclosenest \CONSToption}

\def \NESTpbegin {%
  \ifOPENp \ifOPENobject
    \ifOPENparinner 
    \ifOPENparouter \else
      \VERIFYerrormissingendtag \CONSTp \fi \fi 
    \else \VERIFYerrormissingendtag \CONSTp \fi \fi
  \ifOPENtd %% \OPENparinnertrue
    \else %%%
    \ifOPENth %% \OPENparinnertrue 
    \else  %%%
      \ifOPENobject 
        \ifOPENiframe %%%%%
          \OPENparinnertrue 
        \else \OPENparinnerfalse \fi \fi \fi \fi} %%%
\def \NESTpend {%
  \ELEMENTclosenest \CONSTb
  \ELEMENTclosenest \CONSTem
  \ELEMENTclosenest \CONSTi
  \ELEMENTclosenest \CONSTstrong
  \ELEMENTclosenest \CONSTa
  \ifOPENfontinner \VERIFYerrormissingendtag \CONSTfont \fi}

\def \NESTprebegin {\ELEMENTclosenest \CONSTp}
\def \NESTselectend {\ELEMENTclosenest \CONSToption} 

\def \NESTtablebegin {%
  \ifOPENb \OPENboutertrue \else \OPENbouterfalse \fi
  \ifOPENi \OPENioutertrue \else \OPENifalse \fi
  \ifOPENfont \OPENfontoutertrue \else \OPENfontouterfalse \fi
  \ifOPENp \OPENparoutertrue \else \OPENparouterfalse \fi}   
\def \NESTtableend {%
  \ELEMENTclosenest \CONSTtd
  \ELEMENTclosenest \CONSTth
  \ELEMENTclosenest \CONSTtr
  \ELEMENTclosenest \CONSTthead
  \ELEMENTclosenest \CONSTtbody
  \ELEMENTclosenest \CONSTtfoot
  \ifOPENfontouter \else \ELEMENTclosenest \CONSTfont \fi}   
\def \NESTtableendouter {%
  \ifOPENbouter \VERIFYerrormisnested \fi    
  \ifOPENiouter \VERIFYerrormisnested \fi 
  \ifOPENfontouter \VERIFYerrormisnested \fi  
  \ifOPENbouter \else \ifOPENiouter \else \ifOPENfontouter \else
    \MESSAGEdot \fi \fi \fi}

\def \NESTtbodybegin {%
  \ELEMENTclosenest \CONSTcolgroup
  \ELEMENTclosenest \CONSTthead
  \ELEMENTclosenest \CONSTtbody
  \ELEMENTclosenest \CONSTtfoot}   
\def \NESTtbodyend {%
  \ELEMENTclosenest \CONSTtd
  \ELEMENTclosenest \CONSTth
  \ELEMENTclosenest \CONSTtr}

\def \NESTtdbegin {%
  \ELEMENTclosenest \CONSTtd
  \ELEMENTclosenest \CONSTth}   
\def \NESTtdend {%
  \ifOPENbouter \else \ELEMENTclosenest \CONSTb \fi
  \ELEMENTclosenest \CONSTem
  \ifOPENiouter \else \ELEMENTclosenest \CONSTi \fi
  \ELEMENTclosenest \CONSTstrong}

\def \NESTtdthend {%
  \ifOPENfontinner \VERIFYerrormissingendtag \CONSTfont \fi
  \ELEMENTclosenest \CONSTa
  \ifOPENparinner \VERIFYerrormissingendtag \CONSTp \fi     
% \ifOPENp \ifOPENfloat \ifOPENparouter \else \VERIFYerroropenp \fi %%% Fixme
% \else \VERIFYerrormissingendtag \CONSTp \fi \fi
  } 

\let \NESTtfootbegin \NESTtbodybegin
\let \NESTtfootend \NESTtbodyend

\let \NESTthbegin \NESTtdbegin
\let \NESTthend \NESTtdend %%%

\let \NESTtheadbegin \NESTtbodybegin
\let \NESTtheadend \NESTtbodyend

\def \NESTtitlebegin {\ELEMENTclosenest \CONSTstyle}

%\let \NESTtrbegin \NESTtbodybegin
\def \NESTtrbegin {\ELEMENTclosenest \CONSTtr}
\let \NESTtrend \NESTtdbegin % sic! 

\let \NESTulbegin \NESTolbegin   
\let \NESTulend \NESTolend

% NEW: =======================================================================

\ldef \NEWatt #1 {%
  \message {#1,}%
  \gDef \CONSTconst #1 {#1}%   
  \glDef \CONSTatt #1 {%
    \VERIFYerrorproprietaryatt {#1}}} % must be redefined for tag 
  
\ldef \NEWattdef #1 #2{%
  \gDef \CONSTconst #1 {#1}%
  \glDef \CONSTatt #1 {#2}}
                    
\ldef \NEWattnotstrictunsupported #1 {%
  \glDef \CONSTatt #1 {\VERIFYnotstrict \VERIFYerrorunsuppattprop {#1}}}
    
\ldef \NEWatttag #1 #2 #3{% define \TAG#2ATT#1 (reverse args)
  \glDef \CONSTtag #2\CONSTatt #1 {#3}}
     
\ldef \NEWatttagdeprecated #1 #2 #3{%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYerrordeprecatedatt {#1}#3}}
    
\ldef \NEWatttagdeprecatedunsupported #1 #2 {%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYerrordeprecatedatt {#1}%
    \VERIFYerrorunsuppattprop {#1}}}
         
\ldef \NEWatttagproprietary #1 #2 #3{%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYerrorproprietaryatt {#1}#3}}
    
\ldef \NEWatttagproprietaryunsupported #1 #2 {%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYerrorproprietaryatt {#1}%
    \VERIFYerrorunsuppattprop {#1}}}
    
\ldef \NEWatttagnotstrict #1 #2 #3{%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYnotstrictatt {#2}#3}}
    
\ldef \NEWatttagnotstrictunsupported #1 #2 {%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYnotstrict \VERIFYerrorunsuppattprop {#1}}}
    
\ldef \NEWatttagtemplate #1 #2 #3 {% use \TAG#3ATT#1 as template; reverse args 
  \glDef \CONSTtag #2\CONSTatt #1 {%
    \csname \CONSTtag #3\CONSTatt #1\endcsname}}
    
\ldef \NEWatttagunsupported #1 #2 {%
  \glDef \CONSTtag #2\CONSTatt #1 {% reverse args
    \VERIFYerrorunsuppattprop {#1}}} 
     
\ldef \NEWattquiet #1 {% like \NEWatt, but without message in gerolf.log
  \gDef \CONSTconst #1 {#1}%   
  \glDef \CONSTatt #1 {\VERIFYerrorproprietaryatt {#1}}}
  
\ldef \NEWattproprietary #1 {% like \NEWatt, but without message in gerolf.log
  \gDef \CONSTconst #1 {#1}%   
  \glDef \CONSTatt #1 {\VERIFYerrorproprietaryatt {#1}}}
  
\ldef \NEWattunsupported #1 {%
  \glDef \CONSTatt #1 {\VERIFYerrorunsuppattprop {#1}}}   

\ldef \NEWpropquiet #1 #2{% like \NEWpropnew, without \message in gerolf.log
  \glDef \CONSTprop #1 {#2}}  
  
\ldef \NEWpropmessage #1 {%
  \message {#1,}%
  \glDef \CONSTprop #1 {\VERIFYerrorunsuppattprop {#1}}}  
  
\ldef \NEWpropnew #1 #2{%
  \message {#1,}%
  \glDef \CONSTprop #1 {#2}}
  
\ldef \NEWpropnewtag #1 #2 #3{%
  \glDef {\CONSTtag #1\CONSTprop #2} {#3}}
    
\ldef \NEWpropproprietary #1 #2{% like \NEWpropnew, with error message in log
  \glDef \CONSTprop #1 {\VERIFYerrorproprietaryatt {#1}#2}} 
   
\ldef \NEWproptagunsupported #1 #2 {% %%%
  \glDef \CONSTtag #1\CONSTprop #2 {% reverse args
    \VERIFYerrorunsuppattprop {#2}}} 
    
\ldef \NEWpropunsupported #1 {%
  \glDef \CONSTprop #1 {\VERIFYerrorunsuppattprop {#1}}}  
  
% NO: ========================================================================

\nec \NOcell
\nec \NOcol
\def \NOcollast {0}
\nec \NOddlast
\nec \NOh
\nec \NOinclude \NOinclude = 0 % included documents
\nec \NOinput \NOinput = 1 % chained documents
\nec \NOli
\nec \NOlilast

% Paragraph numbering:

\nec \NOpar

\def \NOparadvance {%
  \ifnum \NOpar > 1 \message {-}\fi
  \global \advance \NOpar by 1 
  \message {\the \NOpar.}}
  
\nec \NOparlast

\def \NOparlastsetglobal {%
  \global \NOparlast = \verifyWELLFORMtotalelements}

\def \NOparreset {%
  \NOpar = 0 }

\def \NOparresetglobal {%
  \global \NOpar = 0 }  
  
\nec \NOrow
\nec \NOrowspan
\nec \NOtable

% OBEY: ======================================================================

\def \OBEYend {%
  \ifOPENli \else \NOparresetglobal \fi 
  \hangindent = 0mm}

\def \OBEYnormalspaces {%
  \catcode`\ \CATwhitespace}

\def \OBEYnormallines {%
  \catcode`\^^M=\CATendofline}

\def \OBEYnormalspacesandlines {%
  \OBEYnormalspaces \OBEYnormallines}

\def \OBEYobeyspaces {% active whitespace
  \catcode`\ =\CATactive}

\def \OBEYobeyspacesandlines {%
  \OBEYobeyspaces \OBEYobeylines}

\def \OBEYpagebreak {%
  \vfill \par \break}

\def \OBEYstrutspace {{% 
  \setbox 3 = \hbox {x}% 
  \strut \hskip \wd 3 }}

% Init active whitespace, compare Knuth, pages 352, 381 (no whitespace and
% linebreaks allowed here):

{\OBEYobeyspaces\global\let =\OBEYstrutspace} %% check this

{\catcode `\^^M=\CATactive%
  \gdef\OBEYobeylines{\catcode`\^^M=\CATactive\let^^M\par}%
  \global\let^^M=\par}

{\catcode `\^^M=\CATactive%
  \gdef\OBEYspacelines{\catcode`\^^M=\CATactive\let^^M\CONSTspace}}
    
% OBJECT: ====================================================================

\def \OBJECTdata {exit}

\def \OBJECThandle {%
  \ifLINKunrendered \OPENobjectfalse \else
    \ifx \URLhref \empty \else
    \ifx \OBJECTtype \CONSTtexthtml \MESSAGEobjecthtml \FILEhtmltrue \else 
    \ifx \OBJECTtype \CONSTtextplain \MESSAGEobjectplain \FILEplaintrue \else
    \ifx \OBJECTtype \CONSTtextTeX \MESSAGEobjectTeX \FILETeXtrue \else 
      \LINKunrenderedtrue \fi \fi \fi \fi        
    \ifLINKunrendered \else \CHAINobjectloadurl \fi
    \ifOPENtable \CHAINget \VERIFYwellformedness \fi \fi}
  
\def \OBJECTinit {%
  \ifOPENp \OPENparoutertrue \fi
  \let \URLhref \empty
  \let \OBJECTtype \empty
  \FONTfamilygivenfalse}

\def \OBJECTplain {%
  \ifFONTfamilygiven \FONTchoose \FONTdo \else \FONTdomono \fi
  \parindent = 0mm
  \catcode `\< = \CATother
  \OBEYobeylines \OBEYobeyspaces}

\def \OBJECTtex {%
  \endmarkupCAT \tenrm \parindent = 20pt}
    
% OUTPUT: ====================================================================

% Fixme: outsource margin stuff

\output = {\OUTPUTpagesingle {\unvbox 255 }} % executed by TeX engine itself

\def \OUTPUTbody #1{% <body>, <gedcom>
  \frenchspacing % Fixme: should depend on language
  \FONTsizeadjusttrue \FONTdecorationtrue
  \let \Style \empty
  \VALUE = {black}\COLORsetforeground
  \DEFsearch {\CONSTSTYLE @page}%
  \ifDEF \ELEMENT = {@page}\ELEMENTvaluegetstyle 
    \OUTPUTmarginset \OUTPUTgutter \fi
  \ifOPENiframe \OUTPUTinit \fi
  \ifOPENobject \else \OUTPUTinit \fi
  \parindent = 0mm
  \ELEMENT = \expandafter {#1}%
  \ELEMENTvalueget 
  \MARGIN = 0mm
  \global \NOtable = 0
  \global \BACKUPnotable = 0
  \OUTPUTmake \OUTPUTfootline 
  \GAPsetstrut
  \KERNINGdonefalse
  \COLORizeforeground
  \let \COLORbody \COLORforeground
  \FONTpageno = \FONTfamily
  \FONTchoose \FONTdo 
  \KERNINGcheck \KERNINGshow 
  \MESSAGEfontfamily   
  \CODEPAGEwindowscheck
  \MESSAGEcodepagelanguage}
  
\def \OUTPUTbreak {%
  \VALUEset \test
  \ifx \test \CONSTalways \OBEYpagebreak \else 
    \ifx \test \CONSTavoid \nobreak \else 
      \ifx \test \CONSTleft \CLASSbreakifeven \else
         \ifx \test \CONSTright \CLASSbreakifodd \fi \fi \fi \fi}
         
\def \OUTPUTbreakh {%
  \ifnum \count 1 > 1 \OUTPUTbreak \fi}
      
%  Double-column output, compare Knuth, pages 416/417 (manmac.tex):

\new \ifOUTPUTdouble

\def \OUTPUTdoublebegin {%
  \ifOUTPUTdouble \LINEupskip \OUTPUTdoublebegindo \fi}

  \def \OUTPUTdoublebegindo {%
    \ifnum \clubpenalty > 9999 \clubpenalty = 9999 \fi
    \ifnum \widowpenalty > 9999 \widowpenalty = 9999 \fi
    \hbadness = 5000
    \output = {\global \setbox \OUTPUTpagepart = \vbox {%
      \unvbox 255 \bigskip }}\eject
    \output = {\OUTPUTpagedoublebegin}%
    \hsize = \TEXTwidth
      \advance \hsize by -\LINEheight 
      \hsize = 0.5\hsize 
    \vsize = \TEXTheight
      \vsize = 2\vsize}

\def \OUTPUTdoubleend {%
  \ifOUTPUTdouble \OUTPUTdoubleenddo \fi}  

  \def \OUTPUTdoubleenddo {%
    \output = {\OUTPUTpagedoubleend }\eject
    \pagegoal = \TEXTheight \bigskip}
      
\def \OUTPUTfootline {%
  \xdef \setLINEheightbody {\LINEheight = \the \LINEheight}% dummy expand
  \xdef \setFONTsizebody {\SIZE = \the \SIZE \SIZEbase = 3 }%
  \global \footline = {%
    \ifOUTPUTnopage 
      \ifOUTPUTnopagedont \hfil \else \OUTPUTfootlinedo \fi
    \else \ifOUTPUTnopagedo \OUTPUTfootlinedo \else \hfil \fi \fi}}

  \def \OUTPUTfootlinedo {%
    \setLINEheightbody \setFONTsizebody \strut
   {\FONTfamily = \FONTpageno \FONTchoose \FONTdo
    \let \OUTPUTfootlinedoleft \hss \let \OUTPUTfootlinedoright \hss
    \ifOUTPUTgutter 
      \ifodd \OUTPUTnopage \let \OUTPUTfootlinedoright \empty
      \else \let \OUTPUTfootlinedoleft \empty \fi \fi 
    \OUTPUTfootlinedoleft
    \ifnum \OUTPUTnopage > 2 \the \OUTPUTnopage \else \ifOUTPUTnopagedo 
      \ifnum \OUTPUTnopage > 0 \the \OUTPUTnopage \fi \fi \fi 
    \OUTPUTfootlinedoright}}
    
\new \ifOUTPUTgutter

\def \OUTPUTgutter {%
  \DEFsearch {\CONSTSTYLE :left-CONTEXT-@page}\ifDEF
    \xdef \STYLEpageleft {%
      \csname \CONSTSTYLE :left-CONTEXT-@page\endcsname}%
    \DEFsearch {\CONSTSTYLE :right-CONTEXT-@page}\ifDEF
     \global \OUTPUTguttertrue
      \xdef \STYLEpageright {%
        \csname \CONSTSTYLE :right-CONTEXT-@page\endcsname}%
      \ifodd \OUTPUTnopage \ELEMENT = {pageright}%
      \else \ELEMENT = {pageleft}\fi
      \ELEMENTvaluegetstyle \OUTPUTmarginset \fi \fi}
      
\let \OUTPUTheight \pdfpageheight
  \ifx \pdfpageheight \undefined 
    \csname newdimen\endcsname \OUTPUTheight \fi

\def \OUTPUTinit {%
  \global \hsize = \OUTPUTwidth
    \global \advance \hsize by -\OUTPUTmarginleft 
    \global \advance \hsize by -\OUTPUTmarginright
    \global \hoffset = -1in
    \global \advance \hoffset by \OUTPUTmarginleft
  \global \vsize = \OUTPUTheight
    \global \advance \vsize by -\OUTPUTmargintop 
    \global \advance \vsize by -\OUTPUTmarginbottom
    \global \voffset = -1in
    \global \advance \voffset by \OUTPUTmargintop
  \OUTPUTmake}
      
\def \OUTPUTmake {% 
  \global \TEXTheight = \vsize
  \global \TEXTwidth = \hsize 
  \ifdim \LINEheight > 0mm \global \LINEheightpageno = \LINEheight \fi
 {\divide \OUTPUTmarginbottom by 3
  \ifdim \OUTPUTmarginbottom > \LINEheightpageno
    \global \MARGINpageno = 1.5\OUTPUTmarginbottom
    \global \advance \MARGINpageno by -0.5\LINEheightpageno
  \else \global \MARGINpageno = 2\LINEheightpageno \fi}}
  
\ned \OUTPUTmarginbottom
\ned \OUTPUTmarginleft
\ned \OUTPUTmarginright
        
\def \OUTPUTmarginset {%
  \OUTPUTmargintop = \MARGINtop
  \OUTPUTmarginright = \MARGINright
  \OUTPUTmarginbottom = \MARGINbottom
  \OUTPUTmarginleft = \MARGINleft 
  \MARGINtop = 0mm
  \MARGINright = 0mm
  \MARGINbottom = 0mm
  \MARGINleft = 0mm }
  
\ned \OUTPUTmargintop

\let \OUTPUTnopage \pageno

\new \ifOUTPUTnopage

\def \OUTPUTnopagecheck {%
  \ifnum \count 1 > 1 \global \OUTPUTnopagetrue \else
    \ifnum \count 2 > 1 \global \OUTPUTnopagetrue \else
      \ifnum \count 3 > 1 \global \OUTPUTnopagetrue \fi \fi \fi}

\new \ifOUTPUTnopagedo
\new \ifOUTPUTnopagedont  
      
\def \OUTPUTpagedoublebegin {%
  \splittopskip = \topskip 
  \splitmaxdepth = \maxdepth
  \dimen 0 = \TEXTheight 
  \advance \dimen 0 by -\ht \OUTPUTpagepart
  \vfuzz = 1ex 
  \vbadness = 10000
  \setbox 0 = \vsplit 255 to \dimen 0 
  \setbox 2 = \vsplit 255 to \dimen 0
  \OUTPUTpagesingle \OUTPUTpagepartdo
  \unvbox 255 \penalty \outputpenalty }
  
\def \OUTPUTpagedoubleend {%
  \setbox 0 = \vbox {\unvbox 255 }%
  \dimen 0 = \ht 0
  \advance \dimen 0 by \topskip
  \advance \dimen 0 by -\LINEheight
  \divide \dimen 0 by 2
  \splittopskip = \topskip
  \vfuzz = 1ex
  \vbadness = 10000
   {\loop \global \setbox 3 = \copy 0
      \global \setbox 1 = \vsplit 3 to \dimen 0
      \ifdim \ht 3 > \dimen 0 \global \advance \dimen 0 by 1pt \repeat}%
  \setbox 0 = \vbox to \dimen 0 {\unvbox 1 }%
  \setbox 2 = \vbox to \dimen 0 {\unvbox 3 \vfil}%
  \OUTPUTpagepartdo} 
      
\def \OUTPUTpagesingle #1{%
  \noecho
  \count 1 = 0 \count 2 = 0 \count 3 = 0
  \count 4 = 0 \count 5 = 0 \count 6 = 0
  \count 7 = 0 \count 8 = 0 \count 9 = 0
  \shipout \vbox {%
    \vfuzz = 1ex
    \offinterlineskip
    \ifOUTPUTdouble \OUTPUTgutter \OUTPUTpagesinglelocal 
    \else \OUTPUTgutter \OUTPUTinit \fi
    \ifCOLORbgbody \COLORizebackground \fi
    \ifBACKGROUND \BACKGROUNDmake \fi
    \makeheadline  
    \ifCOLOR \COLORize \COLORactive \fi 
%%% \COLORize {1 0 0 rg 1 0 0 RG}% can show lines with wrong color on top
    \glet \COLORactive \COLORforeground
    \vbox to \TEXTheight {#1\vss}%
    \ifCOLOR \COLORize \COLORbody \fi
    \vskip \MARGINpageno \line {\GAPsetstrut \strut \the \footline}%
    \boxmaxdepth = \maxdepth}%   
  \advancepageno
  \global \hangindent = 0mm 
  \global \hangafter = 1 }
        
  \def \OUTPUTpagesinglelocal {%
    \hsize = \OUTPUTwidth
      \advance \hsize by -\OUTPUTmarginleft 
      \advance \hsize by -\OUTPUTmarginright
      \global \hoffset = -1in 
      \global \advance \hoffset by \OUTPUTmarginleft
    \vsize = \OUTPUTheight
      \advance \vsize by -\OUTPUTmargintop 
      \advance \vsize by -\OUTPUTmarginbottom
      \voffset = -1in
      \advance \voffset by \OUTPUTmargintop}      
      
\neb \OUTPUTpagepart

\def \OUTPUTpagepartdo {%
  \unvbox \OUTPUTpagepart 
  \hbox to \TEXTwidth {\box 0 \hss \box 2 }}
  
\def \OUTPUTsize {%
  \VALUEset \test 
  \expandafter \OUTPUTsizeparse \test \relax}   
  
  \def \OUTPUTsizeparse #1 #2\relax {%
    \VALUE = {#1}\VALUEdimenset \OUTPUTwidth \hsize
    \VALUE = {#2}\VALUEdimenset \OUTPUTheight \vsize }
  
\let \OUTPUTwidth \pdfpagewidth
  \ifx \pdfpagewidth \undefined 
    \csname newdimen\endcsname \OUTPUTwidth \fi 
    
% PADDING: ===================================================================
  
\ned \PADDINGbottom

\def \PADDINGbegin {%
  \vbox \bgroup
  \ifTABLEinter \else \vskip \PADDINGtop \fi
  \hbox \bgroup \hskip \PADDINGleft}

\def \PADDINGend {%
  \hskip \PADDINGright \egroup
  \ifTABLEinter \else \vskip \PADDINGbottom \fi \egroup} 

\ned \PADDINGleft
\ned \PADDINGright

\def \PADDINGset {%
  \edef \PADDINGtest {\the \VALUE \CONSTspace}%
  \expandafter \PADDINGcheckspace \PADDINGtest \relax}
  % supporting only one value for all:
  \def \PADDINGcheckspace #1 #2\relax {%
    \edef \PADDINGcheckspacesecond {#2}%
    \ifx \PADDINGcheckspacesecond \empty
      \csname \CONSTproppadding top\endcsname
      \PADDINGright = \PADDINGtop
      \PADDINGbottom = \PADDINGtop
      \PADDINGleft = \PADDINGtop 
    \else \VERIFYerrorunsuppattprop \CONSTpadding \fi} 

\ned \PADDINGtop
              
% PLAIN: =====================================================================

% Plain TeX entities:

\def \PLAINAacute {\'A}
\def \PLAINaacute {\'a}
\def \PLAINAcirc {\^A}
\def \PLAINacirc {\^a}
\def \PLAINacute {\'\empty}
\let \PLAINAElig \AE
\let \PLAINaelig \ae
\def \PLAINAgrave {\`A}
\def \PLAINagrave {\`a}
\let \PLAINAring \AA
\let \PLAINaring \aa
\def \PLAINalefsym {\FONTcmsymb \char "40}
\def \PLAINAlpha {\FONTcmmath A}
\def \PLAINalpha {\FONTcmmath \char "0B}
\def \PLAINamp {\&}
\def \PLAINand {\FONTcmsymb \char "5E}
\def \PLAINang {{\FONTcmsymb \char "36}\lower 1.1ex \hbox { \char "7B}}
\def \PLAINasymp {\FONTcmsymb \char "18}
\def \PLAINAtilde {\~A}
\def \PLAINatilde {\~a}
\def \PLAINAuml {\"A}
\def \PLAINauml {\"a}
\def \PLAINbdquo {,\kern -.2ex,}
\def \PLAINBeta {\FONTcmmath B}
\def \PLAINbeta {\FONTcmmath \char "0C}
\def \PLAINbrvbar {\FONTcmsymb \char "6A}
\def \PLAINbull {\FONTcmsymb \char "0F}
\def \PLAINcap {\FONTcmsymb \char "5C}
\def \PLAINcedil {\char "18}% \c does not work here
\def \PLAINCcedil {C\llap {\char "18 \CONSTspace}}%
\def \PLAINccedil {c\llap {\char "18}}%
\def \PLAINcent {c\kern .2ex\llap /}
\def \PLAINChi {\FONTcmmath X}
\def \PLAINchi {\FONTcmmath \char "1F}
\def \PLAINcirc {\FONTcmsymb \char "0D}
\def \PLAINclubs {\FONTcmsymb \char "7C}
\def \PLAINcopy {{\FONTcmsymb \char "0D}\llap {\raise .1ex 
  \hbox {c}\hskip .667ex}}
\def \PLAINcrarr {\FONTcmsymb \char "20\kern -0.35ex 
  \raise 0.45ex \hbox {\char "37}}
\def \PLAINcup {\FONTcmsymb \char "5B}
\def \PLAINcurren {.\llap {\raise .8ex \hbox {.}}%
  \kern -.45ex o\kern -.45ex .\llap {\raise .8ex \hbox {.}}}
\def \PLAINDagger {\FONTcmsymb \char "7A}
\def \PLAINdagger {\FONTcmsymb \char "79}
\def \PLAINdArr {\FONTcmsymb \char "2B}
\def \PLAINdarr {\FONTcmsymb \char "23}
\def \PLAINdeg {\FONTcmtext \char "17\kern -0.5ex \strut}
\def \PLAINDelta {\FONTcmmath \char "01}
\def \PLAINdelta {\FONTcmmath \char "0E}
\def \PLAINdiams {\FONTcmsymb \char "7D}
\def \PLAINdivide {\FONTcmsymb \char "04}
\def \PLAINEacute {\'E}
\def \PLAINeacute {\'e}
\def \PLAINEcirc {\^E}
\def \PLAINecirc {\^e}
\def \PLAINcong {=\llap {\raise .6ex \hbox {\FONTcmsymb \char "18}}}
\def \PLAINEgrave {\`E}
\def \PLAINegrave {\`e}
\let \PLAINempty \O
\def \PLAINEpsilon {\FONTcmmath E}
\def \PLAINepsilon {\FONTcmmath \char "0F}
\def \PLAINequiv {\FONTcmsymb \char "11}
\def \PLAINEta {\FONTcmmath H}
\def \PLAINeta {\FONTcmmath \char "11}
\def \PLAINETH {\raise 0.3ex \hbox {-}\kern -0.85ex D}
\def \PLAINeth {\CONSTspace \char "13 \kern -1.6ex {\FONTcmmath \char "40}}
\def \PLAINEuml {\"E}
\def \PLAINeuml {\"e}
\def \PLAINeuro {C\llap {\raise .2ex \hbox {\FONTcmital = }}}
\def \PLAINexist {\FONTcmsymb \char "39}
\def \PLAINfnof {\FONTcmmath f}
\def \PLAINforall {\FONTcmsymb \char "38}
\Def {PLAINfrac12} {{\FONTcmsymb \char "36}{\FONTcmsmall 
  \raise 1ex \hbox {1}\kern 0.667ex 2}}
\Def {PLAINfrac14} {{\FONTcmsymb \char "36}{\FONTcmsmall 
  \raise 1ex \hbox {1}\kern 0.5ex 4}}
\Def {PLAINfrac34} {{\FONTcmsymb \char "36}{\FONTcmsmall 
  \raise 1ex \hbox {3}\kern 0.5ex 4}}
\def \PLAINfrasl {\FONTcmsymb \char "36\hskip 1ex}
\def \PLAINGamma {\FONTcmmath \char "00}
\def \PLAINgamma {\FONTcmmath \char "0D}
\def \PLAINge {\FONTcmsymb \char "15}
\def \PLAINgt {\FONTcmmath >}
\def \PLAINhArr {\FONTcmsymb \char "2C}
\def \PLAINharr {\FONTcmsymb \char "24}
\def \PLAINhearts {\FONTcmsymb \char "7E}
\def \PLAINhellip {.\kern -.1ex.\kern -.1ex.}
\def \PLAINIacute {\'I}
\def \PLAINiacute {\'\i}
\def \PLAINIcirc {\^I}
\def \PLAINicirc {\^\i}
\def \PLAINiexcl {!`}
\def \PLAINIgrave {\`I}
\def \PLAINigrave {\`\i}
\def \PLAINimage {\FONTcmsymb \char "3D}
\def \PLAINinfin {\FONTcmsymb \char "31}
\def \PLAINint {\FONTcmsymb \char "73}
\def \PLAINIota {\FONTcmmath I}
\def \PLAINiota {\FONTcmmath \char "13}
\def \PLAINiquest {?`}
\def \PLAINisin {\FONTcmsymb \char "32}
\def \PLAINIuml {\"I}
\def \PLAINiuml {\"\i}
\def \PLAINKappa {\FONTcmmath K}
\def \PLAINkappa {\FONTcmmath \char "14}
\def \PLAINLambda {\FONTcmmath \char "03}
\def \PLAINlambda {\FONTcmmath \char "15}
\def \PLAINlang {\FONTcmsymb \char "68}
\def \PLAINlaquo {\FONTcmsmalltype <\kern -.5ex <}
\def \PLAINlArr {\FONTcmsymb \char "28}
\def \PLAINlarr {\FONTcmsymb \char "20}
\def \PLAINlceil {\FONTcmsymb \char "65}
\def \PLAINldquo {``}
\def \PLAINle {\FONTcmsymb \char "14}
\def \PLAINlfloor {\FONTcmsymb \char "63}
\def \PLAINlowast {\FONTcmmath \char "3F}
\def \PLAINloz {\FONTcmsymb \char "05}
\def \PLAINlrm {\VERIFYerrorlostplain \CONSTlrm}
\def \PLAINlsaquo {\FONTcmsmalltype <}
\def \PLAINlsquo {`}
\def \PLAINlt {\FONTcmmath <}
\def \PLAINmacr {\raise .75ex \hbox {\char "7B}}
\def \PLAINmdash {\char "7C}
\def \PLAINmicro {\FONTcmmath \char "16}
\def \PLAINmiddot {\FONTcmsymb \char "01}
\def \PLAINminus {\char "7B}
\def \PLAINMu {\FONTcmmath M}
\def \PLAINmu {\FONTcmmath \char "16}
\def \PLAINnabla {\FONTcmsymb \char "72}
\def \PLAINndash {\char "7B}
\def \PLAINne {=\kern -.3ex\llap /}
\def \PLAINni {\FONTcmsymb \char "33}
\def \PLAINnot {\FONTcmsymb \char "3A}
\def \PLAINnotin {{\FONTcmsymb \char "32}\kern -.3ex\llap /}
\def \PLAINnsub {{\FONTcmsymb \char "1A}\kern -.3ex\llap /}
\def \PLAINNu {\FONTcmmath N}
\def \PLAINnu {\FONTcmmath \char "17}
\def \PLAINNtilde {\~N}
\def \PLAINntilde {\~n}
\def \PLAINOacute {\'O}
\def \PLAINoacute {\'o}
\def \PLAINOcirc {\^O}
\def \PLAINocirc {\^o}
\let \PLAINOElig \OE
\let \PLAINoelig \oe
\def \PLAINOgrave {\`O}
\def \PLAINograve {\`o}
\def \PLAINoline {\raise 1ex \hbox {\char "2D}}
\def \PLAINOmega {\FONTcmmath \char "0A}
\def \PLAINomega {\FONTcmmath \char "21}
\def \PLAINOmicron {\FONTcmmath O}
\def \PLAINomicron {\FONTcmmath o}
\def \PLAINor {\FONTcmsymb \char "5F}
\def \PLAINordf {\FONTcmsmall \raise 1ex \hbox {a}}
\def \PLAINordm {\FONTcmsmall \raise 1ex \hbox {o}}
\let \PLAINOslash \O
\let \PLAINoslash \o
\def \PLAINoplus {\FONTcmsymb \char "08}
\def \PLAINOtilde {\~O}
\def \PLAINotilde {\~o}
\def \PLAINotimes {\FONTcmsymb \char "0A}
\def \PLAINOuml {\"O}
\def \PLAINouml {\"o}
\def \PLAINpara {\FONTcmsymb \char "7B}
\def \PLAINpart {\FONTcmmath \char "40}
\Def {PLAINpermil} {{\FONTcmsymb \char "36}{\FONTcmsmall 
  \raise 1ex \hbox {0}\kern 0.75ex 00}}
\def \PLAINperp {\FONTcmsymb \char "3F}
\def \PLAINPhi {\FONTcmmath \char "08}
\def \PLAINphi {\FONTcmmath \char "1E}
\def \PLAINPi {\FONTcmmath \char "05}
\def \PLAINpi {\FONTcmmath \char "19}
\def \PLAINpiv {\FONTcmmath \char "24}
\def \PLAINplusmn {\FONTcmsymb \char "06}
\def \PLAINpound {\FONTcmital \char "24}
\def \PLAINPrime {\FONTcmsymb \char "30\char "30}
\def \PLAINprime {\FONTcmsymb \char "30}
\def \PLAINprod {\char "05}
\def \PLAINprop {\VERIFYerrorlostplain \CONSTprop}
\def \PLAINPsi {\FONTcmmath \char "09}
\def \PLAINpsi {\FONTcmmath \char "20}
\def \PLAINquot {\FONTcmtype "}
\def \PLAINradic {\raise .75\LINEheight \hbox {\FONTcmsymb \char "70}}
\def \PLAINrang {\FONTcmsymb \char "69}
\def \PLAINraquo {\FONTcmsmalltype >\kern -.5ex >}
\def \PLAINrArr {\FONTcmsymb \char "29}
\def \PLAINrarr {\FONTcmsymb \char "21}
\def \PLAINrceil {\FONTcmsymb \char "64}
\def \PLAINrdquo {''}
\def \PLAINreal {\FONTcmsymb \char "3C}
\def \PLAINreg {{\FONTcmsymb \char "0D}\llap {\lower 0.15ex 
  \hbox {R\hskip 0.25ex}}}
\def \PLAINrfloor {\FONTcmsymb \char "62}
\def \PLAINRho {\FONTcmmath P}
\def \PLAINrho {\FONTcmmath \char "1A}
\def \PLAINrlm {\VERIFYerrorlostplain \CONSTrlm}
\def \PLAINrsaquo {\FONTcmsmalltype >}
\def \PLAINrsquo {'}
\def \PLAINsdot {\FONTcmsymb \char "01}
\def \PLAINsect {\FONTcmsymb \char "78}
\def \PLAINsbquo {,}
\def \PLAINScaron {\v S}
\def \PLAINscaron {\v s}
\def \PLAINSigma {\FONTcmmath \char "06}
\def \PLAINsigma {\FONTcmmath \char "1B}
\def \PLAINsigmaf {\FONTcmmath \char "26}
\def \PLAINsim {\FONTcmsymb \char "18}
\def \PLAINspades {\FONTcmsymb \char "7F}
\def \PLAINsub {\FONTcmsymb \char "1A}
\def \PLAINsube {\FONTcmsymb \char "13}
\def \PLAINsum {\char "06}
\def \PLAINsup {\FONTcmsymb \char "1B}
\Def {PLAINsup1} {\FONTcmsmall \raise 1ex \hbox {1}}
\Def {PLAINsup2} {\FONTcmsmall \raise 1ex \hbox {2}}
\Def {PLAINsup3} {\FONTcmsmall \raise 1ex \hbox {3}}
\def \PLAINsupe {\FONTcmsymb \char "13}
\let \PLAINszlig \ss
\def \PLAINTau {\FONTcmmath T}
\def \PLAINtau {\FONTcmmath \char "1C}
\Def {PLAINthere4} {.\kern -.25ex {\PLAINmiddot }\kern -.25ex .}
\def \PLAINTheta {\FONTcmmath \char "02}
\def \PLAINtheta {\FONTcmmath \char "12}
\def \PLAINthetasym {\FONTcmmath \char "23}
\def \PLAINTHORN {I\kern -0.525ex {\raise 0.3ex \hbox {o}}}
\def \PLAINthorn {\lower 0.3ex \hbox {I}\kern -0.525ex o} 
\def \PLAINtimes {\FONTcmsymb \char "02}
\def \PLAINtrade {\FONTcmsmall \raise 1ex \hbox {TM}}
\def \PLAINUacute {\'U}
\def \PLAINuacute {\'u}
\def \PLAINuArr {\FONTcmsymb \char "2A}
\def \PLAINuarr {\FONTcmsymb \char "22}
\def \PLAINUcirc {\^U}
\def \PLAINucirc {\^u}
\def \PLAINUgrave {\`U}
\def \PLAINugrave {\`u}
\def \PLAINuml {\char "7F}
\def \PLAINupsih {\FONTcmmath \char "07}
\def \PLAINUpsilon {\FONTcmmath Y}
\def \PLAINupsilon {\FONTcmmath u}
\def \PLAINUuml {\"U}
\def \PLAINuuml {\"u}
\def \PLAINweierp {\FONTcmsymb P}
\def \PLAINXi {\FONTcmmath \char "04}
\def \PLAINxi {\FONTcmmath \char "18}
\def \PLAINYacute {\'Y}
\def \PLAINyacute {\'y}
\def \PLAINyen {Y\llap =}
\def \PLAINYuml {\"Y}
\def \PLAINyuml {\"y}
\def \PLAINZeta {\FONTcmmath Z}
\def \PLAINzeta {\FONTcmmath \char "10}
\def \PLAINzwj {\penalty 10000 \strut}
\def \PLAINzwnj {\strut}   

% PROP: ======================================================================

\new \ifPROP

\def \PROPget {%
  \expandafter \PROPlistparse \the \PROPlist ;STOP:-GMS-STOP;}
    
\net \PROPlist

\def \PROPlistget #1{% 
  % Fixme: replaceable - set \PROPlist, call \PROPget
  \expandafter \PROPlistparse #1;STOP:-GMS-STOP;}

  \def \PROPlistparse #1#2:#3#4;{%
    \lowercase {\edef \PROPlistparsefirst {#1#2}}%
    \edef \PROPlistparsethird {#3}% %%%
    \edef \PROPlistparsefourth {#4}%
    \ifx \PROPlistparsethird \CONSTquotmark %%% Fixme: check apostrophe too
      \let \PROPlistparsethirdfourth \PROPlistparsefourth %%%
    \else \edef \PROPlistparsethirdfourth {#3#4}\fi
    \let \PROPlistparsenext \relax
    \ifx \PROPlistparsefourth \CONSTstopmark \PROPlistparsestop
    \else \PROPlistparserun \fi 
    \PROPlistparsenext \PROPlistparsevalue}

    \def \PROPlistparserun {%
      \VALUE = \expandafter {\PROPlistparsethirdfourth}%
      \edef \PROPlistparseruntest {%
        \PROPlistparsethirdfourth \CONSTspace}%
      \let \PROPlistparserunvalue \empty 
      \expandafter \PROPlistparserunspace 
        \PROPlistparseruntest \CONSTstopmark
      \VALUE = \expandafter {\PROPlistparserunvalue}%
      \DEFsearch {\CONSTtag \the \ELEMENT \CONSTprop \PROPlistparsefirst}%
      \ifDEF \PROPlistparserunelement \else \PROPlistparserundo \fi
      \let \PROPlistparsevalue \PROPlistparse}

      \def \PROPlistparserundo {%
        \DEFsearch {\CONSTprop \PROPlistparsefirst}%
        \ifDEF \PROPlistparserundonext \else 
          \VERIFYerrorunrecogattprop \PROPlistparsefirst \fi}
      
        \def \PROPlistparserundonext {%
          \def \PROPlistparsenext {%
            \csname \CONSTprop \PROPlistparsefirst \endcsname}}

      \def \PROPlistparserunelement {%
        \def \PROPlistparsenext {\csname \CONSTtag \the \ELEMENT 
          \CONSTprop \PROPlistparsefirst \endcsname}}
    
      \def \PROPlistparserunspace #1 #2{%
        \edef \NEWpropwhitespaceparsefirst {#1}%
        \expandafter \PROPlistparserunspaceclear #1"\relax %%%
        \ifx \NEWpropwhitespaceparsefirst \CONSTquotmark %%% Fixme: check 
          \let \NEWpropwhitespaceparsefirst \empty \fi %%% apostrophe too
        \edef \NEWpropwhitespaceparsesecond {#2}% 
        \ifx \NEWpropwhitespaceparsesecond \CONSTquotmark %%% Fixme: check 
          \let \NEWpropwhitespaceparsesecond \empty \fi %%% apostrophe too
        \ifx \NEWpropwhitespaceparsesecond \CONSTstopmark 
          \PROPlistparserunspacestop    
        \else \ifx \NEWpropwhitespaceparsetest \CONSTcommaquotmark %%%
          \PROPlistparserunspacestop %%%
          \let \PROPlistparsenext \PROPlistparserunspacegulp %%%
        \else \PROPlistparserunspacedo \fi \fi 
        \PROPlistparsenext}  

        \def \PROPlistparserunspaceclear #1"#2\relax {%
          \edef \NEWpropwhitespaceparsefirst {#1}%
          \edef \NEWpropwhitespaceparsetest {#2}}% %%% %%%
      
        \def \PROPlistparserunspacedo {%
          \edef \PROPlistparserunvalue {%
            \PROPlistparserunvalue \NEWpropwhitespaceparsefirst 
            \CONSTspace \NEWpropwhitespaceparsesecond}%
          \let \PROPlistparsenext \PROPlistparserunspace}
          
        \def \PROPlistparserunspacegulp #1GMS-STOP;{%
          \fi} %%% Fixme: dirty conditional construction
  
        \def \PROPlistparserunspacestop {%
          \edef \PROPlistparserunvalue {%
            \PROPlistparserunvalue \NEWpropwhitespaceparsefirst}%
          \let \PROPlistparsenext \relax}   
  
    \def \PROPlistparsestop {%
      \let \PROPlistparsevalue \relax}
       
% REFERENCE: =================================================================

\new \ifREFERENCEamp

\def \REFERENCEfinish #1{} 

\def \REFERENCEget {{% get special signs in gap content
  \global \GAPsegment = {}%
    \edef \REFERENCEgetprobe {\the \GAP \CONSTampersand}%
    \expandafter \REFERENCEgetdo \REFERENCEgetprobe \empty;%
  \global \GAP = \GAPsegment}}
  
  \bgroup \CATreference
  
  \gldef \REFERENCEgetdo °1&°2°3;{{% parse gap for delimiters "&" and ";":
    \ifOPENpre \let \strut \empty 
      \OBEYspacelines \OBEYnormalspaces \fi
    \edef \REFERENCEgetdothird {°3}%
    \edef \REFERENCEgetdofirst {°1}%
    \ifx \REFERENCEgetdofirst \empty \else \GAPsegmentappend {°1}\fi
    \ifx \REFERENCEgetdothird \empty \else 
      \REFERENCEgetdoamp °2°3&\relax \fi}}
      
    \gldef \REFERENCEgetdoamp °1&°2\relax {%
      \edef \REFERENCEgetdoamptest {°2}%
      \ifx \REFERENCEgetdoamptest \CONSTampersand 
        \REFERENCEgetdoampersand °1 \relax
      \else \REFERENCEgetdocodepage °1;%
         \ifREFERENCEundefined \else 
           \aftergroup \REFERENCEgetdo \fi \fi}
           
      \gldef \REFERENCEgetdoampersand °1 °2\relax {%
        \REFERENCEundelimitedtrue \VERIFYerrorundelimited {°1}%
        \REFERENCEgetdocodepage °1;\GAPsegmentappend {°2}}
        
    % Get a special character by a given reference to the codepage:
    \gdef \REFERENCEgetdocodepage °1°2°3;{% find out the type of reference
      \def \First {°1}%
      \def \Second {°2}%
      \xdef \currentreference {°1°2°3}%
      \ifx \First \CONSThashmark
        \uppercase {\edef \Third {"°3}}%
        \ifx \Second \CONSTx
          \referenceNAMEdouni \Third 
        \else \ifx \Second \CONSTX
          \referenceNAMEdouni \Third
        \else \ifnum °2°3 > 255 \referenceNAMEdouni {°2°3}\else
          \DEFsearch {\CONSTspecific \FONTfamilyuc}\ifDEF
            \REFERENCEnumber {°2°3}\else 
              \referenceNAMEdouni {°2°3}\fi \fi \fi \fi
      \else \referenceNAME {°1}{°2°3}\REFERENCEnumber \fi}
           
  \egroup

\def \REFERENCEnumber #1{% get special char by number (<=255) in codepage
  \ifnum #1 > -1 
    \ifnum #1 < 256 
      \ifnum #1 = 160 \referenceNAMEanbsp 
      \else \GAPsegmentappend {\char #1\REFERENCErelax }\fi %%%
    \else \MESSAGEnotexcharacter {#1}\fi 
  \else \MESSAGEnotexcharacter {#1}\fi}  
  
\let \REFERENCErelax \relax

\new \ifREFERENCEundefined 
    
% referenceNAME: -------------------------------------------------------------
  
  \def \referenceNAME #1#2#3{%
    \edef \myarg {#1#2}% 
    \def \referenceNAMEnumber {#3}%
    \ifx \myarg \CONSTshy \referenceNAMEashy \else
    \ifx \myarg \CONSTemsp \referenceNAMEaemsp \else
    \ifx \myarg \CONSTensp \referenceNAMEaensp \else
    \ifx \myarg \CONSTnbsp \referenceNAMEanbsp \else
    \ifx \myarg \CONSTthinsp \referenceNAMEathinsp \else
    \ifCODEPAGEplain \referenceNAMEtexplain \else 
      \ifCODEPAGEwin \referenceNAMEwindo \else 
        \referenceNAMEget \fi \fi \fi \fi \fi \fi \fi}
      
    % References that are not treated as characters:
    \def \referenceNAMEashy {\GAPsegmentappend \-}
    \def \referenceNAMEaemsp {\GAPsegmentappend {\hskip 1em}}
    \def \referenceNAMEaensp {\GAPsegmentappend {\hskip 1ex}}
    \def \referenceNAMEanbsp {\GAPsegmentappend {% Fixme: used globally
      \penalty 10000 \strut \hbox {\ }}}
    \def \referenceNAMEathinsp {\GAPsegmentappend {\hskip .5ex}}
            
    \def \referenceNAMEdo {%
      \DEFsearch {\CONSTref \myarg }\ifDEF
        \edef \test {"\csname \CONSTref \myarg \endcsname}%
        \expandafter \ifnum \test < 256 
          \expandafter \expandafter \expandafter \referenceNAMEnumber
            \expandafter {\test}%
        \else \referenceNAMEdouni \test \fi
      \else \referenceNAMEdotex \fi}
    
      % Get special char by its name in the codepage:
      \def \referenceNAMEdotex {%
        \DEFsearch {\CONSTplain \myarg }\ifDEF
        \edef \probe {{\FONTcmtext \csname \CONSTplain \myarg \endcsname}}%
          \expandafter \expandafter \expandafter \GAPsegmentappend 
            \expandafter {\probe}%
        \else \VERIFYerrorundefref {\CONSTampersand \myarg;}\fi}
  
      \def \referenceNAMEdouni #1{%
        \ifCODEPAGEwin \DEFsearch {WIN#1}%
          \ifDEF \csname WIN#1\endcsname
          \else \referenceNAMEdouninum {#1}\fi
        \else \referenceNAMEdouninum {#1}\fi}

        % Get special char by number (>255) in codepage:
        \def \referenceNAMEdouninum #1{{%
          % Fixme: redundance with \FONTchoose \useFONT in font.tex.
          % Fixme: Set Unicode data: catcode, lccode, uccode
          \ifnum #1 = 160 \referenceNAMEanbsp \else
            \edef \first {#1}%
            \UNICODEslotset \first \UNICODEpointindexset \first
            \DATAhexinput = \UNICODEslot \DATAhexoutput = {}\DATAhex
            \expandafter \expandafter \expandafter \DATAlengthget
              \expandafter {\the \DATAhexoutput}%
            \let \leading \empty
            \ifnum \DATAlength = 3 \def \leading {0}\else
              \ifnum \DATAlength = 2 \def \leading {00}\else
                \ifnum \DATAlength = 1 \def \leading {000}\fi \fi \fi  
            \DATAhexinput = \first   
            \ifnum \DATAhexinput < "A0 \else
              \edef \CODEPAGE {G\leading \the \DATAhexoutput}\fi
            \ifFONTbold \edef \MAPisbold {1}\else 
              \edef \MAPisbold {0}\fi
            \ifFONTitalic \edef \MAPisitalic {1}\else 
              \edef \MAPisitalic {0}\fi
            \edef \somefontname {\CONSTfonthyphen \CODEPAGE
              -\FONTfamilyuc -\MAPisbold -\MAPisitalic}%
            \DEFsearch \somefontname
            \ifDEF \glet \next \relax \else 
              \referenceNAMEdouninumfallget \fi
            \DEFsearch \somefontname 
            \ifDEF \next \referenceNAMEdouninumfont
            \else \DEFsearch {\CONSTplain \currentreference }\ifDEF
              \referenceNAMEdouninumfallback 
              \else \expandafter \VERIFYerrorlost \first \relax \fi \fi \fi}} 
            
          \def \referenceNAMEdouninumfallback {%
           \VERIFYerrorfallbackname \currentreference
           \GAPsegmentappend {{\FONTcmtext \csname \CONSTplain
           \currentreference \endcsname}}}
         
          \def \referenceNAMEdouninumfallget {%
            \edef \somefontname {\CONSTfonthyphen \CODEPAGE
             -\FONTfallbackuc -\MAPisbold -\MAPisitalic}%
            \gdef \next {\expandafter \VERIFYerrorfallback \first \relax}} 
          
          \def \referenceNAMEdouninumfont {%
            \edef \probe {{{\font \FONT = 
              \csname \somefontname \endcsname \CONSTat \SIZEcurrent 
              \FONT \char \number \UNICODEpointindex}}}%
            \expandafter \expandafter \expandafter \GAPsegmentappend
              \expandafter {\probe}} 
            
    \gdef \referenceNAMEget {%
      \DEFsearch {\CONSTref \myarg }\ifDEF \referenceNAMEdo
      \else \VERIFYerrorundefref {\CONSTampersand \myarg;}\fi}
  
    \def \referenceNAMEtexplain {%
      \DEFsearch {\CONSTplain \myarg }\ifDEF
        \expandafter \expandafter \expandafter \GAPsegmentappend 
          \expandafter {\csname \CONSTplain \myarg \endcsname}%
      \else \VERIFYerrorundefref {\CONSTampersand \myarg;}\fi}  
    
    \def \referenceNAMEwindo {%
      \DEFsearch {\CONSTwin \myarg }\ifDEF
        \edef \test {"\csname \CONSTwin \myarg \endcsname}%
          \expandafter \expandafter \expandafter \referenceNAMEnumber 
            \expandafter {\test}%
      \else \referenceNAMEdo \fi}
      
% SCRIPT: ====================================================================

\def \SCRIPTcheck #1#2{%
  \ifx \SCRIPTtest #1\let \SCRIPTnext #2\fi}

\def \SCRIPTend {%
  \csname \CONSTtag /\CONSTscript \endcsname \shredder}

\def \SCRIPThandle {% Fixme: does not work within tables due to backup mode
  \ifx \SCRIPTtype \CONSTtextTeX \MESSAGEobjectTeX
    \endmarkupCAT \tenrm \parindent = 20pt
    \ifx \URLhref \empty \else 
      \FILEsearch \URLhref \ifFILEexist
        \bgroup \let \end \relax \input \URLhref \relax \egroup 
       \else \VERIFYerrorabsent \URLhref \fi \fi
  \else \SCRIPTothertrue \LINKunrenderedtrue 
    \CATwhitespacegt 
    \CATwhitespaceslash % % Fixme: word 'script' fools '</script>' tag
  \fi}

\def \SCRIPTinit {%
  \let \SCRIPTtype \empty
  \let \URLhref \empty}

\ldef \SCRIPTparse #1 {%
  \lowercase {\edef \SCRIPTtest {#1}}%
  \let \SCRIPTnext \SCRIPTparse 
  \SCRIPTcheck \CONSTscript \SCRIPTend % fooled by word "script" in scripts
  \SCRIPTcheck \CONSTendscript \SCRIPTend
  \SCRIPTcheck \CONSTendcommentendscript \SCRIPTend
  \SCRIPTcheck \CONSTendcomment \shredder
  \SCRIPTnext}
  
\def \SCRIPTset {%
  \edef \SCRIPTtype {\CONSTtext /\the \VALUE}}
           
% SHEET: =====================================================================

% Access CSS style sheet:

\let \SHEETlast \empty

\def \SHEETload {%
  \ifx \LINKmedia \empty \let \SHEETnext \SHEETloaddo \else
    \ifx \LINKmedia \CONSTprint \let \SHEETnext \SHEETloaddo \fi \fi}
    
  % Fixme: better done in \FILEnameget with respect to relative paths:
  \def \SHEETloaddo {%
    \URLinternetfalse
    \expandafter \URLgetinternet \URLhref ://\relax
    \expandafter \URLgetrelative \URLhref ://://\relax
    \let \CHAINfolderbackup \CHAINfoldercurrent
      \let \CHAINfoldercurrent \empty
      \SHEETloaddoanyinternet
      \SHEETloaddoanyfile
      \SHEETloaddoany \SHEETloaddoempty \relax % if ".css" missing
      \SHEETloaddoany \SHEETloaddorelax \SHEETloaddoparse
    \glet \CHAINfoldercurrent \CHAINfolderbackup
    \global \CSSaddedfalse}
  
    \def \SHEETloaddoany #1#2{%
      \ifx \SHEETloadtest \empty #1\else 
        \let \SHEETloadnext #2\fi \SHEETloadnext}
        
    \def \SHEETloaddoanyfile {%
      \ifFILEexist \glet \SHEETnew \SHEETloadprobe \fi
      \let \SHEETloadtest \empty \SHEETloadfile}

    \def \SHEETloaddoanyinternet {%
      \ifURLinternet 
        \let \SHEETloadnext \SHEETloaddoanyinternetone
      \else \let \SHEETloadnext \SHEETloaddoanyinternettwo \fi
      \SHEETloadnext}
  
      \def \SHEETloaddoanyinternetone {%
        \let \FILEname \empty
        \let \FILEpath \empty
        \let \FILEsourcelast \empty 
        \edef \SHEETloadprobe {../\URLhref /}%
        \expandafter \FILEnamegetsourceparse \SHEETloadprobe \relax
        \let \SHEETloadprobe \FILEname}

      \def \SHEETloaddoanyinternettwo {%
        \OPENobjecttrue
          \CHAINfile \URLhref
          \CHAINloadnextfalse 
        \OPENobjectfalse
        \edef \SHEETloadprobe {.\CHAINfoldercurrent /\chainNEXTfile}}
    
    \def \SHEETloaddoempty {%
      \global \advance \verifyWELLFORMtotalfile by -1 
        % compensation if loaded twice
      \edef \SHEETloadprobe {\SHEETloadprobe .css}%
      \let \SHEETloadnext \SHEETloadfile}

      \def \SHEETloadfile {%
        \ifx \SHEETlast \SHEETnew \else \SHEETloadfiledo \fi}

        \def \SHEETloadfiledo {%
          \glet \SHEETlast \SHEETnew
          \verifyWELLFORMtotalfileadvance 
          \ifFILEtoomany \else \SHEETloadfiledoit \fi}

          \def \SHEETloadfiledoit {%
            \message {(\SHEETloadprobe)}%
            \openin \FILEplaintext = \SHEETloadprobe \relax
            \loop \FILEcheckeof \FILEplaintext
              \ifFILEnotended \read \FILEplaintext to \myline
              \edef \SHEETloadtest {\SHEETloadtest \myline}%
            \repeat \closein \FILEplaintext}
                        
    \def \SHEETloaddoparse {%
      \CSSget \SHEETloadtest}

    \def \SHEETloaddorelax {%
      \let \SHEETloadnext \relax}
    
\let \SHEETnext \empty

\def \SHEETstylebegin {%
  \let \LINKmedia \empty}

\def \SHEETstyleclear {% 
  \ifCSSadded \glet \SHEETlast \empty \fi}
    
\def \SHEETstyleend {%
  \ifx \LINKmedia \CONSTscreen \else
    \SHEETstyleclear
    \edef \expandedGAP {\the \GAP}%
    \CSSget \expandedGAP \GAP = {}\fi}    
         
% SIZE: ======================================================================

\ned \SIZE

\nec \SIZEbase 

  \def \SIZEbaseadvance #1{%
    \ifnum \SIZEbase < 7 \advance \SIZEbase by #1\fi}

  \def \SIZEbasediminish #1{%
    \ifnum \SIZEbase > 1 \advance \SIZEbase by -#1\fi}

\def \SIZEbaselarger {%
  \SIZEbaseadvance 1 }

\def \SIZEbaseset {% Fixme: needs lowercase
  \SIZEbase = \the \VALUE}

\def \SIZEbasesmaller {%
  \SIZEbasediminish 1 }  
  
\def \SIZEchange #1{% Get default font size:
  \lowercase {\edef \SIZEchangetest {#1}}%
  \ifx \SIZEchangetest \CONSTlarger \SIZEbaselarger \else
  \ifx \SIZEchangetest \CONSTsmaller \SIZEbasesmaller \else
  \ifx \SIZEchangetest \CONSTxxlarge \SIZEbase = 6 \else
  \ifx \SIZEchangetest \CONSTxlarge \SIZEbase = 5 \else
  \ifx \SIZEchangetest \CONSTlarge \SIZEbase = 4 \else
  \ifx \SIZEchangetest \CONSTmedium \SIZEbase = 3 \else
  \ifx \SIZEchangetest \CONSTsmall \SIZEbase = 2 \else
  \ifx \SIZEchangetest \CONSTxsmall \SIZEbase = 1 \else
  \ifx \SIZEchangetest \CONSTxxsmall \SIZEbase = 0 \else
    \VALUEdimenset \SIZE \SIZE
  \fi \fi \fi \fi \fi \fi \fi \fi \fi
  \KERNINGcheck \KERNINGdonefalse} % Fixme: time bandit
  
\ned \SIZEcurrent

\new \ifSIZEgiven 

% Magnification:
% The font size can be set via <basefont size="n"> (deprecated) with n=1 to 7,
% 3 = medium, using CSS2 magnification steps (scaling factor = 1.2).
% This should be done if <big>, <small>, <basefont size="n"> or
% <font size="n"> are executed: 

\def \SIZEmagnify {%
  \divide \SIZEcurrent by \CONSTnumbermedium
  \ifcase \SIZEbase 
    \SIZEtempo = \CONSTnumberxxsmall \or % 0
    \SIZEtempo = \CONSTnumberxsmall \or % 1
    \SIZEtempo = \CONSTnumbersmall \or % 2
    \SIZEtempo = \CONSTnumbermedium \or % 3
    \SIZEtempo = \CONSTnumberlarge \or % 4
    \SIZEtempo = \CONSTnumberxlarge \or % 5
    \SIZEtempo = \CONSTnumberxxlarge \or % 6
    \SIZEtempo = \CONSTnumberxxxlarge \or % 7
    \SIZEtempo = \CONSTnumberxxxxlarge % 8
  \else \SIZEmagnifydo \fi 
  \multiply \SIZEcurrent by \SIZEtempo}
  
  \def \SIZEmagnifydo {%
    \ifnum \SIZEbase < 0 \SIZEtempo = \CONSTnumberxxxsmall
    \else \SIZEtempo = \CONSTnumberxxxxxlarge \fi}  

\def \SIZEset {%
  \VALUEset \SIZEsetnew 
  \ifx \SIZEsetold \SIZEsetnew \else
    \let \SIZEsetold \SIZEsetnew 
    \SIZEchange {\the \VALUE}\SIZEgiventrue \fi}
    
  \let \SIZEsetnew \empty
  \let \SIZEsetold \empty
    
\def \SIZEswitch #1{%
  \edef \SIZEswitchtest {#1}%
  \ifx \SIZEswitchtest \CONSTnumberone \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumbertwo \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumberthree \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumberfour \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumberfive \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumbersix \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumberseven \SIZEbaseset \else
  \ifx \SIZEswitchtest \CONSTnumberpone \SIZEbaseadvance 1\else
  \ifx \SIZEswitchtest \CONSTnumberptwo \SIZEbaseadvance 2\else
  \ifx \SIZEswitchtest \CONSTnumberpthree \SIZEbaseadvance 3\else
  \ifx \SIZEswitchtest \CONSTnumberpfour \SIZEbaseadvance 4\else
  \ifx \SIZEswitchtest \CONSTnumbermone \SIZEbasediminish 1\else
  \ifx \SIZEswitchtest \CONSTnumbermtwo \SIZEbasediminish 2\else
  \ifx \SIZEswitchtest \CONSTnumbermthree \SIZEbasediminish 3\else 
    \VERIFYerrorinvalidsize {#1}%
  \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi}

  \nec \SIZEtempo
  \nec \SIZEtempotwo

% SPAN: ======================================================================
  
% Fixme: "rowspan" attribute must be handled before "class"
  
% Fixme: If attributes and properties were scanned before "executing" tags,
% table layout information like row- and colspans would be accessible easier.

\def \SPANcol {\CONSTnumberone}

\def \SPANcolnoadvance {%
  \advance \NOcol by 1 }
    
\def \SPANcolexecdo {%
  \xDef {\CONSTcolwidth 
    \the \TABLEnesting.\the \NOcol} {\the \SPANcolgroupwidth}}
        
\def \SPANcollast {0}

\new \ifSPANcolgiven

\def \SPANcolgroupexec {%
  \ifx \SPANcol \empty \else \SPANcolgroupexecdo \MESSAGEcolspan \fi}
  
  \def \SPANcolgroupexecdo {{%
    \ifTABLEcolspan \ifnum \SPANcol > 0
      \divide \hsize by \SPANcol
      \xdef \SPANcolgroupwidth {\the \hsize}\fi \fi}}

\def \SPANcolgroupinit {%
  \glet \SPANcol \empty
  \global \TABLEcolspanfalse 
  \NOcol = 0 }
  
\def \SPANcolgroupset {%
  \global \TABLEcolspantrue \VALUEintegerget
  \xdef \SPANcol {\VALUEinteger}}

\let \SPANcolgroupwidth \empty

\def \SPANcolpost #1{% 
  \VALUEintegerget
  \ifnum \VALUEinteger > 0
    \xdef \NOcollast {\the \NOcol}%
    \global \advance \NOcol by -1      
    \global \advance \NOcol by \VALUEinteger 
    \multiply #1 by \VALUEinteger   
    \xdef \SPANcollast {\VALUEinteger}\fi}   

\def \SPANcolpre #1{%
  \DEFsearch {TCOLS\the \NOtable}\ifDEF
    \edef \SPANcolpretest {%
      \csname TCOLS\the \NOtable \endcsname}%
    \ifx \SPANcolpretest \empty \else
      \SPANcolpredefault = \SPANcolpretest \fi \fi
  \ifx \SPANcol \empty \divide #1 by \SPANcolpredefault 
  \else \divide #1 by \SPANcol \fi}
  \nec \SPANcolpredefault

\def \SPANlayout {% Fixme: flatten
  \DEFsearch {TCOLS\the \NOtable}\ifDEF
    \edef \SPANlayouttest {%
      \csname TCOLS\the \NOtable \endcsname}%
    \ifx \SPANlayouttest \empty \else
      \message {- \SPANlayouttest}%
      \ifx \SPANlayouttest \CONSTnumberone 
        \message {col,}\else \message {cols,}\fi \fi \fi
  \DEFsearch {TROWS\the \NOtable}\ifDEF
    \edef \SPANlayouttest {%
      \csname TROWS\the \NOtable \endcsname}%
    \ifx \SPANlayouttest \empty \else
      \message {\SPANlayouttest}%
      \ifx \SPANlayouttest \CONSTnumberone 
        \message {row}\else \message {rows}\fi \fi \fi}
        
\def \SPANrowclear {%
  \count 8 = 0
  \loop \ifnum \count 8 < \BACKUPtdmax
    \advance \count 8 by 1
    \xDef {attSPANrowspan\the 
      \TABLEnesting .\the \count 8 } {0}% Fixme: \empty
    \xDef {\CONSTcolwidth \the \TABLEnesting .\the \count 8 } \empty
  \repeat}

\def \SPANrowhfill {%
  \ifSPANrowspangiven \hfill \hfill \fi \par}

\def \SPANrowpost #1#2{% 
  \ifnum \NOcollast > 0 \global \advance \NOcol by -1 \fi
  \global \SPANrowspangiventrue \SPANrowspangivenheretrue
  \ifx \SPANcolgroupwidth \empty #1\else \SPANcolexecdo \fi   
 {\VALUEintegerget
  \NOrowspan = \VALUEinteger
  \advance \NOrowspan by \NOrow 
  \xDef {attSPANrowspan\the \TABLEnesting .\the \NOcol} {\the \NOrowspan}}%
  \let #2\vss}

\def \SPANrowpre #1{%
  \MESSAGEtdcol
  \DEFsearch {attSPANrowspan\the \TABLEnesting .\the \NOcol }\ifDEF
    \edef \test {\csname 
      attSPANrowspan\the \TABLEnesting .\the \NOcol \endcsname}%
    \count 7 = \NOrow
    \advance \count 7 by -\test
    \edef \test {\the \count 7 }%
    \ifnum \test < 0
      \DEFsearch {\CONSTcolwidth \the \TABLEnesting .\the \NOcol }\ifDEF 
        \edef \test {\csname 
          \CONSTcolwidth \the \TABLEnesting .\the \NOcol \endcsname}%
          \ifSPANrowspangivenhere \else      
            \ifx \test \empty 
             {% Fixme: colspan gets lost
              \divide #1 by \BACKUPtdmax
              \multiply #1 by \SPANcollast % Fixme: too simple
              \hskip #1}\MESSAGEhyphen
            \else \hskip \test \MESSAGEhyphen \fi
            \global \advance \NOcol by 1
            \SPANrowpre {#1}\fi 
      \else {\divide #1 by \BACKUPtdmax 
        \hskip #1}\fi \fi \fi}% recursion

\def \SPANrowrest {%
  \ifnum \TABLEnesting = 1 \SPANrowspangivenfalse \fi}

\new \ifSPANrowspangiven
\new \ifSPANrowspangivenhere

% TABLE: =====================================================================

\def \TABLEbegin #1{%
  \ifhmode \hss \par \LINEupskip \fi % Fixme: may cause overlap
  \vbox \bgroup \moveright #1%
  \hbox \bgroup \raise \LINEheight
  \vtop \bgroup \vskip \MARGIN % align cells of different heights
  \hbox \bgroup \hskip \MARGIN
  \ifdim \BORDER > 0mm \BORDERupdate \fi
  \BORDERprofiledraw \CONSTbegin \CONSTtable
  \PADDINGbegin \vbox \bgroup}

\new \ifTABLEcolspan

\def \TABLEend {%
  \egroup \PADDINGend 
  \BORDERprofiledraw \CONSTend \CONSTtable
  \hskip \MARGIN \egroup
  \vskip \MARGIN \egroup \egroup \egroup}

\def \TABLEendhandle {%
  \ifOPENtable \hfill \TABLEend \fi}

\def \TABLEinit {%
  \OPENtdfalse \OPENthfalse \OPENtrfalse
  \OPENtbodyfalse \OPENtfootfalse \OPENtheadfalse 
  \OPENfontinnerfalse \SPANrowspangivenfalse
  \TABLEnoadvance \MESSAGEtablenest \NOrow = 0
  \let \TABLEalign \CONSTcenter
  \ifOPENp \else \TEXTindent = 0mm \fi 
  \ifnum \TABLEnesting = 1 \global \TABLEswap = 0mm \fi
  \TABLEheight = 0mm 
  \let \BORDERprofile \empty
  \BORDERreset   
  \let \SPANcol \empty}
  
\new \ifTABLEinter

\ned \TABLEheight

\nec \TABLEnesting 

\def \TABLEnestingadvance {% 
  \advance \TABLEnesting by 1 }

\def \TABLEnoadvance {%
  \global \advance \NOtable by 1 }

\new \ifTABLEnobreak

\def \TABLEsplit #1{%
  \ifTABLEnobreak \else \ifSPANrowspangiven \else
    \ifOPENthead \else \ifOPENtbody 
      \else \ifOPENtfoot \else 
      \ifnum \TABLEnesting = 1
        \ifnum \NOrow > 1 % minimal split rows 
          \TABLEsplitinter #1\fi \fi \fi \fi \fi \fi \fi}
            
  % imitate \TABLEend and \TABLEbegin for page break:
  \def \TABLEsplitinter #1{% 
    \xdef \interNOrow {\the \NOrow}%
    \xdef \interhsize {\the \hsize}%
    \egroup
    \global \TABLEintertrue
    \PADDINGend 
    \BORDERprofiledraw \CONSTend \CONSTtable
    \hskip \MARGIN \egroup \egroup \egroup \egroup
    \vbox \bgroup 
    \LINEheight = 0pt 
    \moveright #1\hbox \bgroup
    \vtop \bgroup
    \hbox \bgroup \hskip \MARGIN
    \ifdim \BORDER > 0mm \BORDERupdate \fi
    \BORDERprofiledraw \CONSTbegin \CONSTtable
    \PADDINGbegin 
    \global \TABLEinterfalse
    \vbox \bgroup
    \NOrow = \interNOrow
    \hsize = \interhsize}
            
\def \TABLEsplitset {%
  \VALUEset \test 
  \ifx \test \CONSTavoid \TABLEnobreaktrue \fi}

\let \TABLEsummary \empty

\def \TABLEsummarycheck {%
  \ifx \TABLEsummary \empty \VERIFYerrorempty \CONSTsummary \fi}
  
\def \TABLEsummaryset {%
  \edef \TABLEsummary {\the \VALUE \relax }\MESSAGEvalue}
  
\ned \TABLEswap

\def \TABLEswapdo #1#2{%
  \ifOPENp
    \ifnum \TABLEnesting = 1
      #1\else
        \ifdim #2 > \LINEheight
          \global \advance \TABLEheight by #2\fi \fi
    \else \global \advance \TABLEswap by #2%
      \global \advance \TABLEswap by \LINEheight \fi \fi} 

% TAG: =======================================================================

% A document is composed of declarations, elements, comments, references,
% and instructions, all of which are indicated by markup.
% The markup input looks like this: ...<tag x>gap x<tag y>gap y<tag z>...
% Thus, it can be 'shreddered' into a sequence of tags and gaps.
% A tag is thought to be of the form "<element attributelist>".

\net \TAG

\ldef \TAGget #1>{%
  \TAG = {#1}\TAGgetdo #1 >\CATactivelessthan
  \ifnum \TAGstarted = 0 \TAGgetstart \fi
  \ATTunquotedmessagefalse
  \ifGAPobey \OBEYobeyspacesandlines \fi
  \tagCHECK}

  \ldef \TAGgetdo #1#2 #3>{% 
    \lowercase {\ELEMENT = {#1#2}}%
    \edef \TAGfirst {#1}%
    \def \TAGfirstsecond {#1#2}%
    \def \TAGsecond {#2}%
    \def \TAGlast {#3}%
    \ATTlist = {#3}%
    \let \TAGgetdonext \TAGgetdoexec
    \tagCOMMENTcheck \TAGfirstsecond \TAGlast \TAGgetdonext % three args
    \ifOPENobject \ifOPENtable \else \BACKUPpush \TAGgetdonext \fi
      \else \BACKUPpush \TAGgetdonext \fi
    \TAGgetdonext}        

    \def \TAGgetdoexec {%
      \ifx \TAGlast \empty \ATTfalse \else \ATTtrue \fi
      \PROPfalse
      \DEFsearch {\CONSTtag \the \ELEMENT}%
      \ifDEF \TAGgetdoexecdo \else 
        \expandafter \TAGgetdoexechtml \the \ELEMENT %%%
          \empty \empty \empty \empty \relax \fi %%%
      \TAGgetdoexecnext}

      % Detect <html:xxx> and <?xml...> tags % 2007/03/08
      \lowercase {\def \TAGgetdoexechtml #1#2#3#4#5#6\relax {% 
        \edef \TAGgetdoexechtmlrest {#2#3#4#5#6}%       
        \edef \TAGgetdoexechtmlsix {#6}%  
        \edef \TAGgetdoexechtmltwofour {#2#3#4}% 
        \ifx \TAGgetdoexechtmltwofour \CONSTxml
          \let \TAGgetdoexechtmlsix \CONSTxml \fi % skip \empty test
        \ifx \TAGgetdoexechtmlsix \empty 
          \TAGgetdoexecdonot 
        \else 
          \DEFsearch {\CONSTtag #6}%
          \ifDEF \def \TAGgetdoexecnext {%
            \csname \CONSTtag \TAGgetdoexechtmlsix \endcsname}%
            \ELEMENT = \expandafter {\TAGgetdoexechtmlsix}% %%%
          \else 
            \DEFsearch {\CONSTtag \TAGgetdoexechtmlrest}%
            \ifDEF \def \TAGgetdoexecnext {%
              \csname \CONSTtag \TAGgetdoexechtmlrest \endcsname}%
              \ELEMENT = \expandafter {\TAGgetdoexechtmlrest}% %%%
            \else \TAGgetdoexecdonot \fi \fi \fi}}
 
      \def \TAGgetdoexecdo {%
        \def \TAGgetdoexecnext {\csname \CONSTtag \the \ELEMENT \endcsname}}

      \def \TAGgetdoexecdonot {%
        \ifx \TAGfirst \CONSTexclamation
          \def \TAGgetdoexecnext {%
            \TAGgetdoexecdonotexclam \TAGsecond \TAGlast}% <! ...
        \else \def \TAGgetdoexecnext {%
          \TAGgetdoexecdonotquest \TAGfirst \TAGgetdoexecdonotrecognize}\fi}
          
          % Do not execute tag if it starts with exclamation or question mark:
          \def \TAGgetdoexecdonotexclam #1#2{% <! ...
            \let \TAGgetdoexecdonotexclamnext \relax
            \ifx #1\CONSTdoublehyphen \TAGgetdoexecdonotexclamhyphen #2%
            \else \ifx #1\CONSTdoctype 
              \verifyDOCTYPEget #2\fi \fi 
            \TAGgetdoexecdonotexclamnext}

            \def \TAGgetdoexecdonotexclamhyphen #1{% <!-- ...
              \ifOPENstyle \TAGgetdoexecdonotexclamstyle #1\fi}

              \def \TAGgetdoexecdonotexclamstyle #1{%
                \ifx \LINKmedia \CONSTscreen \else 
                  \def \TAGgetdoexecdonotexclamnext {\CSSget #1}\fi}
                  
          \def \TAGgetdoexecdonotquest #1#2{% <? ...
            \ifx #1\CONSTquotation \relax % <? ...
              \ifOPENbody \GAPwrite \fi
            \else #2\GAPwrite \fi}   
            
        \def \TAGgetdoexecdonotrecognize {%
          \ifx \TAGfirst \CONSTslash
            \ifx \TAGsecond \empty \else \Message {\TAGfirst \TAGsecond}\fi
          \else \VERIFYerrorunrecognized {\TAGfirst \TAGsecond}\fi}

  \def \TAGgetstart {%
    \beginmarkupCAT \nonstopmode \global \TAGstarted = 1 }

\nec \TAGstarted

% tagCHECK: ------------------------------------------------------------------

  \def \tagCHECK {%
    \ifEND \tagCHECKobject \else \tagCHECKchain \fi
    \tagCHECKnext}

    \def \tagCHECKchain {%
      \ifCHAINloadnext \tagCHECKchaininput \else \tagCHECKchainscript \fi}

      \def \tagCHECKchaininput {%
        \ifOPENobject \tagCHECKchaininputdo \else
          \ifnum \NOinput < 2 \tagCHECKchaininputdo 
          \else \tagCHECKrelax \fi \fi}
        
        \def \tagCHECKchaininputdo {%
          \def \tagCHECKnext {\CHAINget \VERIFYwellformedness}}
    
      \def \tagCHECKchainscript {%
        \ifOPENscript \tagCHECKchainscriptother 
        \else \tagCHECKchainscriptgap \fi}
      
        \def \tagCHECKchainscriptgap {%
          \CATactivelessthan 
          \let \tagCHECKnext \GAPget} 

        \def \tagCHECKchainscriptother {%
          \ifSCRIPTother \tagCHECKchainscriptotherdo 
          \else \tagCHECKchainscriptothernone \fi}
        
          \def \tagCHECKchainscriptothernone {%
            \tagCHECKrelax 
            \ifx \SCRIPTtype \CONSTtextTeX
              \ifx \LINKhref \empty \CATotherlessthan \fi \fi}
        
          \def \tagCHECKchainscriptotherdo {%
            \endmarkupCAT \beginscriptCAT
            \let \tagCHECKnext \SCRIPTparse} 

    \def \tagCHECKobject {%
      \ifOPENobject \tagCHECKrelax \else \tagCHECKobjectend \fi}  

      \def \tagCHECKobjectend {%
        \let \tagCHECKnext \VERIFYwellformedness}

    \def \tagCHECKrelax {%
      \let \tagCHECKnext \relax} 
  
% tagCOMMENT: ----------------------------------------------------------------

\new \iftagCOMMENT

\new \iftagCOMMENTbegun

  \def \tagCOMMENTcheck #1#2#3{%   
    \expandafter \tagCOMMENTcheckdo #1\empty \empty \empty \relax 
    \iftagCOMMENT \expandafter \tagCOMMENTcheckparse #2--\relax #3\fi} 
        
    \ldef \tagCOMMENTcheckdo #1#2#3#4\relax {%
      \edef \tagCOMMENTbegintest {#1#2#3}%
      \ifx \tagCOMMENTbegintest \CONSTcommentbegin
        \tagCOMMENTtrue \tagCOMMENTbeguntrue \tagCOMMENTfinishedfalse
        \tagCOMMENTcheckdofinish #4-\relax
      \else \tagCOMMENTfalse \fi} % Fixme: one cannot say this here
    
      \ldef \tagCOMMENTcheckdofinish #1-#2\relax {%
        \edef \tagCOMMENTcheckdofinishtest {#2}%
        \ifx \tagCOMMENTcheckdofinishtest \CONSTdoublehyphen
          \tagCOMMENTfinishedtrue \tagCOMMENTbegunfalse \fi}
        
    \ldef \tagCOMMENTcheckparse #1--#2\relax #3{%   
      \edef \tagCOMMENTsecond {#2}%
      \ifBACKUP \else \ifBACKUPpop \else \GAPwrite \fi \fi
      \ifx \tagCOMMENTsecond \CONSTcommentend \tagCOMMENTcheckparsestop #3%
      \else \def \tagCOMMENTfirst {#1}%
        \ifx \tagCOMMENTsecond \empty
          \ifx \tagCOMMENTfirst \empty 
            \iftagCOMMENTfinished \else \let #3\tagCOMMENTcheckparsedummy \fi 
          \else \let #3\tagCOMMENTcheckparsedummy \fi 
        \else \ifOPENstyle \else \ifOPENscript \else  
          \tagCOMMENTcheckparsedo #3\fi \fi \fi \fi}     

      \def \tagCOMMENTcheckparsedo #1{%   
        \ifx \tagCOMMENTfirst \empty
          \iftagCOMMENTfinished \let #1\tagCOMMENTcheckparsefinished
          \else \let #1\tagCOMMENTcheckparsedofinish \fi 
        \else \ifx \tagCOMMENTsecond \empty 
          \let #1\tagCOMMENTcheckparsedofinish \fi \fi} 
        
        \ldef \tagCOMMENTcheckparsedofinish #1-->{%
          \tagCOMMENTcheckparsefinished}
        
      \ldef \tagCOMMENTcheckparsedummy #1-->{% 
        \tagCOMMENTcheckparsefinished \GAPget}% for <tag> inside comment    

      \def \tagCOMMENTcheckparsefinished {%
        \tagCOMMENTbegunfalse \tagCOMMENTfinishedtrue \tagCOMMENTfalse 
        \beginmarkupCAT \shredder}
      
      \def \tagCOMMENTcheckparsestop #1{%
        \tagCOMMENTfinishedtrue \tagCOMMENTbegunfalse
        \ifOPENstyle \else \ifBACKUP \else 
          \let #1\GAPwrite \fi \fi}

\def \tagCOMMENTend #1{%
  \expandafter \tagCOMMENTenddo #1\empty \empty \empty \relax}

  \ldef \tagCOMMENTenddo #1#2#3#4\relax {%
    \edef \tagCOMMENTenddotest {#1#2#3}%
    \ifx \tagCOMMENTenddotest \CONSTendcomment
      \tagCOMMENTfalse \tagCOMMENTbegunfalse \tagCOMMENTfinishedtrue \fi}

\new \iftagCOMMENTfinished    
   
% UNICODE: ===================================================================

% Every known character on earth shall be given a unique code number,
% usally expressed in hexadecimal form, with digits running 0 to 9
% and from A to F. The data of (at most) 256 characters is defined in
% slot files (UXXXX.dat), which are excerpts of the unicode database
% files like UnicodeData.txt.
% - The slot file format is: < 1) unicode point, four hexadecimal
% digits; 2) unicode character name; 3) general category;
% 4) canonical combining classes; 5) bidirectional category;
% 6) character decomposition mapping; 7) decimal digit value;
% 8) digit value; 9) numeric value; 10) mirrored; 11) unicode
% character name, version 1.0; 12) ISO 10646 comment field;
% 13) uppercase mapping; 14) lowercase mapping; 15) titlecase
% mapping >.
% - Only columns 1, 3, 13 and 14 are needed for Markup Shredder. With
% exception of U0000.dat, columns 2, 11 and 12 may be deleted in the
% slot files in order to reduce their sizes by 50 percent. If you
% want to know the character names, for instance, or if you need more
% slots for other alphabets, please have a look at the source files
% (http://www.unicode.org/Public/UNIDATA/UnicodeData.txt and others).

\ldef \UNICODEadd #1#2.#3 {% add unicode data slot file to UNICODEslots list
  \def \second {#2}%
  \ifx \second \empty \else
    % Count slots:
      \advance \UNICODEnumberofslots by 1
    % Get decimal representation of #2:
       \uppercase {\UNICODEslot = "#2}%
    % Get base register of unicode slot:
      \UNICODEslotregbase = 128
      \advance \UNICODEslotregbase by -\UNICODEnumberofslots
      \multiply \UNICODEslotregbase by 256
    % Build item:
      \uppercase {\edef \myitem {%
        [\the \UNICODEnumberofslots]
        [#2]
        [\the \UNICODEslot]
        [\the \UNICODEslotregbase] }}%
    % Build list:
      \expandafter \DATAarrayfour \myitem \DATAarrayafter \UNICODEslots \fi}
  \ifx \eTeXversion \undefined \ldef \UNICODEadd #1#2.#3 {}\fi
  
\nec \UNICODEcat

\net \UNICODEdata
\UNICODEdata = {0;0;0;0.0pt;0.0pt;0;0;;} % "pt" means "protruding" here

\ldef \UNICODEdataget
  #1;% catcode
  #2;% lccode
  #3;% uccode
  #4;% lpcode roman/italic
  #5;% rpcode roman/italic
  #6;% codepage name
  #7;% codepage index
  #8;% entity name 
  #9%  glyph name
\relax {%
  \UNICODEcat = #1
  \UNICODElc = #2
  \UNICODEuc = #3
  \UNICODElp = #4
  \UNICODErp = #5
  \CODEPAGEname = \expandafter {#6}
  \CODEPAGEindex = #7
  \UNICODEentityname = \expandafter {#8}%
  \UNICODEglyphname = \expandafter {#9}}

\ldef \UNICODEdataset 
  #1;% catcode
  #2;% lccode
  #3;% uccode
  #4;% lpcode roman.italic
  #5;% rpcode roman.italic
  #6;% codepage name
  #7;% codepage index
  #8;% entity name 
  #9%  glyph name
\relax {%
  \expandafter \UNICODEdataget \the \UNICODEdata \relax
  \if #1-\else \UNICODEcat = #1\fi
  \if #2-\else \UNICODElc = #2\fi
  \if #3-\else \UNICODEuc = #3\fi
  \if #4-\else \UNICODElp = #4\fi
  \if #5-\else \UNICODErp = #5\fi
  \if #6-\else \CODEPAGEname = \expandafter {#6}\fi
  \if #7-\else \CODEPAGEindex = #7\fi
% \if fails for names like aa... or cc...:
  \edef \eighth {#8}%
  \ifx \eighth \CONSThyphen \else \UNICODEentityname = \expandafter {#8}\fi
  \edef \ninth {#9}%
  \ifx \ninth \CONSThyphen \else \UNICODEglyphname = \expandafter {#9}\fi
  \edef \myUNICODEdata {%
    \the \UNICODEcat;%
    \the \UNICODElc;%
    \the \UNICODEuc;%
    \the \UNICODElp;%
    \the \UNICODErp;%
    \the \CODEPAGEname;%
    \the \CODEPAGEindex;%
    \the \UNICODEentityname;%
    \the \UNICODEglyphname}%
  \UNICODEdata = \expandafter {\myUNICODEdata}}
    
\net \UNICODEentityname

\def \UNICODEget {%
  \UNICODEslotregbaseset {\the \UNICODEslotpointreg}% 
  \UNICODEdata = \expandafter {\the \toks \UNICODEslotpointreg}%
  \edef \testdata {\the \UNICODEdata}%
  \ifx \testdata \empty \UNICODEglyphname = {.notdef}%
  \else \expandafter \UNICODEdataget \the \UNICODEdata \relax \fi}
  
  \def \UNICODEslotregbaseset #1{% base register number of unicode slot point
    \UNICODEslotregbase = #1
    \divide \UNICODEslotregbase by 256
    \multiply \UNICODEslotregbase by 256 }

\net \UNICODEglyphname

\nec \UNICODElc
\ned \UNICODElp

\nec \UNICODEnumberofslots

\nec \UNICODEpointindex % 0 ... 255

\def \UNICODEpointindexset #1{% set index of unicode point (0 ... 255)
  \UNICODEpointindex = #1
  \advance \UNICODEpointindex by -\UNICODEslot}

\ned \UNICODErp 
 
\nec \UNICODEslot % 0 ... 65536 

\ldef \UNICODEslotload #1#2#3#4{% read slot list completely
  \bgroup
    \count 0 = #4
    \advance \count 0 by 255
    \edef \test {\the \count 0}%
    \message {- #1)}%
    \lowercase {\message {[u#2.row]}}%
    \ifx \GMSdisplayregs \undefined \else
      \message {(T#4 to}%
      \message {T\test)}\fi
  \egroup
  \MESSAGEunicodedefined {#2name1}%
  \MESSAGEunicodedefined {#2name2}%
  \UNICODEslotpointreg = #4
  \lowercase {\openin 1 = u#2.row}%
    \loop \FILEcheckeof 1 \ifFILEnotended \read 1 to \myline
      \ifx \myline \CONSTpar \else
        \expandafter \UNICODEslotloaddo \myline ;;;;;;;\relax \fi \repeat
  \closein 1 }
  \ifx \eTeXversion \undefined \let \UNICODEslotload \relax \fi

  \ldef \UNICODEslotloaddo % read a line from unicode data table
    #1;% Code point
    #2;% Character name
    #3;% General Category
    #4;% Canonical Combining Classes
    #5;% Bidirectional Category
    #6;% Character Decomposition Mapping
    #7;% Decimal digit value
    #8%  (second half of data line)
  \relax {\UNICODEslotpointregset {"#1}%
    \edef \firstfirst {#1}%
    \edef \thirdfirst {#3}%
    \let \mycategory \CATother
    \ifx \thirdfirst \CONSTlu \let \mycategory \CATletter \fi
    \ifx \thirdfirst \CONSTll \let \mycategory \CATletter \fi
    \ifx \thirdfirst \CONSTlt \let \mycategory \CATletter \fi
    \ifx \thirdfirst \CONSTlm \let \mycategory \CATletter \fi
    \ifx \thirdfirst \CONSTlo \let \mycategory \CATletter \fi
    \ifx \thirdfirst \CONSTzs \let \mycategory \CATwhitespace \fi
    \ifx \firstfirst \CONSTpar \else
      \uppercase {\toks \UNICODEslotpointreg = {"#1}}%
    \fi \UNICODEslotloaddoit #8;;;;;;;\relax}

    \ldef \UNICODEslotloaddoit
      #1;% Digit value
      #2;% Numeric value
      #3;% Mirrored
      #4;% Unicode 1.0 Name
      #5;% 10646 comment field
      #6;% Uppercase Mapping
      #7;% Lowercase Mapping
      #8%  Titlecase Mapping
    \relax {%
      \edef \firstsecond {#1}%
      \ifx \firstsecond \CONSTpar \else
        \expandafter \UNICODEdataset \mycategory;"0#7;"0#6;-;-;-;-;-;-\relax
        \global \toks \UNICODEslotpointreg = \expandafter {\the \UNICODEdata}%
      \fi} 

\nec \UNICODEslotpointreg

\def \UNICODEslotpointregset #1{% register number of slot point
  \UNICODEslotpointreg = \csname \the \UNICODEslot slot\endcsname
  \advance \UNICODEslotpointreg by #1
  \advance \UNICODEslotpointreg by -\UNICODEslot}

\nec \UNICODEslotregbase

\def \UNICODEslotset #1{% Standard Unicode Value (decimal): set slot
  \UNICODEslot = #1
  \divide \UNICODEslot by 256
  \multiply \UNICODEslot by 256 }

\let \UNICODEslots \empty 

\nec \UNICODEuc

\def \UNICODEwrite {%
  \UNICODEwriteenctrue \UNICODEwriteslot \UNICODEwriteencfalse}
  
\new \ifUNICODEwriteenc
  
\ldef \UNICODEwriteline #1{\immediate \backupwrite 3{#1}}%

% Read all UNICODE slots found on UNICODEslots list:
\def \UNICODEwriteslot {% 
  \def \\ 
    [##1] % number of UNICODE slot file (1, 2, 3, ... , 127)
    [##2] % UNICODE slot number, hex. (0000, 0100, 0200, ... , FF00)
    [##3] % UNICODE slot number, dec. (0, 256, 512, ... , 65280)
    [##4] {% baseno. of UNICODE slot regs. (32512, 32256, 32000, ... , 256)
      \edef \second {##2}%
      \UNICODEslot = ##3
      \ifx \second \empty \else
        \xDef \the \UNICODEslot slot {##4}%
        \ifUNICODEwriteenc \UNICODEwriteslotdo {##1}{##2}{##3}{##4}\else
          \UNICODEslotload {##1}{##2}{##3}{##4}\fi \fi}%
  \ifUNICODEwriteenc \else 
    \message {- Installed rows of the Unicode character space:}\fi
  \UNICODEslots}
  \ifx \eTeXversion \undefined \let \UNICODEwriteslot \relax \fi 

  \def \UNICODEwriteslotdo #1#2#3#4{%
    \UNICODEwriteslotdouni {#1}{#2}{#3}{#4}%
    \UNICODEwriteslotdoglyph {#1}{#2}{#3}{#4}}

    \def \UNICODEwriteslotdoglyph #1#2#3#4{{% use Adobe glyph names
      \immediate \openout 3 g#2.enc\message {g#2.enc}%
      \UNICODEwriteline {/g#2-Encoding [}%
        \UNICODEslotregbase = #4
        \advance \UNICODEslotregbase by 256 % now regtopofUNICODEslot
        \UNICODEslotpointreg = #4 \count 8 = "#2
        \loop \ifnum \UNICODEslotregbase > \UNICODEslotpointreg
         {\UNICODEget
          \DATAhexinput = \the \count 8 \DATAhexoutput = {}\DATAhex 
          \UNICODEwriteslotdoglyphline}%
          \advance \UNICODEslotpointreg by 1 \advance \count 8 by 1
        \repeat
      \UNICODEwriteline {] def}%
      \CODEPAGEencwriteline {\CONSTpercent \CONSTspace
         Generated by \GMSname \CONSTspace (\GMSdomain)}%
      \immediate \closeout 3 }} 
  
      \def \UNICODEwriteslotdoglyphline {%
        \edef \testglyphname {\the \UNICODEglyphname}%
        \ifx \testglyphname \empty \def \testglyphname {.notdef}\fi
        \UNICODEwriteline {/\testglyphname \CONSTspace \CONSTpercent
          \CONSTspace  \the \DATAhexoutput}}  

    \def \UNICODEwriteslotdouni #1#2#3#4{{% use Unicode values
      \immediate \openout 3 u#2.enc\message {u#2.}%
      \UNICODEwriteline {/u#2-Encoding [}%
        \UNICODEslotregbase = "#2 % misusing register name:
        \advance \UNICODEslotregbase by 256 % now regtopofUNICODEslot
        \UNICODEslotpointreg = "#2
        \loop \ifnum \UNICODEslotregbase > \UNICODEslotpointreg
          \DATAhexinput = \UNICODEslotpointreg \DATAhexoutput = {}\DATAhex
         {\count 2 = \UNICODEslotpointreg
          \ifnum \count 2 < "10 \def \myprefix {000}\else
          \ifnum \count 2 < "100 \def \myprefix {00}\else
          \ifnum \count 2 < "1000 \def \myprefix {0}\else
          \let \myprefix \empty \fi \fi \fi
          \UNICODEglyphname = {%
            uni\myprefix \the \DATAhexoutput}\UNICODEwriteslotdouniline}%
          \advance \UNICODEslotpointreg by 1 \repeat
      \UNICODEwriteline {] def}%
      \CODEPAGEencwriteline {\CONSTpercent \CONSTspace
         Generated by \GMSname \CONSTspace (\GMSdomain)}%
      \immediate \closeout 3 }}
  
      \def \UNICODEwriteslotdouniline {%
        \edef \testglyphname {\the \UNICODEglyphname}%
        \ifx \testglyphname \empty \def \testglyphname {.notdef}\fi
        \UNICODEwriteline {/\testglyphname}}
                   
% Unicode slot names: --------------------------------------------------------

\Def 0000name1 {Controls-0, Basic \CONSTlatin \CONSTspace (ISO-646/ASCII),}
\Def 0000name2 {Controls-1, \CONSTlatin-1 \CONSTsupplement \CONSTspace 
  (ISO-8859-1)}
\Def 0100name1 {\CONSTlatin \CONSTspace \CONSTextended -A,}
\Def 0100name2 {\CONSTlatin \CONSTspace \CONSTextended -B/1}
\Def 0200name1 {\CONSTlatin \CONSTspace \CONSTextended -B/2, 
  International Phonetic} 
\Def 0200name2 {Alphabet \CONSTextension s, Spacing Modifier Letters}
\Def 0300name1 {Combining Diacritical Marks,}
\Def 0300name2 {Greek}
\Def 0400name1 {Cyrillic}
\Def 0500name1 {Cyrillic \CONSTsupplement ary,}
\Def 0500name2 {Armenian, Hebrew}
\Def 0600name1 {Arabic}
\Def 0700name1 {Syriac, Thaana}
\Def 0900name1 {Devanagari, Bengali}
\Def 0A00name1 {Gurmukhi, Gujarati}
\Def 0B00name1 {Oriya, Tamil}
\Def 0C00name1 {Telugu, Kannada}
\Def 0D00name1 {Malayalam, Sinhala}
\Def 0E00name1 {Thai, Lao}
\Def 0F00name1 {Tibetan}
\Def 1000name1 {Myanmar, Georgian}
\Def 1100name1 {Hangul Jamo}
\Def 1200name1 {Ethiopic/1}
\Def 1300name1 {Ethiopic/2, Cherokee}
\Def 1400name1 {\CONSTcanadian \CONSTspace /1}
\Def 1500name1 {\CONSTcanadian \CONSTspace /2}
\Def 1600name1 {\CONSTcanadian \CONSTspace /3, Ogham, Runic}
\Def 1700name1 {Tagalog, Hanunoo, Buhid,}
\Def 1700name2 {Tagbanwa, Khmer}
\Def 1800name1 {Mongolian}
\Def 1E00name1 {\CONSTlatin \CONSTspace \CONSTextended \CONSTspace Additional}
\Def 1F00name1 {Greek \CONSTspace \CONSTextended}
\Def 2000name1 {General Punctuation, Super- and Subscripts, Currency}
\Def 2000name2 {\CONSTsymbols, Combining Diacritical Marks for \CONSTsymbols}
\Def 2100name1 {Letterlike \CONSTsymbols,}
\Def 2100name2 {Number Forms, Arrows}
\Def 2200name1 {\CONSTmathematic al Operators}
\Def 2300name1 {\CONSTmiscellaneous \CONSTspace Technical}
\Def 2400name1 {Control Pictures, Optical Character Recognition,}
\Def 2400name2 {Enclosed Alphanumerics}
\Def 2500name1 {Box Drawing, Block Elements,}
\Def 2500name2 {Geometric Shapes}
\Def 2600name1 {\CONSTmiscellaneous \CONSTspace \CONSTsymbols}
\Def 2700name1 {Dingbats, \CONSTmiscellaneous \CONSTspace 
  \CONSTmathematic al \CONSTsymbols-A,}
\Def 2700name2 {\CONSTsupplement al Arrows-A}
\Def 2800name1 {Braille Patterns}
\Def 2900name1 {\CONSTsupplement al Arrows-B, \CONSTmiscellaneous}
\Def 2900name2 {\CONSTmathematic \CONSTspace \CONSTsymbols-B}
\Def 2A00name1 {\CONSTsupplement al \CONSTmathematic al}
\Def 2A00name2 {Operators}
\Def 2B00name1 {}%
\Def 2C00name1 {}%
\Def 2D00name1 {}%
\Def 2E00name1 {Chinese-Japanese-Korean Radicals \CONSTsupplement}
\Def 2F00name1 {KangXi Radicals,}
\Def 2F00name2 {\CONSTideograph ic Description Characters}
\Def 3000name1 {CJK \CONSTsymbols \CONSTspace and Punctuation,}
\Def 3000name2 {Hiragana, Katakana}
\Def 3100name1 {Bopomofo, Hangul \CONSTcompatibility, Jamo, Kanbun,}
\Def 3100name2 {Bopomofo \CONSTextended, Katakana Phonetic \CONSTextension s}
\Def 3200name1 {Enclosed CJK Letters and Months}
\Def 3300name1 {CJK Compatibility}
\Def 3400name1 {CJK Unified \CONSTideograph s}
\Def 3400name2 {\CONSTextension \CONSTspace A}
\Def 4E00name1 {CJK Unified \CONSTideograph s}
\Def A000name1 {Yi Syllables}
\Def A400name1 {Yi Radicals}
\Def AC00name1 {Hangul Syllables}
\Def F600name1 {\CONSTcorporateuse \CONSTspace \CONSTadobe}
\Def F700name1 {\CONSTcorporateuse \CONSTspace \CONSTadobe}
\Def F800name1 {\CONSTcorporateuse \CONSTspace (Apple Dingbats)}
\Def FC00name1 {\CONSTcorporateuse \CONSTspace \CONSTadobe}
\Def FD00name1 {\CONSTcorporateuse \CONSTspace \CONSTadobe}
\Def F900name1 {CJK \CONSTcompatibility \CONSTspace \CONSTideograph s}
\Def FB00name1 {Alphabetic \CONSTpresentation,}
\Def FB00name2 {Arabic \CONSTpresentation-A}
\Def FE00name1 {Variation Selectors, Comb. Half Marks, CJK Comp.}
\Def FE00name2 {Forms, Small Form Variants, Arabic Pres. Forms-B}
\Def FF00name1 {Halfwidth and Fullwidth Forms,}
\Def FF00name2 {Specials}
\Def 10300name1 {Old Italic, Gothic}
\Def 10400name1 {Deseret}
\Def 12300name1 {Klingon}
\Def 1D000name1 {Byzantine Musical \CONSTsymbols}
\Def 1D100name1 {Musical \CONSTsymbols}
\Def 1D400name1 {\CONSTmathematic al Alphanumeric \CONSTsymbols}
\Def 20000name1 {CJK Unified \CONSTideograph s}
\Def 20000name2 {\CONSTextension \CONSTspace B}
\Def 2F800name1 {CJK \CONSTcompatibility \CONSTspace \CONSTideograph s}
\Def 2F800name2 {\CONSTsupplement}
\Def E0000name1 {Tags}
  
% URL: =======================================================================

% Distinguish internal and external destinations
% (handled by pdf viewer and web client):

\bgroup \CATotherhashmark \CATparameterdegree
\gdef \URLget °1{%
  \expandafter \URLgetlocal °1#\relax
  \expandafter \URLgetinternet °1://\relax
  \expandafter \URLgetemail °1mailto:\relax  
  \ifGEDCOM \expandafter \URLgetgedcomemail °1@.@\relax \fi
  \expandafter \URLgetnews °1news:\relax
  \expandafter \URLgethtm °1.htm#GMS-STOP\relax
  \expandafter \URLgetrelative °1://://\relax}
\egroup 
  
  \def \URLgetemail #1mailto:#2\relax {%
    \def \URLemailsecond {#2}%
    \ifx \URLemailsecond \empty \else \URLinternettrue \fi}
                      
    \def \URLgetgedcomemail #1@#2.#3@#4\relax {%
      \def \URLemailfourth {#4}%
      \ifx \URLemailfourth \CONSTdotat \URLinternettrue 
        \xdef \ANCHORext {mailto:#1@#2.#3}%
        \glet \ANCHORint \ANCHORext \fi}
    
    \let \URLgedcomimage \empty

  \bgroup \CATotherhashmark \CATparameterdegree
  \gdef \URLgethtm °1.°2htm°3#°4\relax {%
    \def \URLhtmsecond {°2}%
    \def \URLhtmthird {°3}%
    \def \URLhtmfourth {°4}%
    \ifx \URLhtmsecond \empty \URLgethtmsecondempty
    \else \URLgethtmsecondfull \fi}
  \egroup 

    \def \URLgethtmsecondempty {%
      \ifx \URLhtmthird \CONSTl \URLPARSEsecondemptystop 
      \else \ifx \URLhtmthird \empty \URLPARSEsecondemptystop \fi \fi}    
      \def \URLPARSEsecondemptystop {%
        \ifx \URLhtmfourth \CONSTstopmark \else \URLinternettrue \fi}

    \def \URLgethtmsecondfull {%
      \ifx \URLhtmthird \CONSTdothtm 
      \else \ifx \URLhtmthird \CONSTldothtm 
      \else \ifx \URLhtmthird \empty 
      \else \ifx \URLhtmfourth \CONSTstopmark 
        \URLinternettrue \fi \fi \fi \fi}

  \def \URLgetinternet #1://#2\relax {% Fixme: used globally
    \edef \URLinternetfirst {#1}%
    \ifx \URLinternetfirst \CONSTftp \URLinternettrue 
    \else \ifx \URLinternetfirst \CONSThttp \URLinternettrue 
    \else \ifx \URLinternetfirst \CONSThttps \URLinternettrue 
    \fi \fi \fi}
          
  \bgroup \CATotherhashmark \CATparameterdegree
  \gdef \URLgetlocal °1#°2{%
    \edef \URLlocalfirst {°1}%
    \edef \URLlocalsecond {°2}%
    \ifx \ANCHORext \empty
      \URLgetlocalempty \fi
    \ifx \URLlocalsecond \CONSTrelax
      \URLgetlocalrelax 
    \else \URLgetlocalnorelax \fi
    \URLlocalnext}
  \egroup

    \def \URLgetlocalempty {%
      \let \ANCHORext \URLlocalfirst}

    \def \URLgetlocalnorelax {%
      \ifx \URLlocalsecond \CONSThashmark \else
        \URLgetlocalnorelaxhash \fi}
      \def \URLgetlocalnorelaxhash {%
        \let \URLlocalnext \URLgetlocal
        \let \ANCHORint \URLlocalsecond}
  
    \def \URLgetlocalrelax {%
      \let \URLlocalnext \relax
      \edef \ANCHORint {\ANCHORint \URLlocalfirst}}
      
  \def \URLgetnews #1news:#2\relax {%
    \def \URLnewssecond {#2}%
    \ifx \URLnewssecond \empty \else \URLinternettrue \fi}
    
  \def \URLgetrelative #1://#2://#3\relax {%
    \edef \URLrelativefirst {#1}%
    \ifx \URLrelativefirst \CONSTfilelc \URLinternetfalse
      \edef \URLrelativefirst {#2}%
      \let \ANCHORint \URLrelativefirst
      \let \URLhref \ANCHORint \fi}

\let \URLhref \empty

\new \ifURLinternet

% VALUE: =====================================================================

% Handle numbers, dimensions and per cent values:

\net \VALUE
    
% Set a dimension register to a value given absolutely or relatively:
\bgroup \CATotherpercent \CATcommentbar
\gdef \VALUEdimenset #1#2{|
  \VALUElowercaseget
  \ifx \VALUElowercase \CONSTauto
    \VERIFYerrorunsuppattprop {"\CONSTauto"}\VALUE = {50%}\fi
  \let \valueUNIT \empty \valueUNITfalse \valueUNITpxfalse
  \edef \VALUEdimensettest {#1#2\the \VALUE %\relax}| "%" no comment here!
  \expandafter \valueDIMENsetreg \VALUEdimensettest}
\egroup

\def \VALUEintegerget {%
  \expandafter \valueINTEGERgetdo \expandafter {\the \VALUE}%
  \let \VALUEinteger \valueINTEGER}
  
\def \VALUEintegerset #1{%
  \VALUEintegerget 
  \edef #1{\VALUEinteger}}
  
\def \VALUElowercaseget {%
  \expandafter \VALUElowercaseparse \the \VALUE \relax}

  \def \VALUElowercaseparse #1\relax {%
    \lowercase {\edef \VALUElowercase {#1}}}
  
 \def \VALUEset #1{%
   \edef #1{\the \VALUE}}  
  
\def \VALUEsetglobal #1{%
  \xdef #1{\the \VALUE}}
  
\def \VALUEsetlowercase #1{%
  \VALUElowercaseget 
  \edef #1{\VALUElowercase}}
  
\def \VALUEsetrelax #1{%
  \edef #1{\the \VALUE \relax}}
  
\def \VALUEuppercaseget {%
  \expandafter \VALUEuppercaseparse \the \VALUE \relax}

  \def \VALUEuppercaseparse #1\relax {%
    \uppercase {\edef \VALUEuppercase {#1}}}
  
\def \VALUEwidows {%
  \edef \VALUEwidowstest {\the \VALUE}%
  \ifx \VALUEwidowstest \CONSTnumberone \global \widowpenalty = 9999 \else
  \ifx \VALUEwidowstest \CONSTnumbertwo \global \widowpenalty = 10000 \fi \fi}
  
% valueDIMEN: ----------------------------------------------------------------

  \ned \valueDIMENsetpercent
  
  % #1 has to be a register that will be set to #3 (per cent of #2 if #4="%"):
  \bgroup \CATotherpercent \CATcommentbar  
  \gdef \valueDIMENsetreg #1#2#3%#4\relax {|
    \def \valuePERCENTfirst {#1}|
    \def \valuePERCENTsecond {#2}|
    \def \valuePERCENTthird {#3}|
    \def \valuePERCENTparsetest {#4}|
    \ifx \valuePERCENTparsetest \CONSTpercent \valueDIMENsetregpercent
    \else \valueDIMENsetregdo \fi}
  \egroup

    \def \valueDIMENsetregdo {% 
      \valueNUMBERtrue 
      \edef \arg {\valuePERCENTthird \valuePERCENTparsetest}%
      \expandafter \valueDIMENsetregdopercent \arg \CONSTstopmark
      \valueDIMENsetregdounit
      \ifvalueNUMBER \valueDIMENsetregdonumber \else 
        \valueDIMENsetregdoit \fi}
  
      \new \ifvalueUNIT
      \new \ifvalueUNITpx
      
      \def \valueDIMENsetregdoit {% 
        \ifvalueUNITpx \valueDIMENsetregdoitpx
        \else \ifvalueUNIT \valuePERCENTfirst = \valuePERCENTthird \relax 
        \else \VERIFYerrorinvalidunit \valueUNIT \fi \fi}
    
        \def \valueDIMENsetregdoitpx {%
          \edef \valuePERCENTparsetest {\valuePERCENTthird}%
          \expandafter \valueDIMENsetregdoitpxget \valuePERCENTparsetest}
      
          \def \valueDIMENsetregdoitpxget #1px{%
            \edef \valueDIMENsetregdoitpxgettest {#1}%
            \ifx \valueDIMENsetregdoitpxgettest \empty \else 
              \valuePERCENTfirst = #1pt \fi}

      \def \valueDIMENsetregdonumber {% 
        \valueDIMENsetpercent = \valuePERCENTthird sp
        \ifnum \valueDIMENsetpercent < 2000 
          \valueDIMENsetregdonumberget 
          \valuePERCENTfirst = \valueDIMENsetpercent
        \else \valuePERCENTfirst = 1cm \fi}
    
        % Seems to be a number, not a dimension, so assume pixels:
        \def \valueDIMENsetregdonumberget {%
          \multiply \valueDIMENsetpercent by 65536 }% 1 pt = 65536 sp
          
      \def \valueDIMENsetregdounit {%
        \ifx \valueUNIT \CONSTpx \valueUNITtrue \valueUNITpxtrue \else
        \ifx \valueUNIT \CONSTpt \valueUNITtrue \else
        \ifx \valueUNIT \CONSTmm \valueUNITtrue \else
        \ifx \valueUNIT \CONSTcm \valueUNITtrue \else
        \ifx \valueUNIT \CONSTex \valueUNITtrue \else
        \ifx \valueUNIT \CONSTem \valueUNITtrue \else
        \ifx \valueUNIT \CONSTin \valueUNITtrue \else
          \valueDIMENsetregdounitnonhtml \fi \fi \fi \fi \fi \fi \fi}

        \def \valueDIMENsetregdounitnonhtml {% Fixme: do error message
          \ifx \valueUNIT \CONSTpc \valueUNITtrue \else
          \ifx \valueUNIT \CONSTdd \valueUNITtrue \else
          \ifx \valueUNIT \CONSTcc \valueUNITtrue \else
          \ifx \valueUNIT \CONSTbp \valueUNITtrue \else
          \ifx \valueUNIT \CONSTsp \valueUNITtrue \fi \fi \fi \fi \fi}

      \bgroup \CATotherpercent \CATcommentbar
      \gdef \valueDIMENsetregdopercent #1{|
        \edef \valuePERCENTparsetest {#1}|
        \let \valueNUMBERparsenext \valueDIMENsetregdopercent
        \ifx \valuePERCENTparsetest \CONSTstopmark 
          \valueDIMENsetregdopercentstop
        \else \valueDIMENsetregdopercentrun \fi 
        \valueNUMBERparsenext}
      \egroup

        \def \valueDIMENsetregdopercentrun {%
          \ifx \valuePERCENTparsetest \empty \else 
            \valueDIMENsetregdopercentrundo \fi}
      
          \def \valueDIMENsetregdopercentrundo {%
            \ifx \valuePERCENTparsetest \CONSTdot \else 
            \ifx \valuePERCENTparsetest \CONSThyphen \else 
            \ifx \valuePERCENTparsetest \CONSTnumberzero \else 
            \ifx \valuePERCENTparsetest \CONSTnumberone \else
            \ifx \valuePERCENTparsetest \CONSTnumbertwo \else 
            \ifx \valuePERCENTparsetest \CONSTnumberthree \else
              \valueDIMENsetregdopercentrundoit \fi \fi \fi \fi \fi \fi
            \ifvalueNUMBER \else 
              \edef \valueUNIT {\valueUNIT \valuePERCENTparsetest }\fi}
          
              \def \valueDIMENsetregdopercentrundoit {%
                \ifx \valuePERCENTparsetest \CONSTnumberfour \else 
                \ifx \valuePERCENTparsetest \CONSTnumberfive \else
                \ifx \valuePERCENTparsetest \CONSTnumbersix \else 
                \ifx \valuePERCENTparsetest \CONSTnumberseven \else
                \ifx \valuePERCENTparsetest \CONSTnumbereight \else 
                \ifx \valuePERCENTparsetest \CONSTnumbernine \else
                  \valueNUMBERfalse \fi \fi \fi \fi \fi \fi}

        \def \valueDIMENsetregdopercentstop {%
          \let \valueNUMBERparsenext \relax}
   
    \def \valueDIMENsetregpercent {% 
      \valuePERCENTfirst = \valuePERCENTsecond
      \valueDIMENsetpercent = \valuePERCENTthird pt
      \divide \valueDIMENsetpercent by 65536
      \divide \valuePERCENTfirst by 10
      \multiply \valuePERCENTfirst by \valueDIMENsetpercent
      \divide \valuePERCENTfirst by 10 }      
    
% valueINTEGER: --------------------------------------------------------------

  \def \valueINTEGER {0}
    
  \def \valueINTEGERgetdo #1{%
    \let \valueINTEGER \empty   
    \valueINTEGERgetfoundtrue
    \valueINTEGERgetdoit #1\end
    \ifvalueINTEGERgetfound \else \def \valueINTEGER {0}\fi
    \ifx \valueINTEGER \empty \def \valueINTEGER {0}\fi}
    
    \new \ifvalueINTEGERgetfound

    \def \valueINTEGERgetdoit #1{% 
      \edef \valueINTEGERgetdoitgiven {#1}%
      \ifx \end #1\let \valueINTEGERnext \relax \else
        \count 8 = 0 % Fixme: reserve counter
        \let \valueINTEGERold \valueINTEGER
        \loop \ifnum \count 8 < 10
          \valueINTEGERgetdoitcheck {\the \count 8 }% 
          \advance \count 8 by 1 \repeat 
        \ifx \valueINTEGERold \valueINTEGER \valueINTEGERgetfoundfalse \fi
        \let \valueINTEGERnext \valueINTEGERgetdoit 
      \fi \valueINTEGERnext}

      \def \valueINTEGERgetdoitcheck #1{% 
        \edef \valueINTEGERgetdoitchecktest {#1}%
        \ifx \valueINTEGERgetdoitgiven \valueINTEGERgetdoitchecktest
          \edef \valueINTEGER {\valueINTEGER \valueINTEGERgetdoitgiven}\fi}
          
% VERIFY: ====================================================================

% Fixme: Mention open elements only if required or doctype xhtml

\def \VERIFYerrorabsent #1{%
  \message {! Absent: "#1".}%
  \DEFsearch {\CONSTABSENT #1}\ifDEF \else
    \global \advance \verifyWELLFORMtotalabsent by 1
    \xDef {\CONSTABSENT #1} {}\fi}

\def \VERIFYerrorapostrophized {%
  \verifyWELLFORMtotalunquotedadvance
  \ifx \VERIFYerrorapostroph \undefined  
    \message {! Apostrophized.}%
    \glet \VERIFYerrorapostroph \empty \fi}

\def \VERIFYerrorcannotrender {%
  \verifyWELLFORMtotalotheradvance \message {Cannot render.}}

\def \VERIFYerrorcat {% Fixme: move
  \CATotherhashmark \CATotherampersand \CATparameterdegree}

\def \VERIFYerrorcodepagereplaced #1{%
  \verifyWELLFORMtotalotheradvance \message {Replaced: "#1".}}

\def \VERIFYerrordebugend {% Force end of TeX run (GMS debugging)
  \csname TAG/trace\endcsname
  \Message {end}\MESSAGEproprietary \vfill \eject \getend}

\def \VERIFYerrordeprecated #1{%
  \verifyWELLFORMmessdiff {#1}{Deprecated}%
    \verifyWELLFORMdiffdeprecated 
      \verifyWELLFORMtotaldeprecated \CONSTdepr}

\def \VERIFYerrordeprecatedatt #1{%
  \verifyWELLFORMmessdiff {#1}{Deprecated: #1}%
    \verifyWELLFORMdiffdeprecated 
      \verifyWELLFORMtotaldeprecated \CONSTdeprap}

\let \verifyWELLFORMerrordiff \empty

\def \VERIFYerrorduplicate #1{%
  \message {! Duplicate: [#1].}%
  \global \advance \verifyWELLFORMtotalduplicate by 1 }

\def \VERIFYerrorempty #1{%
  \verifyWELLFORMmessdiff {#1}{Missing: #1}%
    \verifyWELLFORMdiffempty \verifyWELLFORMtotalempty \CONSTEMPTY}

\bgroup \VERIFYerrorcat   
  \gdef \VERIFYerrorfallback °1°2\relax {\def \first {°1}%
    \ifx \first \CONSTquotmark \def \first {x}\fi   
    \message {! Fallback: &#\first °2;}%
    \global \advance \verifyWELLFORMtotalfallback by 1 }    
\egroup

\bgroup \VERIFYerrorcat 
  \gdef \VERIFYerrorfallbackname °1{\message {! Fallback: &°1;}%
    \global \advance \verifyWELLFORMtotalfallback by 1 }
\egroup

\def \VERIFYerrorfontfalse {%
  \message {! False font.}\verifyWELLFORMtotalotheradvance}  

\def \VERIFYerrorfontreset #1{%
  \message {! Font reset.}% 
  \global \advance \verifyWELLFORMtotalother by 1 }
    % Fixme: \verifyWELLFORMtotalotheradvance
  
\def \VERIFYerrorfontstyle #1{%
  \message {! Unsupported font-style: #1}}
  
\def \VERIFYerrorfontweight #1{%
  \message {! Unsupported font-weight: #1}}

\def \VERIFYerrorinvalidfontsize {%
  \verifyWELLFORMtotalotheradvance \message {Invalid font size.}}

\def \VERIFYerrorinvalidsize #1{%
  \verifyWELLFORMtotalotheradvance \message {Invalid font size "#1".}}

\def \VERIFYerrorinvalidunit #1{%
  \verifyWELLFORMmessdiff {#1}{Invalid unit: "#1"}%
    \verifyWELLFORMdiffinvalidunit 
      \verifyWELLFORMtotalinvalidunit \CONSTinvalidunit}     

\bgroup \VERIFYerrorcat 
  \gdef \VERIFYerrorlost °1°2\relax {\def \first {°1}%
    \ifx \first \CONSTquotmark \def \first {x}\fi   
    \message {! Lost: &#\first °2;}%
    \global \advance \verifyWELLFORMtotallost by 1 }     
\egroup

\def \VERIFYerrorline {(line \the \inputlineno)} % Fixme: use more often

\def \VERIFYerrorlostplain #1{%
  \verifyWELLFORMtotalotheradvance \message {! Lost: #1;}}

\def \VERIFYerrormetanospace #1{%
  \verifyWELLFORMtotalotheradvance
  \message {\CONSTpleasedonotwrite}%
  \message {"#1" before "="}%
  \message {(\CONSTthereshouldbe}%
  \message {no space).}}

\def \VERIFYerrormetaonespace #1{%
  \verifyWELLFORMtotalotheradvance
  \message {\CONSTpleasedonotwrite}%
  \message {"#1" after ";"}%
  \message {(\CONSTthereshouldbe}%
  \message {one space).}}

\def \VERIFYerrormisformeddate {%
  \verifyWELLFORMtotalotheradvance \message {Misformed: "YYYY-MM-DD".}}    

\def \VERIFYerrormisnested {%
  \message {! Misnested.}\VERIFYerrormisnesting}

\def \VERIFYerrormisnesting {%
  \global \advance \verifyWELLFORMtotalmisnesting by 1 }% just for statistic

\def \VERIFYerrormissingendtag #1{% Fixme: outsource
  \ifnum \verifyWELLFORMtotalunclosed < 2
%%% \message {! Open: #1.}\else 
    \message {! Open: #1 \VERIFYerrorline.}\else 
%%% \ifverifyDOCTYPExhtmlclaim \message {! Open: #1.}\else
    \ifverifyDOCTYPExhtmlclaim \message {! Open: #1 \VERIFYerrorline.}\else
      \message {!}\fi \fi
  \xdef \ELEMENTopen {#1}%
  \xdef \backupelement {\the \ELEMENT}%
   \xdef \backupATTlist {\the \ATTlist}%
    \glet \backupifATT \ifATT
     \glet \backupifPROPERTY \ifPROPERTY
       \global \advance \verifyWELLFORMtotalunclosed by 1
       \csname \CONSTtag /#1\endcsname
     \global \let \ifPROPERTY \backupifPROPERTY 
    \global \let \ifATT \backupifATT 
   \global \ATTlist = \expandafter {\backupATTlist}%
  \global \ELEMENT = \expandafter {\backupelement}}

\def \VERIFYerrormissingheight {%
  \verifyWELLFORMtotalotheradvance \message {Unspecified: height.}}

\def \VERIFYerrormissingspace {%
  \verifyWELLFORMtotalotheradvance \message {Missing space before />.}}    

\def \VERIFYerrormissingwidth {%
  \ifnum \NOrow < 2
    \ifnum \verifyWELLFORMtotalmissingwidth < 2 
      \ifTABLEcolspan \else 
        \global \advance \verifyWELLFORMtotalmissingwidth by 1
        \message {! Unspecified: width.}\fi \fi \fi}

\def \VERIFYerrormissingulol {%
  \verifyWELLFORMtotalotheradvance 
  \message {Missing parent element <dl>, <ol> or <ul>.}}

\def \VERIFYerrormisspelled {%
  \verifyWELLFORMmessdiff {}{Misspelled}%
    \verifyWELLFORMdiffproprietary 
      \verifyWELLFORMtotalproprietary \CONSTprop}       

\def \VERIFYerrornocodepage #1{%
  \verifyWELLFORMtotalotheradvance \message {No codepage #1.}}

\def \VERIFYerrornofamilydefined #1{%
  \verifyWELLFORMtotalotheradvance 
  \message {No font-family defined for "#1".}}

\def \VERIFYerrornofontforCP #1{%
  \verifyWELLFORMtotalotheradvance \echo {No such font(s) installed for
    \CONSTcodepage \CONSTspace \CODEPAGEhtml:}%
  \echo {\CONSTspace \CONSTspace #1}}

\def \VERIFYerrornolineheight {%
  \verifyWELLFORMtotalotheradvance \message {Missing line-height. }}

\def \VERIFYerrornostylesheettype {%
   \global \advance \verifyWELLFORMtotalempty by 1 
   \message {! Missing attribute: type = "text/css".}}

\def \VERIFYerroropenp {%
  \global \advance \verifyWELLFORMtotalunclosed by 1
  \message {! Open: p.}\endgroup}

\def \VERIFYerrorproprietary #1{%
  \verifyWELLFORMmessdiff {#1}{Proprietary}%
    \verifyWELLFORMdiffproprietary 
      \verifyWELLFORMtotalproprietary \CONSTprop}   

\def \VERIFYerrorproprietaryatt #1{%
  \verifyWELLFORMmessdiff {#1}{Proprietary: #1}%
    \verifyWELLFORMdiffproprietary 
      \verifyWELLFORMtotalproprietary \CONSTpropap} 

\def \VERIFYerrorsuperfluous {%
  % Rendering unescaped end tags in preformatted code sections:
  \ifOPENpre \CONSTlessthan \the \ELEMENT >\else
    \ifnum \verifyWELLFORMtotalunclosed > 0 
      \edef \VERIFYerrortest {\the \ELEMENT}%
      \edef \VERIFYerrortestopen {/\ELEMENTopen}%
      \ifx \VERIFYerrortest \VERIFYerrortestopen
        \message {! Overlapping.}%
        \global \advance \verifyWELLFORMtotalunclosed by -1
        \global \advance \verifyWELLFORMtotaloverlap by 1
      \else \VERIFYerrorsupermessage \fi
    \else \VERIFYerrorsupermessage \fi \fi}

\def \VERIFYerrorsupermessage {%
 \global \advance \verifyWELLFORMtotalsuperfluous by 1 
  \message {! Superfluous \VERIFYerrorline.}}

\def \VERIFYerrortracebegin {%
  \global \tracinggroups = 1 
  \global \tracingmacros = 1 }

\def \VERIFYerrortraceend {%
  \global \tracingcommands = 0
  \global \tracinggroups = 0
  \global \tracingnesting = 0 
  \global \tracingifs = 0
  \global \tracingmacros = 0 }

\def \VERIFYerrorunanchored {%
  \verifyWELLFORMtotalotheradvance \message {Unanchored.}} 

\def \VERIFYerroruncolored #1{%
  \verifyWELLFORMmessdiff {#1}{Uncolored: "#1"}%
    \verifyWELLFORMdiffuncolored 
      \verifyWELLFORMtotaluncolored \CONSTuncolored}

\def \VERIFYerrorundefclass #1{%
  \verifyWELLFORMmessdiff {#1}{Undeclared: "#1"}%
    \verifyWELLFORMdiffundefclass 
      \verifyWELLFORMtotalundefclass \CONSTundecl}

\def \VERIFYerrorundefref #1{%
  \REFERENCEundefinedtrue
  \verifyWELLFORMmessdiff {#1}{Undefined: '#1'}%
    \verifyWELLFORMdiffundefref 
      \verifyWELLFORMtotalundefref \CONSTundefref}

\def \VERIFYerrorundelimited #1{%
  \global \advance \verifyWELLFORMtotalundelimited by 1
  \message {! Undelimited: \CONSTampersand #1;}}      

\def \VERIFYerrorunloadable #1{%
  \verifyWELLFORMtotalotheradvance \message {Unloadable: "#1".}}

\def \VERIFYerrorunquot {%
  \ifnum \verifyWELLFORMtotalunquoted < 1
    \VERIFYerrorunquoted {\ATTfirstunquoted 
      \CONSTspace = "\the \VALUE".}\else %% Fixme: 'class = break' => 'always'
    \ifATTunquotedmessage \else \ATTunquotedmessagetrue 
      \ifnum \verifyWELLFORMtotalunquoted < 20 \message {! ".}\fi \fi \fi
  \verifyWELLFORMtotalunquotedadvance}

\def \VERIFYerrorunquoted #1{%
  \edef \VERIFYerrorunquotedtest {\the \VALUE}%
  \ifx \VERIFYerrorunquotedtest \empty \else 
    \message {! Unquoted: #1}\verifyWELLFORMtotalunquotedadvance \fi}

\def \VERIFYerrorunrecogattprop #1{%
  \ifCLASSpredefined \else
    \verifyWELLFORMmessdiff {#1}{Unrecognized: '#1' \VERIFYerrorline}%
      \verifyWELLFORMdiffunrecognized 
        \verifyWELLFORMtotalunrecognized \CONSTunrecap \fi}

\def \VERIFYerrorunrecognized #1{%
  \Message {#1}% show start tag which is undefined
  \verifyWELLFORMmessdiff {#1}{Unrecognized}%
   \verifyWELLFORMdiffunrecognized 
      \verifyWELLFORMtotalunrecognized \CONSTunrec}

\def \VERIFYerrorunselected #1{%
  \verifyWELLFORMtotalotheradvance \message {Unselected:}\message {#1.}} 

\def \VERIFYerrorunsuppattprop #1{%
  \verifyWELLFORMmessdiff {#1}{Unsupported: #1}%
    \verifyWELLFORMdiffunsupported 
      \verifyWELLFORMtotalunsupported \CONSTunsupap}

\def \VERIFYerrorunsupported #1{%
  \verifyWELLFORMmessdiff {#1}{Unsupported}%
    \verifyWELLFORMdiffunsupported 
      \verifyWELLFORMtotalunsupported \CONSTunsup}

\def \VERIFYerroryoumeantcenter {%
  \verifyWELLFORMmessdiff {}{Confused: align = "center"}%
    \verifyWELLFORMdiffconfused 
      \verifyWELLFORMtotalconfused {\CONSTconfu center}}

\def \VERIFYerroryoumeantmiddle {%
  \verifyWELLFORMmessdiff {}{Confused: valign = "middle"}%
    \verifyWELLFORMdiffconfused 
      \verifyWELLFORMtotalconfused {\CONSTconfu middle}}

\def \VERIFYnotstrict {%
  \global \verifyDOCTYPEnotstricttrue
  \ifnum \verifyWELLFORMtotaldeprecated = 0
    \ifnum \verifyWELLFORMclass = 0 \MESSAGEnotstrict
      \verifyWELLFORMtotalotheradvance 
        \global \verifyWELLFORMclass = 1 \else
      \ifnum \verifyWELLFORMclass = 2 \MESSAGEnotstrict
        \verifyWELLFORMtotalotheradvance 
          \global \verifyWELLFORMclass = 3 \fi \fi \fi}

\def \VERIFYnotstrictatt #1{%
  \global \verifyDOCTYPEnotstricttrue
  \ifnum \verifyWELLFORMtotaldeprecated = 0
    \ifnum \verifyWELLFORMclass = 0 
      \verifyWELLFORMtotalotheradvance \MESSAGEnotstrictatt {#1}%
      \global \verifyWELLFORMclass = 1 \else
      \ifnum \verifyWELLFORMclass = 2 
        \verifyWELLFORMtotalotheradvance \MESSAGEnotstrictatt {#1}%
        \global \verifyWELLFORMclass = 3 \fi \fi \fi}
            
\def \VERIFYwellformedness {%
  \ifinner \ELEMENTcloseinner \fi
  \ifnum \ELEMENTlevel > 0 \ELEMENTcloseouter \fi
  \ifverifyDOCTYPEnotstrict \def \VERIFYwellformednesstest {0}\else 
    \def \VERIFYwellformednesstest {1}\fi
  \verifyWELLFORMdo \verifyDOCTYPE \VERIFYwellformednesstest}
           
% verifyDOCTYPE: -------------------------------------------------------------

  % The doctype declaration check will set \verifyDOCTYPE to a number in range
  % 0 to 5:

  % 0: XHTML strict
  % 1: XHTML transitional or frameset
  % 2: HTML strict
  % 3: HTML transitional or frameset
  % 4: none (initial)
  % 5: unrecognized

  \nec \verifyDOCTYPE \verifyDOCTYPE = 4 % "none"

  \def \verifyDOCTYPEget #1{%
    \ifnum \verifyDOCTYPE = 4
      \global \verifyDOCTYPE = 5 % "unrecognized"
      \edef \probe {#1\CONSTspace}%
      \expandafter \verifyDOCTYPEgetxhtmlstrict \probe
        XHTML {} Strict//EN\relax
      \ifverifyDOCTYPExhtmlclaim \else
        \expandafter \verifyDOCTYPEgetxhtmltrans \probe
          XHTML {} Transitional//EN\relax \fi
      \ifverifyDOCTYPExhtmlclaim \else
        \expandafter \verifyDOCTYPEgetxhtmlframe \probe
          XHTML {} Frameset//EN\relax \fi
      \ifverifyDOCTYPExhtmlclaim \else %%%
        \expandafter \verifyDOCTYPEgetgedcom \probe %%%
          GEDCOM {} \relax \fi %%%
      \ifverifyDOCTYPExhtmlclaim \else
        \expandafter \verifyDOCTYPEgethtmlstrict \probe
          HTML {} Strict//EN\relax \fi
      \ifverifyDOCTYPExhtmlclaim \else
        \expandafter \verifyDOCTYPEgethtmltrans \probe
          HTML {} Transitional//EN\relax \fi
      \ifverifyDOCTYPExhtmlclaim \else
        \expandafter \verifyDOCTYPEgethtmlframe \probe
          HTML {} Frameset//EN\relax \fi
    \fi}

    \def \verifyDOCTYPEgetdo #1#2#3{%
      \def \second {#2}\def \third {#3}%
      \ifx \second \empty \global \verifyDOCTYPExhtmlclaimfalse \else 
        \ifx \third \empty \global \verifyDOCTYPExhtmlclaimfalse \else
          \xdef \verifyDOCTYPEversion {#2}\global \verifyDOCTYPE = #1\fi \fi}
    
    \def \verifyDOCTYPEgetgedcom #1GEDCOM #2\relax {% %%%
      \def \test {#1}%
      \ifx \test \empty \global \verifyDOCTYPExhtmlclaimtrue 
        \verifyDOCTYPEgetdo 0{6.0}{GEDCOM}%
      \else \verifyDOCTYPEgetdo 5{6.0}{GEDCOM}\fi}  
  
    \def \verifyDOCTYPEgethtmlframe #1 HTML #2 Frameset//EN#3\relax {%
      \verifyDOCTYPEgetdo 3{#2}{#3}}   
     
    \def \verifyDOCTYPEgethtmlstrict #1 HTML #2//EN#3\relax {%
      \verifyDOCTYPEgetdo 2{#2}{#3}}  
      
    \def \verifyDOCTYPEgethtmltrans #1 HTML #2 Transitional//EN#3\relax {%
      \verifyDOCTYPEgetdo 3{#2}{#3}}    
    
    \def \verifyDOCTYPEgetxhtmlframe #1 XHTML #2 Frameset//EN#3\relax {%
      \global \verifyDOCTYPExhtmlclaimtrue
      \verifyDOCTYPEgetdo 1{#2}{#3}}    
    
    \def \verifyDOCTYPEgetxhtmlstrict #1 XHTML #2 Strict//EN#3\relax {%
      \global \verifyDOCTYPExhtmlclaimtrue
      \verifyDOCTYPEgetdo 0{#2}{#3}}   
     
    \def \verifyDOCTYPEgetxhtmltrans #1 XHTML #2 Transitional//EN#3\relax {%
      \global \verifyDOCTYPExhtmlclaimtrue
      \verifyDOCTYPEgetdo 1{#2}{#3}}
  
  \new \ifverifyDOCTYPEnotstrict
  
  \def \verifyDOCTYPEversion {unknown} % markup version number not checked

  \new \ifverifyDOCTYPExhtmlclaim
  
% verifyPLURAL: --------------------------------------------------------------

  \def \verifyPLURALabsent #1#2{%
    absent file#1}

  \def \verifyPLURALconfused #1#2{%
    confused attribute value#1 #2}

  \def \verifyPLURALdeprecated #1#2{%
    deprecated element#1 or attribute#1 #2}

  \def \verifyPLURALduplicate #1#2{%
    duplicate anchor name#1 or element id#1}

  \def \verifyPLURALfallback #1#2{%
    fallback font character#1}

  \def \verifyPLURALempty #1#2{%
    missing or empty attribute#1 #2}

  \def \verifyPLURALfile #1#2{%
    ignored file#1}

  \def \verifyPLURALinvalidunit #1#2{%
    invalid length unit#1 #2}

  \def \verifyPLURALlost #1#2{%
    lost character#1}

  \def \verifyPLURALmisnesting #1#2{%
    misnested element#1}

  \def \verifyPLURALmissingwidth #1#2{%
    table#1 or cell#1 without specified width#1}

  \def \verifyPLURALother #1#2{%
    other warning#1}

  \def \verifyPLURALoverlap #1#2{%
    overlapping element#1}

  \def \verifyPLURALproprietary #1#2{%
    proprietary element#1, attribute#1 or 
      propert\ifx #1\empty y\else ies\fi \CONSTspace #2}

  \def \verifyPLURALsuperfluous #1#2{%
    superfluous end tag#1}

  \def \verifyPLURALunclosed #1#2{%
    missing end tag#1}

  \def \verifyPLURALuncolored #1#2{%
    false color#1 #2}

  \def \verifyPLURALundefclass #1#2{%
    undeclared class selector#1 #2}

  \def \verifyPLURALundefref #1#2{%
    undefined or undelimited character reference#1 #2}

  \def \verifyPLURALundelimited #1#2{%
    undelimited reference#1}

  \def \verifyPLURALunquoted #1#2{%
    attribute value#1 without quotation marks}

  \def \verifyPLURALunrecognized #1#2{%
    unrecognized element#1, attribute#1 or 
      propert\ifx #1\empty y\else ies\fi \CONSTspace #2}

  \def \verifyPLURALunsupported #1#2{%
    unsupported element#1, attribute#1 or 
      propert\ifx #1\empty y\else ies\fi \CONSTspace #2}
    
% verifyWELLFORM: ------------------------------------------------------------
    
  \nec \verifyWELLFORM
  
  \nec \verifyWELLFORMclass \verifyWELLFORMclass = 0
  
  \nec \verifyWELLFORMdiffconfused
  \nec \verifyWELLFORMdiffdeprecated
  \nec \verifyWELLFORMdiffempty
  \nec \verifyWELLFORMdiffinvalidunit
  \nec \verifyWELLFORMdiffproprietary
  \nec \verifyWELLFORMdiffuncolored
  \nec \verifyWELLFORMdiffundefclass
  \nec \verifyWELLFORMdiffundefref
  \nec \verifyWELLFORMdiffunrecognized
  \nec \verifyWELLFORMdiffunsupported
  
  \def \verifyWELLFORMdo #1#2{%
    \ifOUTPUTgutter \def \WELLFORMprobe {%
      /PageLayout /TwoColumnRight \CONSTspace }% %% Fixme: bidi
    \else \let \WELLFORMprobe \empty \fi
    \ifx \pdfcatalog \undefined \else
      \pdfcatalog {\WELLFORMprobe} openaction 
        goto page 1 {/Fit}\CONSTspace \fi
    \echo {\CONSTlongline \CONSTline \CONSThalfline}%
    \GMSendabout \GMSgoodbye 
    \message {Warnings and errors:}\verifyWELLFORMokaytrue
  %%% \ifnum #1 = 4 
      \ifnum #1 > 3 %%%
        \ifnum \verifyWELLFORMclass < 2 % no doctype declaration
          \verifyWELLFORMclass = 2 \fi \fi
      \ifx \NAMESPACE \empty \xdef \NAMESPACE {none}%
        \ifnum \verifyWELLFORMclass < 2 % no namespace declaration
          \verifyWELLFORMclass = 2 \fi \fi 
      \verifyWELLFORMdoevaluateno 
        \verifyWELLFORMtotalmisnesting \CONSTmisnesting 6 
      \verifyWELLFORMdoevaluateno
        \verifyWELLFORMtotaloverlap \CONSToverlap 6
      \verifyWELLFORMdoevaluateno 
        \verifyWELLFORMtotalsuperfluous \CONSTsuperfluous 2
      \verifyWELLFORMdoevaluateno
        \verifyWELLFORMtotalunclosed \CONSTunclosed 2
      \verifyWELLFORMdoevaluateno
        \verifyWELLFORMtotalundelimited \CONSTundelimited 2
      \verifyWELLFORMdoevaluateno
        \verifyWELLFORMtotalunquoted \CONSTunquoted 2
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotalempty {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffempty
            \verifyWELLFORMtotalempty \CONSTempty }1 {%
              \ifnum \verifyWELLFORMclass = 2 \verifyWELLFORMclass = 3 \fi}%
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotalconfused {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffconfused 
            \verifyWELLFORMtotalconfused \CONSTconfused }4 \empty
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotaldeprecated {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffdeprecated 
            \verifyWELLFORMtotaldeprecated \CONSTdeprecated}1 {%
              \ifnum \verifyWELLFORMclass = 2 \verifyWELLFORMclass = 3 \fi}%
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotalproprietary {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffproprietary 
            \verifyWELLFORMtotalproprietary \CONSTproprietary }4 \empty
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotaluncolored {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffuncolored 
            \verifyWELLFORMtotaluncolored \CONSTuncolored}1 {%
              \ifnum \verifyWELLFORMclass = 2 \verifyWELLFORMclass = 3 \fi}%
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotalundefclass {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffundefclass 
            \verifyWELLFORMtotalundefclass \CONSTundefclass }0 \empty
      \ifnum \verifyWELLFORMtotalinvalidunit > 0 
        \verifyWELLFORMdonodiff \verifyWELLFORMdiffinvalidunit 
          \verifyWELLFORMtotalinvalidunit \CONSTinvalidunit \fi
      \ifnum \verifyWELLFORMtotalduplicate > 0 
        \verifyWELLFORMdono \CONSTduplicate \fi
      \ifnum \verifyWELLFORMtotalunsupported > 0 
        \verifyWELLFORMdonodiff \verifyWELLFORMdiffunsupported 
          \verifyWELLFORMtotalunsupported \CONSTunsupported \fi
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotalunrecognized {%
          \verifyWELLFORMdonodiff \verifyWELLFORMdiffunrecognized 
            \verifyWELLFORMtotalunrecognized \CONSTunrecognized }5 \empty
      \ifnum \verifyWELLFORMtotalmissingwidth > 0 
        \verifyWELLFORMdono \CONSTmissingwidth \fi
      \ifnum \verifyWELLFORMtotalundefref > 0 
        \verifyWELLFORMdonodiff \verifyWELLFORMdiffundefref 
          \verifyWELLFORMtotalundefref \CONSTundefref \fi
      \ifnum \verifyWELLFORMtotalfallback > 0 
        \verifyWELLFORMdono \CONSTfallback \fi
      \ifnum \verifyWELLFORMtotallost > 0 
        \verifyWELLFORMdono \CONSTlost \fi
      \ifnum \verifyWELLFORMtotalabsent > 0 
        \verifyWELLFORMdono \CONSTabsent \fi
      \ifFILEtoomany \global \advance \verifyWELLFORMtotalfile by 1
        \global \advance \verifyWELLFORMtotalfile by -\NOfilemax
        \ifnum \verifyWELLFORMtotalfile > 0 
          \verifyWELLFORMdono \CONSTfilelc \fi \fi
      \verifyWELLFORMdoevaluate 
        \verifyWELLFORMtotalother {%
          \verifyWELLFORMdono \CONSTother }1 \empty
      \ifnum #2 = 0 \ifnum \verifyWELLFORMclass = 2 
        \global \verifyWELLFORMclass = 3 \fi \fi
    \ifverifyWELLFORMokay \message {none}\noecho \fi
    % add errors which are relevant for well-formedness:
    \verifyWELLFORMtotalerrors = \verifyWELLFORMtotalmisnesting
    \advance \verifyWELLFORMtotalerrors by \verifyWELLFORMtotaloverlap
    \advance \verifyWELLFORMtotalerrors by \verifyWELLFORMtotalsuperfluous
    \advance \verifyWELLFORMtotalerrors by \verifyWELLFORMtotalunclosed
    \advance \verifyWELLFORMtotalerrors by \verifyWELLFORMtotalunquoted
    \advance \verifyWELLFORMtotalerrors by \verifyWELLFORMtotalundelimited
    \ifnum \NOinput > 1
      \edef \test {\the\NOinput}
      \echo {Chained documents: \test }\fi
    \ifnum \NOinclude > 0
      \edef \test {\the\NOinclude}
      \echo {Included documents: \test }\fi
    \edef \test {\the \verifyWELLFORMtotalelements}%
    \echo {Rated elements: \test}%
    \verifyWELLFORMdoget
    \noecho \message {Namespace declaration: \NAMESPACE}%
    \noecho \message {Doctype declaration:}\verifyWELLFORMdodoctype {#1}%
    \noecho \message {Markup language:}%
    \ifGEDCOM %%%
      \ifcase \verifyWELLFORMclass
        \message {\CONSTgedcomxml \CONSTspace (-:}\or % 0
        \message {\CONSTgedcomxml \CONSTspace (-;}\or % 1
        \message {\CONSTgedcomxml \CONSTspace |-:}\or % 2
        \message {\CONSTgedcomxml \CONSTspace |-;}\or % 3
        \message {\CONSTgedcomxml \CONSTspace )-:}\or % 4
        \message {\CONSTgedcomxml\CONSTspace )-;}\else % 5
        \message {\CONSTgedcomxml \CONSTspace ()-:}\fi   
    \else
      \ifcase \verifyWELLFORMclass
        \message {\CONSTXHTMLstrict \CONSTspace (-:}\or % 0
        \message {\CONSTXHTMLtrans \CONSTspace (-;}\or % 1
        \message {\CONSTHTMLstrict \CONSTspace |-:}\or % 2
        \message {\CONSTHTMLtrans \CONSTspace |-;}\or % 3
        \message {\CONSTHTMLprop \CONSTspace )-:}\or % 4
        \message {\CONSTHTMLunknown \CONSTspace )-;}\else % 5
        \message {\CONSTHTMLirreg \CONSTspace ()-:}\fi   
    \fi \end}
  
      % Detected errors will set verifyWELLFORMclass to a number from 0 to 6:

      % 0: XHTML 1.0 strict: no unclosed tags, no superfluous tags,
      %                      no unquoted atts, no deprecated atts,
      %                      no proprietary atts, no empty atts,
      %                      no undefined classes, no other problems
      % 1: XHTML 1.0 trans.: no unclosed tags, no superfluous tags,
      %                      no unquoted atts, no proprietary atts,
      %                      no empty atts, no other problems
      % 2: HTML 4.01 strict: no proprietary atts, no deprecated atts,
      %                      no empty atts, no other problems
      % 3: HTML 4.01 trans.: no proprietary atts
      % 4: HTML proprietary: proprietary atts
      % 5: HTML unknown:     unrecocnized tags or atts
      % 6: HTML irregular:   misnested
  
      \def \verifyWELLFORMdodoctype #1{%
        \ifcase #1%
          \verifyWELLFORMdoctyperegular 0 \or 
          \verifyWELLFORMdoctyperegular 1 \or
          \verifyWELLFORMdoctyperegular 2 \or 
          \verifyWELLFORMdoctyperegular 3 \or
          \MESSAGEnone \else % 4
          \MESSAGEunrecognized \fi} % 5 

        \def \verifyWELLFORMdoctyperegular #1{%
          \ifnum \verifyWELLFORMclass < #1 \MESSAGEplausible \else
            \ifnum \verifyWELLFORMclass = #1 \MESSAGEverified \else 
              \ifnum \verifyWELLFORMclass < 6 \MESSAGEunverified \else
                \ifnum \verifyWELLFORMtotalproprietary > 0 \MESSAGEfalsified 
                \else \MESSAGEunverified \fi \fi \fi \fi} 
  
      \def \verifyWELLFORMdoevaluate #1#2#3#4{%
        \ifnum #1 > 0 #2\ifnum \verifyWELLFORMclass < #3%
          \verifyWELLFORMclass = #3\else #4\fi \fi}
        
      \def \verifyWELLFORMdoevaluateno #1#2#3{%
        \verifyWELLFORMdoevaluate {#1}{\verifyWELLFORMdono {#2}}{#3}\empty}
               
      \def \verifyWELLFORMdono #1{%
        \verifyWELLFORMokayfalse
        \ifnum \csname \CONSTtotal #1\endcsname = 1
          \echo { 1 \csname \CONSTverifyplural #1\endcsname \empty
            \verifyWELLFORMerrordiff }\else
          \echo { \the \csname \CONSTtotal #1\endcsname \CONSTspace \csname 
            \CONSTverifyplural #1\endcsname s\verifyWELLFORMerrordiff}\fi}
        
      \def \verifyWELLFORMdonodiff #1#2#3{%  
        \verifyWELLFORMdonodifferent {#1}{#2}\verifyWELLFORMdono {#3}}
   
        \def \verifyWELLFORMdonodifferent #1#2{% 
          \ifnum #1 > 1 \ifnum #1 < #2   
              \edef \verifyWELLFORMerrordiff {(\the #1\CONSTspace different)}%
            \else \let \verifyWELLFORMerrordiff \empty \fi 
          \else \ifnum #2 > 1 \let \verifyWELLFORMerrordiff \CONSTallthesame 
            \else \let \verifyWELLFORMerrordiff \empty \fi \fi}
                                        
      % Well-formedness here is defined as inverse exponential of the 
      % errors per element ratio, i. e. exp (-errors/elements):
      % exp (-x) = 1 - x + x²/2! - x³/3! +...
      % => 3000 exp (-x) = 3000 - (3000x) + (3000x)²/2000 - (3000x)³/6000 +...

      \def \verifyWELLFORMdoget {%
        \verifyWELLFORM = 3000 
        \verifyWELLFORMtotalratio = \verifyWELLFORMtotalerrors 
        \multiply \verifyWELLFORMtotalratio by 3000 
        \ifnum \verifyWELLFORMtotalelements > 0 
          \divide \verifyWELLFORMtotalratio by 
            \verifyWELLFORMtotalelements \fi
        \ifnum \verifyWELLFORMtotalerrors < 65535
          \verifyWELLFORMtotalterm = 3000
          \verifyWELLFORMdogetterm {1}{-}% 1! = 1
          \verifyWELLFORMdogetterm {2}{}% 2! = 2
          \verifyWELLFORMdogetterm {6}{-}% 3! = 6
          \verifyWELLFORMdogetterm {24}{}% 4! = 24
          \verifyWELLFORMdogetterm {120}{-}% 5! = 120
          \verifyWELLFORMdogetterm {720}{}% 6! = 720
          \verifyWELLFORMdogetterm {5040}{-}% 7! = 5040
          \divide \verifyWELLFORM by 3
          \ifnum \verifyWELLFORM < 1000 \edef \test {0.}%
            \ifnum \verifyWELLFORM < 100 \edef \test {\test 0}%
              \ifnum \verifyWELLFORM < 10 \edef \test {\test 0}%
                \ifnum \verifyWELLFORM < 0 \edef \test {0}\fi \fi \fi
            \edef \test {\test \the \verifyWELLFORM}%
          \else \edef \test {1}\fi
          \echo {Well-formedness: \test }\fi}

        \def \verifyWELLFORMdogetterm #1#2{% #1: faculty, #2:sign
          \ifnum \verifyWELLFORMtotalerrors > 0
            \multiply \verifyWELLFORMtotalterm by \verifyWELLFORMtotalratio
            \divide \verifyWELLFORMtotalterm by 3000
            \verifyWELLFORMtotalerrors = \verifyWELLFORMtotalterm
            \divide \verifyWELLFORMtotalerrors by #1
            \advance \verifyWELLFORM  by #2\verifyWELLFORMtotalerrors \fi}
        
  \def \verifyWELLFORMmessdiff #1#2#3#4#5{%
    \DEFsearch {#5#1}\ifDEF \else
      \message {! #2.}\xDef {#5#1} {}%
      \global \advance #3 by 1 \fi
    \global \advance #4 by 1 }
        
  \new \ifverifyWELLFORMokay
          
  \nec \verifyWELLFORMtotalabsent
  \nec \verifyWELLFORMtotalconfused
  \nec \verifyWELLFORMtotaldeprecated
  \nec \verifyWELLFORMtotalduplicate
  \nec \verifyWELLFORMtotalelements
  \nec \verifyWELLFORMtotalempty
  \nec \verifyWELLFORMtotalerrors
  \nec \verifyWELLFORMtotalfallback

  \nec \verifyWELLFORMtotalfile % opened input or image file

  \def \verifyWELLFORMtotalfileadvance {%
    \global \advance \verifyWELLFORMtotalfile by 2
    \ifnum \verifyWELLFORMtotalfile > \NOfilemax 
      \global \FILEtoomanytrue \message {! Ignored.}\fi
    \global \advance \verifyWELLFORMtotalfile by -1 } % Fixme: move
  
  \nec \verifyWELLFORMtotalinvalidunit
  \nec \verifyWELLFORMtotallost
  \nec \verifyWELLFORMtotalmissingwidth
  \nec \verifyWELLFORMtotalmisnesting

  \nec \verifyWELLFORMtotalother 
  \verifyWELLFORMtotalother = 0 % reset warning counter

  \def \verifyWELLFORMtotalotheradvance {%
    \message {! Warning.}%
    \global \advance \verifyWELLFORMtotalother by 1 }

  \nec \verifyWELLFORMtotaloverlap
  \nec \verifyWELLFORMtotalproprietary
  \nec \verifyWELLFORMtotalratio
  \nec \verifyWELLFORMtotalsuperfluous
  \nec \verifyWELLFORMtotalterm
  \nec \verifyWELLFORMtotalunclosed
  \nec \verifyWELLFORMtotaluncolored
  \nec \verifyWELLFORMtotalundefclass
  \nec \verifyWELLFORMtotalundefref
  \nec \verifyWELLFORMtotalundelimited

  \nec \verifyWELLFORMtotalunquoted

  \def \verifyWELLFORMtotalunquotedadvance {%
    \global \advance \verifyWELLFORMtotalunquoted by 1 }

  \nec \verifyWELLFORMtotalunrecognized
  \nec \verifyWELLFORMtotalunsupported  

\message {win-entities.} %====================================================

% HTML entities that are contained in Windows codepages:

\def \WINamp {26}% 38
\def \WINbdquo {84}% 8222
\def \WINbull {95}% 8226
\def \WINcirc {88}% 710
\def \WINdagger {86}% 8224
\def \WINDagger {87}% 8225
\def \WINeuro {80}% 8364
\def \WINfnof {83}% 402
\def \WINgt {3E}% 62
\def \WINhellip {85}% 8230
\def \WINlt {3C}% 60
\def \WINldquo {93}% 8220
\def \WINlsaquo {8B}% 8249
\def \WINlsquo {91}% 8216
\def \WINmdash {97}% 8212
\def \WINndash {96}% 8211
\def \WINOElig {8C}% 338
\def \WINoelig {9C}% 339
\def \WINpermil {89}% 8240
\def \WINrdquo {94}% 8221
\def \WINrsaquo {9B}% 8250
\def \WINrsquo {92}% 8217
\def \WINsbquo {82}% 8218
\def \WINScaron {8A}% 352
\def \WINscaron {9A}% 353
\def \WINtilde {98}% 732
\def \WINtrade {99}% 8482
\def \WINYuml {9F}% 376
\def \WINZcaron {8E}% 381
\def \WINzcaron {9E}% 382

% Unicode references that are contained in Windows codepages:

% Fixme: use definition macro 

\Def WIN338 {\GAPsegmentappend {\char "8C\REFERENCErelax }}% OElig
\Def WIN339 {\GAPsegmentappend {\char "9C\REFERENCErelax }}% oelig
\Def WIN352 {\GAPsegmentappend {\char "8A\REFERENCErelax }}% Scaron
\Def WIN353 {\GAPsegmentappend {\char "9A\REFERENCErelax }}% scaron
\Def WIN376 {\GAPsegmentappend {\char "9F\REFERENCErelax }}% Yuml
\Def WIN381 {\GAPsegmentappend {\char "8E\REFERENCErelax }}% Zcaron
\Def WIN382 {\GAPsegmentappend {\char "9E\REFERENCErelax }}% zcaron
\Def WIN402 {\GAPsegmentappend {\char "83\REFERENCErelax }}% fnof
\Def WIN710 {\GAPsegmentappend {\char "88\REFERENCErelax }}% circ
\Def WIN8211 {\GAPsegmentappend {\char "96\REFERENCErelax }}% ndash
\Def WIN8212 {\GAPsegmentappend {\char "97\REFERENCErelax }}% mdash
\Def WIN8216 {\GAPsegmentappend {\char "91\REFERENCErelax }}% lsquo
\Def WIN8217 {\GAPsegmentappend {\char "92\REFERENCErelax }}% rsquo
\Def WIN8218 {\GAPsegmentappend {\char "82\REFERENCErelax }}% sbquo
\Def WIN8220 {\GAPsegmentappend {\char "93\REFERENCErelax }}% ldquo
\Def WIN8221 {\GAPsegmentappend {\char "94\REFERENCErelax }}% rdquo
\Def WIN8222 {\GAPsegmentappend {\char "84\REFERENCErelax }}% bdquo
\Def WIN8224 {\GAPsegmentappend {\char "86\REFERENCErelax }}% dagger
\Def WIN8225 {\GAPsegmentappend {\char "87\REFERENCErelax }}% Dagger
\Def WIN8226 {\GAPsegmentappend {\char "95\REFERENCErelax }}% bull
\Def WIN8230 {\GAPsegmentappend {\char "85\REFERENCErelax }}% hellip
\Def WIN8240 {\GAPsegmentappend {\char "89\REFERENCErelax }}% permil
\Def WIN8249 {\GAPsegmentappend {\char "8B\REFERENCErelax }}% lsaquo
\Def WIN8250 {\GAPsegmentappend {\char "9B\REFERENCErelax }}% rsaquo
\Def WIN8364 {\GAPsegmentappend {\char "80\REFERENCErelax }}% euro
\Def WIN8482 {\GAPsegmentappend {\char "99\REFERENCErelax }}% trade

% 3. Markup ##################################################################
 
\echo {- Recognized attributes:} %============================================

% A lot of attributes are only made known to Markup Shredder to enable the
% doctype check, without giving functional support:

\NEWattquiet abbr
\NEWatttagunsupported abbr td
\NEWatttagunsupported abbr th

\NEWattquiet accept
\NEWatttagunsupported accept form
\NEWatttagunsupported accept input

\NEWattquiet accept-charset
\NEWatttagunsupported accept-charset form

\NEWattquiet accesskey
\NEWatttagunsupported accesskey a
\NEWatttagunsupported accesskey area
\NEWatttagunsupported accesskey button
\NEWatttagunsupported accesskey input
\NEWatttagunsupported accesskey label
\NEWatttagunsupported accesskey legend
\NEWatttagunsupported accesskey textarea

\NEWattquiet action
\NEWatttagunsupported action form

\NEWatt align
\NEWatttagtemplate align applet img
\NEWatttagtemplate align caption table
\NEWatttag align col \ALIGNtextbyvalue
\NEWatttagtemplate align colgroup col
\NEWatttagtemplate align div col
\NEWatttagtemplate align h1 col
\NEWatttagtemplate align h2 col
\NEWatttagtemplate align h3 col
\NEWatttagtemplate align h4 col
\NEWatttagtemplate align h5 col
\NEWatttagtemplate align h6 col
\NEWatttagtemplate align hr col
\NEWatttagtemplate align iframe img 
\NEWatttagdeprecated align img {\VALUEsetlowercase \IMAGEalign}     
\NEWatttagtemplate align input img
\NEWatttagtemplate align legend img
\NEWatttagtemplate align object img
\NEWatttagdeprecated align p \ALIGNtextbyvalue
\NEWatttagdeprecatedunsupported align pre 
\NEWatttagdeprecated align table {\VALUEset \TABLEalign}
\NEWatttagtemplate align tbody col
\NEWatttagtemplate align td col
\NEWatttagtemplate align tfoot col
\NEWatttagtemplate align th col
\NEWatttagtemplate align thead col
\NEWatttagtemplate align tr col

\NEWattquiet alink % active link color unused
\NEWatttagdeprecated alink body \empty

\NEWatt alt
\NEWatttagdeprecated alt applet \TAGimgATTalt
\NEWatttagtemplate alt area img
\NEWatttag alt img {\VALUEsetrelax \IMAGEalt \MESSAGEvalue}
\NEWatttagtemplate alt input img

\NEWattquiet aoff

\NEWattquiet archive
\NEWatttagdeprecatedunsupported archive applet
\NEWatttagunsupported archive object

\NEWattquiet axis
\NEWatttagunsupported axis td
\NEWatttagunsupported axis th

\NEWatt background
\NEWatttagdeprecated background body {%
  \BACKGROUNDsourceset \BACKGROUNDload \COLORbgbodytrue}

\NEWatt bgcolor
\NEWatttagdeprecated bgcolor body \COLORsetbgbody
\NEWatttagdeprecated bgcolor table {\COLORsetbgtable \COLORbordertrue}
\NEWatttagtemplate bgcolor td table
\NEWatttagtemplate bgcolor th table
\NEWatttagtemplate bgcolor tr table

\NEWatt border
\NEWatttagdeprecated border img \BORDERset
\NEWatttagtemplate border object img  
\NEWatttag border table \BORDERset

\NEWattproprietary bordercolor
\NEWattproprietary bordercolordark 
\NEWattproprietary bordercolorlight

\NEWattquiet bottommargin

\NEWatt cellpadding
\NEWatttag cellpadding table \PROPpadding

\NEWatt cellspacing
\NEWatttag cellspacing table \PROPmargin

\NEWattquiet char
\NEWatttagunsupported char col
\NEWatttagunsupported char colgroup
\NEWatttagunsupported char tbody
\NEWatttagunsupported char td
\NEWatttagunsupported char tfoot
\NEWatttagunsupported char th
\NEWatttagunsupported char thead
\NEWatttagunsupported char tr

\NEWattquiet charoff
\NEWatttagunsupported charoff col
\NEWatttagunsupported charoff colgroup
\NEWatttagunsupported charoff tbody
\NEWatttagunsupported charoff td
\NEWatttagunsupported charoff tfoot
\NEWatttagunsupported charoff th
\NEWatttagunsupported charoff thead
\NEWatttagunsupported charoff tr

\NEWattquiet charset
\NEWatttagunsupported charset a
\NEWatttagunsupported charset link
\NEWatttagunsupported charset script

\NEWattquiet checked
\NEWatttagunsupported checked input

\NEWattquiet cite
\NEWatttagunsupported cite blockquote
\NEWatttagunsupported cite del
\NEWatttagunsupported cite ins
\NEWatttagunsupported cite q

\message {class,}
  % Fixme: proprietary for base, basefont, head, html, meta,
  % param, script, style, title

\NEWattquiet classid
\NEWatttagunsupported classid object

\NEWattquiet clear
\NEWatttagdeprecatedunsupported clear br {%
  \VALUElowercaseget 
  \ifLINKunrendered \else
    \ifx \VALUElowercase \CONSTall 
      \par \vfil \FLOATindentnone \fi \fi}

\NEWattdef code \empty % Gedcom
\NEWatttagdeprecatedunsupported code applet

\NEWattquiet codebase
\NEWatttagdeprecatedunsupported codebase applet
\NEWatttagunsupported codebase object

\NEWattquiet codetype
\NEWatttagunsupported codetype object

\NEWatt color
\NEWatttagdeprecated color basefont \COLORsetforeground
\NEWatttagdeprecated color font \COLORsetforeground

\NEWattquiet cols
\NEWatttagnotstrictunsupported frameset cols
\NEWatttagunsupported cols textarea

\NEWatt colspan
\NEWatttag colspan td {\SPANcolpost \BOXwidthdefault}
\NEWatttag colspan th {\SPANcolpost \BOXwidthdefault}

\NEWatt compact
\NEWatttagdeprecatedunsupported compact dir
\NEWatttagdeprecated compact dl \OPENdlcompacttrue
\NEWatttagdeprecatedunsupported compact menu
\NEWatttagdeprecatedunsupported compact ol
\NEWatttagdeprecatedunsupported compact ul

\NEWatt content
\NEWatttag content meta {\VALUEset \metacontent} % Fixme: \METAcontent?

\NEWattquiet coords
\NEWatttagunsupported coords a
\NEWatttagunsupported coords area

\NEWatt data
\NEWatttag data object {\VALUEset \URLhref}

\NEWattquiet datetime
\NEWatttagunsupported datetime del
\NEWatttagunsupported datetime ins

\NEWattquiet declare
\NEWatttagunsupported declare object

\NEWattquiet defer
\NEWatttagunsupported defer script

\NEWatt dir
\NEWattdef dir \BIDIsetone % sic!
\NEWatttagproprietaryunsupported dir basefont
\NEWatttagproprietaryunsupported dir br
\NEWatttagproprietaryunsupported dir frame
\NEWatttagproprietaryunsupported dir frameset
\NEWatttagproprietaryunsupported dir iframe
\NEWatttagproprietaryunsupported dir param
\NEWatttagproprietaryunsupported dir script

\NEWattquiet disabled
\NEWatttagunsupported disabled button
\NEWatttagunsupported disabled input
\NEWatttagunsupported disabled optgroup
\NEWatttagunsupported disabled option
\NEWatttagunsupported disabled select
\NEWatttagunsupported disabled textarea

\NEWattquiet enctype
\NEWatttagunsupported enctype form

\NEWatt face
\NEWatttagdeprecated face basefont {\FONTfamily = \VALUE \FONTchoose}
\NEWatttagtemplate face font basefont

\NEWattquiet font-weight

\NEWattquiet for
\NEWatttagunsupported for label

\NEWattquiet frame
\NEWatttagunsupported frame table

\NEWattquiet frameborder
\NEWatttagnotstrictunsupported frameborder frame
\NEWatttagnotstrictunsupported frameborder iframe

\NEWattproprietary framespacing

\NEWattquiet guid

\NEWattquiet headers
\NEWatttagunsupported headers td
\NEWatttagunsupported headers th

\NEWatt height
\NEWatttagtemplate height applet td
\NEWatttagnotstrict height iframe \TAGimgATTheight
\NEWatttag height img {\VALUEdimenset \IMAGEheight \vsize}
\NEWatttagtemplate height object img
\NEWatttagdeprecated height td {%
  \VALUEdimenset \BOXheight \vsize \BOXheightgiventrue}
\NEWatttagtemplate height th td
\NEWatttagproprietary height tr \TAGtdATTheight

\NEWattquiet hover

\NEWatt href
\NEWatttag href a {\VALUEset \URLhref}
\NEWatttagtemplate href area a
\NEWatttagtemplate href base a
\NEWatttagtemplate href link a
\NEWatttagtemplate href xml-stylesheet a %%%

\NEWattquiet hreflang
\NEWatttagunsupported hreflang a
\NEWatttagunsupported hreflang link

\NEWattquiet hspace
\NEWatttagdeprecatedunsupported hspace applet 
\NEWatttagdeprecatedunsupported hspace img
\NEWatttagdeprecatedunsupported hspace object

\NEWatt http-equiv
\NEWatttag http-equiv meta {\VALUEset \metahttpequiv} % Fixme: \META...?

\NEWatt id
\NEWattdef id {\VALUEset \LINKid
  \let \LINKname \LINKid
  \ifx \LINKname \empty \else \ANCHORbyname \LINKname \fi}
\NEWatttagproprietaryunsupported id base
\NEWatttagproprietaryunsupported id head
\NEWatttagproprietaryunsupported id html
\NEWatttagproprietaryunsupported id meta
\NEWatttagproprietaryunsupported id script
\NEWatttagproprietaryunsupported id style
\NEWatttagproprietaryunsupported id title

\NEWattproprietary ids

\NEWattquiet ismap
\NEWatttagunsupported ismap img
\NEWatttagunsupported ismap input

\NEWattquiet label
\NEWatttagunsupported label option
\NEWatttagunsupported label optgroup 

\NEWatt lang
\NEWattdef lang {\VALUEset \LANGUAGEabbreviation \LANGUAGEset}
\NEWatttagproprietaryunsupported lang applet
\NEWatttagproprietaryunsupported lang base
\NEWatttagproprietaryunsupported lang basefont
\NEWatttagproprietaryunsupported lang br
\NEWatttagproprietaryunsupported lang frame
\NEWatttagproprietaryunsupported lang frameset
\NEWatttagproprietaryunsupported lang iframe
\NEWatttagproprietaryunsupported lang param
\NEWatttagproprietaryunsupported lang script

\NEWatt language
\NEWatttagdeprecated language script \SCRIPTset

\NEWattquiet leftmargin

\NEWattquiet link % unvisited link color used for external links
\NEWatttagdeprecated link body \COLORsetlink

\NEWattquiet longdesc
\NEWatttagnotstrictunsupported longdesc frame
\NEWatttagnotstrictunsupported longdesc iframe
\NEWatttagunsupported longdesc img

\NEWattquiet lowsrc

\NEWattproprietary marginbottom 

\NEWattquiet marginheight
\NEWatttagnotstrictunsupported marginheight frame 
\NEWatttagnotstrictunsupported marginheight iframe

\NEWattproprietary marginleft

\NEWattproprietary marginright

\NEWattproprietary margintop 

\NEWattquiet marginwidth
\NEWatttagnotstrictunsupported marginwidth frame
\NEWatttagnotstrictunsupported marginwidth iframe

\NEWattquiet maxlength
\NEWatttagunsupported maxlength input

\NEWatt media
\NEWatttag media link {\VALUEsetlowercase \LINKmedia}
\NEWatttagtemplate media style link

\NEWattquiet menu

\NEWattdef method \empty % Gedcom
\NEWatttagunsupported method form

\NEWattquiet multiple
\NEWatttagunsupported multiple select

\NEWatt name
\NEWatttag name a {\VALUEset \LINKname}
\NEWatttagdeprecated name applet \MESSAGEvalue
\NEWatttagnotstrict name frame \MESSAGEvalue
\NEWatttagnotstrict name iframe \MESSAGEvalue
\NEWatttag name img \MESSAGEvalue
\NEWatttag name input \MESSAGEvalue
\NEWatttag name map \MESSAGEvalue
\NEWatttag name object \MESSAGEvalue
\NEWatttag name param \MESSAGEvalue
\NEWatttag name map \MESSAGEvalue
\NEWatttag name meta {\VALUEset \metaname} % Fixme: \METAname?
\NEWatttag name select \MESSAGEvalue
\NEWatttag name textarea \MESSAGEvalue

\NEWattproprietary newvalues

\NEWattquiet nohref
\NEWatttagunsupported nohref area

\NEWattquiet noresize
\NEWatttagnotstrictunsupported noresize frame

\NEWattquiet noshade
\NEWatttagdeprecatedunsupported noshade hr

\NEWattquiet nowrap
\NEWatttagdeprecatedunsupported nowrap td
\NEWatttagdeprecatedunsupported nowrap th

\NEWattquiet object
\NEWatttagdeprecatedunsupported object applet

% Fixme: proprietary for several elements:
\NEWattunsupported onblur
\NEWattunsupported onchange
\NEWattunsupported onclick
\NEWattproprietary oncopy
\NEWattunsupported ondblclick
\NEWattunsupported onfocus
\NEWattunsupported onkeydown
\NEWattunsupported onkeypress
\NEWattunsupported onkeyup   
\NEWattnotstrictunsupported onload   
\NEWattunsupported onmousedown
\NEWattunsupported onmousemove
\NEWattunsupported onmouseout
\NEWattunsupported onmouseover
\NEWattunsupported onmouseup   
\NEWattunsupported onreset
\NEWattunsupported onselect
\NEWattunsupported onsubmit   
\NEWattnotstrictunsupported onunload

\NEWattquiet point-size

\NEWattquiet profile
\NEWatttagunsupported profile head

\NEWattquiet prompt
\NEWatttagdeprecatedunsupported prompt isindex

\NEWattquiet readonly
\NEWatttagunsupported readonly input

\NEWattquiet ref
\NEWatttag ref link {%
  \ifGEDCOM \VALUEset \URLhref \else \VERIFYerrorproprietaryatt {ref}\fi}

\NEWatt rel
\NEWatttag rel a \empty
\NEWatttag rel link {\VALUEsetlowercase \LINKrel}

\NEWatt rev
\NEWatttagunsupported rev a
\NEWatttagunsupported rev link

\NEWattquiet rightmargin

\NEWattquiet rows
\NEWatttagnotstrictunsupported rows frameset
\NEWatttagunsupported rows textarea

\NEWatt rowspan % Fixme: rowspan needed before class attribute in 3c2stagl.htm
\NEWatttag rowspan td {\SPANrowpost \BOXspancolexec \BOXfillerbottom}
\NEWatttag rowspan th {\SPANrowpost \BOXspancolexec \BOXfillerbottom} 

\NEWattquiet rules
\NEWatttagunsupported rules table

\NEWattquiet scheme
\NEWatttagunsupported meta scheme

\NEWattquiet scope
\NEWatttagunsupported scope td
\NEWatttagunsupported scope th

\NEWattquiet scrolling
\NEWatttagnotstrictunsupported scrolling frame
\NEWatttagnotstrictunsupported scrolling iframe

\NEWattquiet selected
\NEWatttagunsupported selected option

\NEWattquiet shape
\NEWatttagunsupported shape a
\NEWatttagunsupported shape area

\NEWatt size
\NEWatttagdeprecated size basefont {\SIZEswitch {\the \VALUE}}
\NEWatttagtemplate size font basefont 
\NEWatttagunsupported size hr
\NEWatttag size input {\VALUEintegerset \INDENTinputsize}
\NEWatttagtemplate size select input 

\NEWatt span
\NEWatttagtemplate span col colgroup
\NEWatttag span colgroup \SPANcolgroupset

\NEWatt src
\NEWatttagnotstrict src frame {\VALUEset \URLhref}
\NEWatttag src img {\VALUEset \URLhref}
\NEWatttagtemplate src iframe frame
\NEWatttagtemplate src input img
\NEWatttagtemplate src script img

\NEWattunsupported standby

\NEWatt start
%\NEWatttagdeprecated start ol {\VALUEintegerset \NOli 
%  \VERIFYerrorunsuppattprop \CONSTstart} %%% Fixme: used in tds.htm 

\message {style,}
  % Fixme: style is proprietary for base, basefont, head, html, meta,
  % param, script, style, title. 

\NEWatt summary
\NEWatttag summary table \TABLEsummaryset

\NEWattquiet tabindex
\NEWatttagunsupported tabindex a
\NEWatttagunsupported tabindex a
\NEWatttagunsupported tabindex area
\NEWatttagunsupported tabindex button
\NEWatttagunsupported tabindex input
\NEWatttagunsupported tabindex object
\NEWatttagunsupported tabindex select
\NEWatttagunsupported tabindex textarea

\NEWattquiet target
\NEWatttagnotstrict target a \empty
\NEWatttagnotstrict target area \empty
\NEWatttagnotstrict target base \empty
\NEWatttagnotstrict target form \empty
\NEWatttag target link {\ifGEDCOM \else \VERIFYnotstrictatt \fi} 

\NEWattproprietary test

\NEWatt text
\NEWatttagdeprecated text body \COLORsetforeground
  
\NEWatt title
\NEWattdef title \MESSAGEvalue
\NEWatttag title a \empty
\NEWatttag title abbr \empty
\NEWatttag title acronym \empty
\NEWatttag title b \empty
\NEWatttagproprietaryunsupported title base
\NEWatttagproprietaryunsupported title basefont
\NEWatttagproprietaryunsupported title head
\NEWatttagproprietaryunsupported title html
\NEWatttag title i \empty
\NEWatttagproprietaryunsupported title meta
\NEWatttagproprietaryunsupported title param
\NEWatttagproprietaryunsupported title script
\NEWatttag title span \empty
\NEWatttagproprietaryunsupported title title

\NEWattquiet topmargin

\NEWattdef type \empty % Gedcom
\NEWatttagtemplate type a link
\NEWatttagunsupported type button
\NEWatttag type input {\VALUEsetlowercase \INDENTinputtype}
\NEWatttagdeprecatedunsupported type li
\NEWatttag type link {\VALUEset \LINKtype}
\NEWatttag type object {\VALUEset \OBJECTtype}
\NEWatttagdeprecatedunsupported type ol
\NEWatttagtemplate type param link
\NEWatttag type script {\VALUEset \SCRIPTtype}
\NEWatttagtemplate type style link
\NEWatttagdeprecatedunsupported type ul
\NEWatttagtemplate type xml-stylesheet link %%%

\NEWattquiet url   

\NEWattquiet usemap
\NEWatttagunsupported usemap img
\NEWatttagunsupported usemap input
\NEWatttagunsupported usemap object

\NEWatt valign
\NEWatttag valign col \BOXvalignset
\NEWatttagtemplate valign colgroup col
\NEWatttagtemplate valign tbody col
\NEWatttagtemplate valign td col
\NEWatttagtemplate valign tfoot col
\NEWatttagtemplate valign th col
\NEWatttagtemplate valign thead col
\NEWatttagtemplate valign tr col

\NEWatt value
\NEWatttagtemplate value button input
\NEWatttag value input {\VALUEset \INDENTinputvalue}
\NEWatttagtemplate value li input
\NEWatttagtemplate value option input
\NEWatttagtemplate value param input

\NEWattquiet valuetype
\NEWatttagunsupported valuetype param

\NEWattquiet version
\NEWatttagdeprecatedunsupported version html 

\NEWattquiet visibility

\NEWatt vlink % visited link color used for internal links 
\NEWatttagdeprecated vlink body \COLORsetvlink

\NEWattquiet vspace
\NEWatttagdeprecatedunsupported vspace applet
\NEWatttagdeprecatedunsupported vspace img
\NEWatttagdeprecatedunsupported vspace object

\NEWatt width 
\NEWatttagtemplate width applet td
\NEWatttag width col {\TAGtableATTwidth \BOXspancolexec}
\NEWatttagtemplate width colgroup col
\NEWatttagdeprecated width hr {\VALUEdimenset \BOXwidth \hsize}
\NEWatttagnotstrict width iframe {\VALUEdimenset \IMAGEwidth \hsize}
\NEWatttag width img {\VALUEdimenset \IMAGEwidth \hsize}
\NEWatttagtemplate width object img
\NEWatttagtemplate width pre td
\NEWatttag width table {%
  \VALUEdimenset \BOXwidth \hsize \BOXwidthgiventrue}
\NEWatttagdeprecated width td {\TAGtableATTwidth \BOXspancolexec}
\NEWatttagtemplate width th td

\NEWattproprietary wrap

\NEWattdef xmlns {\VALUEsetglobal \NAMESPACE}
\NEWattdef xmlns:html {\VALUEsetglobal \NAMESPACE}
  
\NEWattproprietary xmlns:utility  

\NEWattdef xml:lang \ATTlang
\NEWattunsupported xml:space

\message {...}

\echo {- Pre-defined classes:} %==============================================

% Fixme: outsource

\message {break,}
  \def \CLASSbreak {\VALUE = {always}%
    \csname PROPpage-break-before\endcsname}

\message {breakifeven,}
  \def \CLASSbreakifeven {%
    \ifodd \OUTPUTnopage \else \VALUE = {always}%
      \csname PROPpage-break-before\endcsname \fi}

\message {breakifodd,}
  \def \CLASSbreakifodd {%
    \ifodd \OUTPUTnopage \VALUE = {always}%
      \csname PROPpage-break-before\endcsname \fi}
      
\message {kerning,}%
  \def \CLASSkerning {%
    \KERNINGtrue \KERNINGcheck}

\message {nofloat,}%
  \let \CLASSnofloat \OPENfloatsuppresstrue

\message {noindent,}%
  \def \CLASSnoindent {\TEXTindent = 0pt }

\message {nokerning,}%
  \def \CLASSnokerning {%
    \KERNINGfalse \KERNINGcheckback}

\message {nolink,}%
  \let \CLASSnolink \LINKunlinkedtrue

\message {nopagenumbers,}%
  \def \CLASSnopagenumbers {%
    \global \OUTPUTnopagedofalse \global \OUTPUTnopagedonttrue}

\message {noprint,}%
  \let \CLASSnoprint \LINKunrenderedtrue

\message {noscreen,}%
  \let \CLASSnoscreen \empty

\message {pagenumbers,}%
  \def \CLASSpagenumbers {%
    \global \OUTPUTnopagedotrue \global \OUTPUTnopagedontfalse}

\message {twocolumns.}%
  \let \CLASStwocolumns \OUTPUTdoubletrue

\echo {- Block-level elements:} %=============================================

\ELEMENTnew address
  \beforestart \GAPwrite
  \openstart \ELEMENTvalueget \FONTdo
    \BIDIbegin \afterstart
  \beforeend \GAPwrite \ALIGNend \BIDIend \par 
  \closeend \MESSAGEdot \afterend
  
\ELEMENTnewblock blockquote % Fixme: alignments not supported
  \beforestart \openstart 
  \initstart \advance \leftskip by 2\LINEheight \advance \leftskip by -1ex
    \advance \rightskip by 2\LINEheight \advance \rightskip by -1ex 
    \NOparreset \afterstart \beforeend 
  \closeend \NOparresetglobal \afterend

\ELEMENTnew body
  \beforestart \noecho
  \openstart \OUTPUTbody \CONSTbody \afterstart
  \beforeend \GAPwrite \par \LINEupskip
    \ifOPENobject \else 
      \global \COLORfalse    
      \global \COLORbgfalse       
      \vfill \break \fi
  \closeend \afterend
  
\Def TAGbr/ {%
  \TAGbrexec \VERIFYerrormissingspace}
\def \TAGbr {%
  \TAGbrexec \MESSAGEendemptytag}
  \def \TAGbrexec {%
    \MESSAGEbr \ELEMENTcount \ELEMENTvalueget \GAPwrite 
    \ifLINKunrendered \else    
      \ifGAPspacenow \hskip -\spaceskip \fi %%%
%%%   \GAPwritedonospacetrue 
%%%   \strut 
      \ALIGNend 
      \break
      \global \GAPspacenowtrue \fi}
\Def TAG/br {\relax}
    
\ELEMENTnew caption
  \beforestart \ifGEDCOM \GAPwrite \fi
  \openstart 
    \ifGEDCOM \ELEMENTblockfalse \ELEMENTvalueget
      \ifELEMENTblock \par \FLOATindentnone \fi
    \else \BORDERreset \ELEMENTvalueget \fi
    \afterstart
  \beforeend \GAPwrite \ifGEDCOM \else \par \fi   
  \closeend \afterend
  
\ELEMENTnewblock center
  \beforestart 
  \openstart \ALIGNtextcenter 
  \initstart \OUTPUTdoublebegin 
    \VERIFYerrordeprecated \CONSTcenter \afterstart 
  \beforeend \OUTPUTdoubleend
  \closeend \NOparreset \afterend
  
\Message {col /}
\def \TAGcol {%
  \MESSAGEcol \ELEMENTvalueget \SPANcolnoadvance 
  \BOXspancolexec \MESSAGEendemptytag}   

\ELEMENTnew colgroup
  \beforestart \SPANcolgroupinit \ELEMENTvalueget 
  \openstart \SPANcolgroupexec \afterstart \beforeend
  \closeend \MESSAGEhyphen \afterend

\ELEMENTnewblock dd
  \beforestart \nobreak
  \openstart \NOparreset \LISTnoddlastsetglobal 
    \LISTleftmarginset \FONTitalictrue  
  \initstart \FONTmodechange \afterstart
  \beforeend \closeend \afterend
  
\ELEMENTnewblock div
  \beforestart \noecho \openstart 
    \global \hangindent = 0pt \global \hangafter = 0 %%%
  \initstart \OUTPUTdoublebegin \afterstart 
  \beforeend \OUTPUTdoubleend \closeend \afterend
    
\ELEMENTnewblock dl
  \beforestart \noecho 
    \hangindent = 0pt \hangafter = 0 %%%
  \openstart \OPENddfalse \OPENdtfalse \LISTnostart \initstart 
  \afterstart \beforeend
  \closeend \NOparresetglobal \afterend     

\ELEMENTnewblock dt
  \beforestart 
  \openstart \FONTboldtrue \FONTmodechange \LISTleftmarginsetdt
  \initstart \afterstart 
  \beforeend \nobreak
    \ifOPENdlcompact \LINEupskip \CONSTspace \fi  
    \nobreak \closeend \afterend

\ELEMENTnewblockh 1 5 3 3    1
\ELEMENTnewblockh 2 4 3 2.25 0.75
\ELEMENTnewblockh 3 3 2 2.25 0.75
\ELEMENTnewblockh 4 2 2 1.5  0.5
\ELEMENTnewblockh 5 1 2 0.75 0.25
\ELEMENTnewblockh 6 0 1 0.75 0.25
\let \ELEMENTnewblockh \undefined

\Def TAGhr/ {%
  \GAPwrite \TAGhrexec \ELEMENTvalueget \TAGhrexecindent 
  \VERIFYerrormissingspace \MESSAGEendemptytag}
\def \TAGhr {%
  \GAPwrite \TAGhrexec \ELEMENTvalueget \TAGhrexecindent 
  \MESSAGEendemptytag}  
  \def \TAGhrexec {%
    \strut \ELEMENTcount
    \ifOPENp \par \fi
    \ifOPENtd \vskip -0,67\LINEheight  % <hr /> is allowed inside <li>.
    \else \ifOPENth \vskip -0,67\LINEheight \fi \fi
    \MESSAGEhr % Fixme: misplaced
    \ifLINKunrendered \let \backupunrend \empty 
   \else \let \backupunrend \undefined \fi
    \bgroup \BOXwidth  = \hsize}
  \def \TAGhrexecindent {%
    \ifLINKunrendered \else
      \ifhmode \par \fi
      \centerline {\vbox to \LINEheight {%
        \vss \COLORizeforeground
        \hrule width \BOXwidth height 0.033\LINEheight \vss}}%
      \NOparresetglobal \fi \egroup
    \ifOPENtd \vskip -0.33\LINEheight \fi
    \ifx \backupunrend \undefined \LINKunrenderedfalse \fi}
\Def TAG/hr {\relax}

\ELEMENTnew iframe
  \beforestart 
  \openstart \VERIFYnotstrict \OPENobjecttrue 
    \ELEMENTvalueget \CHAINobjectloadurl
    \MESSAGEgt \MESSAGEinclinebegin \MESSAGElt \CHAINiftable \afterstart 
  \beforeend \MESSAGEinclineend %%%
  \closeend \global \ENDfalse \beginmarkupCAT \afterend % Fixme: \global args
  
\Message {img /}
\def \TAGimg {%
  \MESSAGEimg \ELEMENTcount 
% \ifOPENpre \ifGAPfilled \else 
%   \LINEupskip \hskip -2\LINEheight \hskip 1ex \fi \fi
  \GAPwrite \IMAGEinit \ALIGNfalse 
  \ELEMENTvalueget \IMAGErun \MESSAGEendemptytag}

\Message {input /}
\Def TAGinput/ {%
  \GAPwrite \MESSAGEinput \ELEMENTvalueget
  \TAGinputindent \VERIFYerrormissingspace \MESSAGEendemptytag}
\def \TAGinput {%
  \ELEMENTcount \GAPwrite \MESSAGEinput \ELEMENTvalueget
  \TAGinputindent \MESSAGEendemptytag}
  \def \TAGinputindent {%
    \ifLINKunrendered \else
      \ifx \INDENTinputtype \empty \TAGinputindenttext \else
      \ifx \INDENTinputtype \CONSTtext \TAGinputindenttext \fi \fi \fi} 
    \def \TAGinputindenttext {% Fixme: handle \VALradio and \VALcheckbox too
      \ifvmode \FLOATindentnone \fi
      \INDENTinputvalue \leaders \hrule \hfill \CONSTspace
      \ifOPENtable \else \par \fi}
\Def TAG/input {\relax}

\ELEMENTnewblock li
  \beforestart \NOparreset \MESSAGEli
  \openstart \LISTnolastsetglobal 
  \initstart \LISTleftmarginset \LISTmark \afterstart \beforeend 
  \closeend \LISTnoadvance \LISTpenalty \afterend  
  
\ELEMENTnewblock map
  \beforestart 
  \openstart \OPENpfalse 
  \initstart \VERIFYerrorunsupported \CONSTmap 
  \afterstart \beforeend \closeend \afterend

\ELEMENTnew object
  \beforestart 
  \openstart \OBJECTinit \ELEMENTvalueget \OBJECThandle
  \MESSAGEinclinebeginobject \afterstart
  \beforeend \OPENobjectfalse \MESSAGEinclineendobject
  \closeend \global \ENDfalse \beginmarkupCAT \afterend

\ELEMENTnewblock ol
  \beforestart \noecho 
    \hangindent = 0pt \hangafter = 0 %%%
  \openstart \LISTnostart %%%
  \initstart \afterstart \beforeend
  \closeend \NOparresetglobal \afterend
    
\ELEMENTnew option
  \beforestart
  \openstart 
    \ifLINKunrendered \else \par
      \FLOATindentnone \hskip -\LINEheight
      \COLORize {\the \COLORuldot \CONSTspace rg 
        \the \COLORuldot \CONSTspace RG}%
      \hbox {\vbox {\hrule height 0.1ex 
        \hbox to 0.8ex {\vrule width 0.1ex
          \hfil \vbox to 0.8ex {\vfil }\hfil
          \vrule width 0.1ex }\hrule height 0.1ex }}%
      \hskip \LINEheight \hskip -1ex \fi  
  \afterstart 
  \beforeend \par \closeend \afterend
      
\ELEMENTnewblock p 
  \beforestart \NOparadvance
  \openstart \NOparlastsetglobal 
  \initstart \ifLINKunrendered \else 
     \ifTEXTindentgiven \FLOATindent \else \ELEMENTblockindentbyno \fi \fi 
  \afterstart \beforeend 
  \closeend \MESSAGEdot \afterend   

\ELEMENTnewblock pre % Fixme: alignments not supported
  \beforestart \NOparadvance 
  \openstart 
    \GAPobeytrue 
    \advance \leftskip by 2\LINEheight
    \advance \leftskip by -1ex
    \parindent = 0mm 
    \FONTdomono \OBEYobeylines \OBEYobeyspaces \initstart
  \afterstart \beforeend
  \closeend \OBEYend \afterend
    
\ELEMENTnewblock select
  \beforestart 
  \openstart \advance \leftskip by 2\LINEheight 
    \advance \leftskip by -1ex 
  \initstart \afterstart \beforeend \closeend \afterend
  
\ELEMENTnew table
  \beforestart \MESSAGEhyphen
    \MESSAGEtableline
  \openstart \TABLEinit \BOXinit \ELEMENTvalueget 
    \ifLINKunrendered \else %%%
      \GAPsetstrut \MESSAGEkerning
      \TABLEnestingadvance \FLOATtablealign \TABLEsummarycheck
      \BOXlineheightset \SPANlayout \TABLEbegin \BOXindent \fi
    \afterstart 
  \beforeend 
    \ifLINKunrendered \else %%%
      \TABLEendhandle \par \FLOATtable \SPANrowclear \fi
  \closeend   
    \ifLINKunrendered \else %%%
      \ifOPENtd \LINEupskip \else \ifOPENth \LINEupskip \fi \fi \fi 
    \SPANrowrest \NOparreset
    \NESTtableendouter \afterend

\ELEMENTnewblock tbody
  \beforestart \openstart \initstart \afterstart 
  \beforeend \closeend \afterend

\ELEMENTnew td
  \beforestart \SPANcolnoadvance \MESSAGEtdhyphen
  \openstart 
    \ifLINKunrendered \else %%%
      \BOXbegin \BIDIbegin \fi \afterstart
  \beforeend 
    \ifLINKunrendered \else %%%
      \NESTtdthend \GAPwriteorstrut \BIDIend \BOXend \fi
  \closeend \afterend

\ELEMENTnewblock tfoot % Fixme: not rendered as table footer, if not last row
  \beforestart \openstart \initstart \afterstart 
  \beforeend \closeend \afterend

\ELEMENTnew th
  \beforestart \SPANcolnoadvance \MESSAGEtdhyphen
  \openstart 
    \ifLINKunrendered \else %%%
      \FONTboldtrue \BOXbegin \BIDIbegin \FONTmodechange \fi \afterstart 
  \beforeend 
    \ifLINKunrendered \else %%%
      \NESTtdthend \GAPwriteorstrut \BIDIend \BOXend \fi
  \closeend \afterend
  
\ELEMENTnewblock thead
  \beforestart \openstart \initstart \afterstart 
  \beforeend \closeend \afterend
  
\ELEMENTnew title
  \beforestart \ifGEDCOM \GAPwrite \fi
  \openstart \ifGEDCOM \ELEMENTblockfalse \ELEMENTvalueget
    \ifELEMENTblock \par \FLOATindentnone \fi \fi \afterstart 
  \beforeend
    \ifGEDCOM \GAPwrite \else \METAgettitle \fi
  \closeend \afterend
  
\ELEMENTnew tr
  \beforestart \BOXrownoadvance \MESSAGEtrline 
  \openstart \BOXgridtrbegin \ELEMENTvalueget % Fixme: class cannot be 'body'
    \BOXheightswappedinit \MESSAGEtrnorow \afterstart 
  \beforeend 
    \SPANrowhfill \BOXgridtrend 
    \TABLEswapdo \ifBOXheightgiven \BOXheightswapped % sic! 
  \closeend \TABLEsplit \BOXindent \afterend
  
\ELEMENTnewblock ul
  \beforestart \noecho 
    \hangindent = 0pt \hangafter = 0 %%%
  \openstart \OPENlifalse \LISTnostart \initstart
  \afterstart \beforeend \closeend \NOparresetglobal \afterend
    
\echo {- Inline-level elements:} %--------------------------------------------

\ELEMENTnew a
  \beforestart \GAPwrite \nobreak \ANCHORedfalse
  \openstart \ANCHORinit \ELEMENTvalueget 
    \ANCHORbegin \afterstart 
  \beforeend \GAPwrite
  \ANCHORend 
  \closeend \ANCHORedfalse \afterend

\ELEMENTnew abbr
  \beforestart \GAPwrite
  \openstart \FONTitalictrue \ELEMENTvalueget \afterstart
  \beforeend \FONTmodechange \GAPwrite \closeend \afterend

\ELEMENTnewdefa {acronym} {%
  \FONTitalictrue \FONTmodechange}
  
\ELEMENTnew b
  \beforestart \GAPwrite
  \openstart \FONTboldtrue \ELEMENTvalueget
  \FONTmodechange \afterstart
  \beforeend \GAPwrite \closeend \afterend 
  
\def \TAGbasefont {%
  \MESSAGEbasefont \ELEMENTcount \ELEMENTvalueget \FONTswitchspan
  \MESSAGEendemptytag \VERIFYerrordeprecated \CONSTbasefont}
  
\ifx \eTeXversion \undefined
  \Message {bdo ! Unsupported (eTeX required).}%
\else  
  \Message {bdo}%
  \ELEMENTnew bdo
    \beforestart \GAPwrite
    \openstart \ELEMENTvalueget
    \BIDIbeginone \afterstart
    \beforeend  \GAPwrite \BIDIendone \closeend \afterend
\fi

\ELEMENTnewdefa {big} {% 
  \SIZEbaselarger \COLORizeforeground \FONTdo}

\ELEMENTnewdefa {blink} {% Fixme: should not appear as a message
  \VERIFYerrorproprietary \CONSTblink 
  \FONTboldtrue \FONTitalictrue \FONTmodechange
  \FONTunderline \GAPwrite}
  
\ELEMENTnewdefa {bold} {% Fixme: should not appear as a message
  \VERIFYerrorproprietary \CONSTbold
  \FONTboldtrue \FONTmodechange}
  
\ELEMENTnew cite
  \beforestart \GAPwrite
  \openstart \FONTitalictrue \ELEMENTvalueget 
  \FONTmodechange \afterstart 
  \beforeend \GAPwrite \closeend \afterend 

\ELEMENTnew code 
  \beforestart \GAPwrite \openstart 
  \FONTdomono \ELEMENTvalueget \FONTchangename \afterstart
  \beforeend \GAPwrite \closeend \afterend
  
\ELEMENTnew del
  \beforestart \GAPwrite \openstart \afterstart
  \beforeend \GAPstriketrue \GAPwrite
  \closeend \afterend

\ELEMENTnew dfn
  \beforestart \GAPwrite
  \openstart \FONTitalictrue \ELEMENTvalueget 
  \FONTmodechange \afterstart 
  \beforeend \GAPwrite \closeend \afterend 
  
\ELEMENTnew em
  \beforestart \GAPwrite
  \openstart \FONTitalictrue \ELEMENTvalueget 
  \FONTmodechange \afterstart 
  \beforeend \GAPwrite \closeend \afterend 
  
\ELEMENTnew font
  \beforestart \GAPwrite
  \openstart \FONTdoinner \ELEMENTvalueget
  \VERIFYerrordeprecated \CONSTfont \FONTswitchspan \afterstart 
  \beforeend \GAPwrite \closeend \afterend
  
\ELEMENTnew i
  \beforestart \GAPwrite
  \openstart \FONTitalictrue \ELEMENTvalueget 
  \FONTmodechange \afterstart 
  \beforeend \GAPwrite \closeend \afterend 
  
\ELEMENTnew ins
  \beforestart \GAPwrite
  \openstart \ELEMENTvalueget \afterstart
  \beforeend \FONTunderline \GAPwrite \closeend \afterend
  
\ELEMENTnew kbd
  \beforestart \GAPwrite \openstart 
  \FONTdomono \ELEMENTvalueget \FONTchangename \afterstart
  \beforeend \GAPwrite \closeend \afterend
  
\ELEMENTnew s
  \beforestart \GAPwrite 
  \openstart \VERIFYerrordeprecated \CONSTs 
    \ELEMENTvalueget \afterstart
  \beforeend \GAPstriketrue \GAPwrite
  \closeend \afterend

\ELEMENTnew samp
  \beforestart \GAPwrite \openstart 
  \FONTdomono \ELEMENTvalueget \FONTchangename \afterstart 
  \beforeend \GAPwrite \closeend \afterend
  
\ELEMENTnewdefa {small} {%
  \SIZEsmaller}

\ELEMENTnew span
  \beforestart \GAPwrite
  \openstart \ELEMENTvalueget 
  \FONTswitchspan \afterstart
  \beforeend \LANGUAGEgerman \GAPwrite \closeend \afterend

\ELEMENTnew strike
  \beforestart \GAPwrite 
  \openstart \afterstart
  \beforeend \VERIFYerrordeprecated \CONSTstrike \GAPstriketrue
    \GAPwrite \closeend \afterend

\ELEMENTnew strong
  \beforestart \GAPwrite
  \openstart \FONTboldtrue \ELEMENTvalueget
  \FONTmodechange \afterstart 
  \beforeend \GAPwrite \closeend \afterend 
  
\ELEMENTnew sub
  \beforestart \GAPwrite 
  \openstart \FONTswitchsubbegin \GAPnostrutstrue \afterstart
  \beforeend \GAPwrite 
  \FONTswitchsubend \closeend \afterend

\ELEMENTnew sup
  \beforestart \GAPwrite
  \openstart \FONTswitchsupbegin \GAPnostrutstrue \afterstart
  \beforeend \GAPwrite 
  \FONTswitchsupend \closeend \afterend
  
\ELEMENTnewdefa {tt} {%
  \FONTdomono \COLORizeforeground}

\ELEMENTnew u
  \beforestart \GAPwrite
  \openstart \VERIFYerrordeprecated \CONSTu 
    \ELEMENTvalueget \afterstart
  \beforeend \FONTunderline \GAPwrite \closeend \afterend

\ELEMENTnew var
  \beforestart \GAPwrite
  \openstart \FONTitalictrue \ELEMENTvalueget 
  \FONTmodechange \afterstart
  \beforeend \GAPwrite \closeend \afterend
  
\echo {- Unrendered elements:} %----------------------------------------------

\Message {form}
% In GMS, forms do not open another nesting level. 
% In practice, forms are too often misnested within tables.
\def \TAGform {% 
  \ELEMENTcount \MESSAGEformbegin \OPENformtrue}
\Def TAG/form {%
  \OPENformfalse \MESSAGEformend}
  
\ELEMENTnew head
  \beforestart \noecho
  \openstart \GAPwriteomit % Fixme: \global args
    \global \CSSaddedfalse \afterstart 
  \beforeend \closeend \afterend
  
\ELEMENTnew html 
  \beforestart \MESSAGEhtml
  \openstart \METApdfinfocreator \METApdfcatalogmenu 
    \ELEMENTvalueget \afterstart \beforeend 
  \closeend \ENDtrue \CHAINcheck 
    \ifOPENobject \strut \hfill \par \fi % Fixme: same in <GEDCOM>
    \afterend % Fixme: do not render object gap  
    
\ELEMENTnewdefa {label} {%
  \MESSAGEvalue}
  
\Message {link /}
\def \TAGlink {%
  \MESSAGElink \ELEMENTcount
  \ifGEDCOM \GAPwrite \ANCHORgedcom 
  \else \LINKinit \ELEMENTvalueget \LINKexec \fi 
  \MESSAGEendemptytag}
  
\Message {meta /} 
\def \TAGmeta {%
  \MESSAGEmeta \ELEMENTcount \METAinit
  \ELEMENTvalueget \METAget \MESSAGEendemptytag}
  
\ELEMENTnew script
  \beforestart \GAPwrite 
  \openstart \SCRIPTinit \ELEMENTvalueget \SCRIPThandle
  \afterstart \beforeend 
  \closeend \beginmarkupCAT \afterend
  
\bgroup
  \ELEMENTnew style
    \beforestart 
    \openstart \GAPwriteomit 
      \SHEETstylebegin \ELEMENTvalueget \afterstart
    \beforeend \SHEETstyleend \closeend \afterend
\egroup
  
\def \TAGtrace {% Trace TeX macros for GMS debugging:
  \GAPwrite \Message {trace}\MESSAGEproprietary \VERIFYerrortracebegin}
\Def TAG/trace {%
  \GAPwrite \VERIFYerrortraceend \Message {/trace}}
  
\Def TAGxml {%
  \MESSAGEhtml \Message {?\CONSTxml \CONSTspace ?}\ELEMENTcount}
  
\Def TAGxml-stylesheet {%
  \message {<?\CONSTxml-\CONSTstylesheet}\ELEMENTcount  
  \LINKinit \ELEMENTvalueget  
  \let \LINKrel \CONSTstylesheet
  \LINKexec \message {/>}}    
    
%\echo {- Unsupported elements:} %--------------------------------------------

\ELEMENTnewdefa {applet} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTapplet
  \VERIFYerrordeprecated \CONSTapplet}

\def \TAGarachne {%
  \ELEMENTcount \VERIFYerrorproprietary {arachne}}

\def \TAGarea {%
  \ELEMENTcount \VERIFYerrorunsupported {area}}
  
\def \TAGbase {%
  \MESSAGEbase \VERIFYerrorunsupported \CONSTbase \MESSAGEgt} 
\Def TAG/base {\MESSAGEbaseend}

\ELEMENTnewdefa {button} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTbutton}  

\def \TAGcomment {% used internally
  \ifOPENtr 
    \ifOPENtd \GAPwrite \else \ifOPENth \GAPwrite \fi \fi 
  \else \GAPwrite \fi}
  
\ELEMENTnewdefa {dir} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTdir \VERIFYerrordeprecated \CONSTdir}
  
\def \TAGend {% used internally
  \VERIFYerrordebugend}   

\ELEMENTnewdefa {fieldset} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTfieldset}
  
\def \TAGframe {%
  \ELEMENTcount \VERIFYerrorunsupported \CONSTframe \VERIFYnotstrict}

\ELEMENTnewdefa {frameset} {%
  \VERIFYerrorunsupported \CONSTframeset \VERIFYnotstrict}
  
\def \TAGisindex {%
  \VERIFYerrorunsupported \CONSTisindex \VERIFYerrordeprecated \CONSTisindex}

\ELEMENTnewdefa {layer} {% Fixme: should not appear as a message
  \VERIFYerrorproprietary \CONSTlayer}

\ELEMENTnewdefa {legend} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTlegend}
  
\def \TAGmenu {%
  \MESSAGEmenubegin \VERIFYerrordeprecated \CONSTmenu \MESSAGEmenuisul}

\Def TAG/menu {%
  \csname TAG/ul\endcsname \MESSAGEmenuend}

\ELEMENTnew nobr % Fixme: should not appear as a message
  \beforestart \GAPwrite \openstart 
  \VERIFYerrorproprietary \CONSTnobr
    \VERIFYerrorunsupported \CONSTnobr \afterstart
  \beforeend \closeend \afterend

\ELEMENTnewdefa {noframes} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTnoframes \VERIFYnotstrict}

\ELEMENTnewdefa {noscript} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTscript}

\def \TAGopgroup {%
  \TAGoptgroup \VERIFYerrormisspelled}
\Def TAG/opgroup {%
  \csname \CONSTtag /\CONSToptgroup \endcsname \VERIFYerrormisspelled}

\ELEMENTnew optgroup % Fixme: should not appear as a message
  \beforestart \openstart
  \VERIFYerrorunsupported \CONSToptgroup
  \afterstart \beforeend \closeend \afterend

\def \TAGparam {%
  \ELEMENTcount \VERIFYerrorunsupported \CONSTparam}
  
\ELEMENTnewdefa {q} {% Fixme: should not appear as a message
  \VERIFYerrorunsupported \CONSTq}
  
\def \TAGsdb {%
  \VERIFYerrorproprietary {sdb}}

\def \TAGspacer {%
  \VERIFYerrorproprietary {spacer}}
  
\def \TAGtextarea {%
  \message {<\CONSTtextarea}\VERIFYerrorunsupported 
    \CONSTtextarea \message {>}}
\Def TAG/textarea {\Message {/\CONSTtextarea}}
  
\def \TAGwbr {%
  \MESSAGEwbr \VERIFYerrorproprietary \CONSTwbr}
  
\echo {- Recognized style properties:} %======================================

\NEWpropproprietary align \ALIGNtextbyvalue

\NEWpropunsupported azimuth   

\NEWpropunsupported background
%%%\NEWpropnew background \COLORsetbgspan %%% supporting only color
\NEWpropnewtag body background \BACKGROUNDcolorsetbody 
\NEWpropnewtag table background \COLORsetbgtable
\NEWpropnewtag tbody background \COLORsetbgtable
\NEWpropnewtag td background \COLORsetbgtable
\NEWpropnewtag tfoot background \COLORsetbgtable
\NEWpropnewtag th background \COLORsetbgtable
\NEWpropnewtag thead background \COLORsetbgtable
\NEWpropnewtag tr background \COLORsetbgtable

\NEWpropunsupported background-attachment

\NEWpropmessage background-color
\NEWpropnew background-color \COLORsetbgspan %%%
\NEWproptagunsupported h1 background-color %%% Fixme
\NEWproptagunsupported h2 background-color %%%
\NEWproptagunsupported h3 background-color %%%
\NEWproptagunsupported h4 background-color %%%
\NEWproptagunsupported h5 background-color %%%
\NEWproptagunsupported h6 background-color %%%
\NEWpropnewtag body background-color \COLORsetbackgroundbody
\NEWpropnewtag table background-color \COLORsetbgtable
\NEWpropnewtag tbody background-color \COLORsetbgtable
\NEWpropnewtag td background-color \COLORsetbgtable
\NEWpropnewtag tfoot background-color \COLORsetbgtable
\NEWpropnewtag th background-color \COLORsetbgtable
\NEWpropnewtag thead background-color \COLORsetbgtable
\NEWpropnewtag tr background-color \COLORsetbgtable

\NEWpropmessage background-image
\NEWpropnewtag body background-image {\BACKGROUNDgeturl {\the \VALUE}}
\NEWpropnewtag div background-image {\BACKGROUNDgeturl {\the \VALUE}}

\NEWpropunsupported background-position

\NEWpropnew background-repeat \BACKGROUNDsetrepeat

\NEWpropproprietary behavior \empty

\NEWpropunsupported border
\NEWpropunsupported border-bottom
\NEWpropunsupported border-left
\NEWpropunsupported border-right
\NEWpropunsupported border-top

\NEWpropunsupported border-collapse

\NEWpropnew border-color \COLORsetborder
  
\NEWpropunsupported border-bottom-color
\NEWpropunsupported border-left-color
\NEWpropunsupported border-right-color
\NEWpropunsupported border-top-color

\NEWpropunsupported border-spacing

\NEWpropnew border-style {\VALUEset \BORDERprofile}
  
\NEWpropunsupported border-bottom-style
\NEWpropunsupported border-left-style
\NEWpropunsupported border-right-style
\NEWpropunsupported border-top-style

% Fixme: if a profile like "groove" is given, use "thick"er width:
\NEWpropnew border-width \BORDERset
\NEWpropquiet border-bottom-width \BORDERsetevaldobottom
\NEWpropquiet border-left-width \BORDERsetevaldoleft
\NEWpropquiet border-right-width \BORDERsetevaldoright
\NEWpropquiet border-top-width \BORDERsetevaldotop

\NEWpropunsupported bottom

\NEWpropunsupported caption-side

\NEWpropunsupported clear

\NEWpropunsupported clip

\NEWpropnew color \COLORsetforeground
\NEWpropnewtag ul color \COLORsetlistdot

%%%\NEWpropunsupported content
\NEWpropnew content {\VALUEset \ELEMENTcontent} %%%

\NEWpropunsupported counter-increment   

\NEWpropunsupported cue
\NEWpropunsupported cue-after
\NEWpropunsupported cue-before

\NEWpropunsupported cursor

\ifx \eTeXversion \undefined
  \message {! Unsupported: direction (eTeX required),}
  \NEWpropunsupported direction
\else \message {\CONSTdirection,}%
  \NEWpropnew direction \BIDIset
\fi

\NEWpropnew display \GAPdisplay
\NEWpropnewtag p display \GAPdisplayp

\let \PROPdummy \empty % used internally for CSS selector parsing
\Def PROP;dummy \empty

\NEWpropunsupported elevation

\NEWpropunsupported empty-cells

\NEWpropproprietary filter \empty

\NEWpropmessage float
\NEWpropnewtag img float \TAGimgATTalign

\NEWpropunsupported font

\NEWpropnew font-family \FONTfamilyset

\NEWpropnew font-size \SIZEset
    
\NEWpropnew font-size-adjust \FONTsizeadjustset

\NEWpropunsupported font-stretch

\NEWpropnew font-style \FONTmodestyle

\NEWpropunsupported font-variant

\NEWpropnew font-weight \FONTmodeweight

\NEWpropnew height {%
  \VALUEdimenset \BOXheight \vsize \BOXheightgiventrue}
\NEWpropnewtag a height {%
  \VALUEdimenset \ANCHORheight \LINEheight \ANCHORheightgiventrue}
\NEWpropnewtag img height \TAGimgATTheight

\NEWpropproprietary hspace \empty

\NEWpropunsupported left

\NEWpropunsupported letter-spacing

\NEWpropnew line-height {%   
  \VALUEdimenset \LINEheight \LINEheight 
  \LINEheightgiventrue \GAPsetstrut}
\NEWpropnewtag body line-height {% %%% Fixme: shorten
  \VALUEdimenset \LINEheight \LINEheight %%%
  \LINEheightgiventrue \GAPsetstrut %%%
  \topskip = 0.7083\LINEheight} %%%

\NEWpropunsupported list-style
\NEWpropunsupported list-style-image
\NEWpropunsupported list-style-position
\NEWpropunsupported list-style-type

\NEWpropnew margin \MARGINset

\NEWpropnew margin-bottom {%
  \VALUEdimenset \MARGINbottom \vsize
  \MARGINgiventrue \MARGINbottomgiventrue}
\NEWpropnewtag img margin-bottom {%
  \VALUEdimenset \IMAGEmarginbottom \vsize}

\NEWpropnew margin-left {%
  \VALUEdimenset \MARGINleft \hsize \MARGINgiventrue}
\NEWpropnewtag p margin-left {%
  \VALUEdimenset \MARGINleft \hsize \MARGINgiventrue
  \advance \leftskip by \MARGINleft}

\NEWpropnew margin-right {%
  \VALUEdimenset \MARGINright \hsize \MARGINgiventrue}
\NEWpropnewtag p margin-right {%
  \VALUEdimenset \MARGINright \hsize \MARGINgiventrue
  \advance \rightskip by \MARGINright}

\NEWpropnew margin-top {%
  \VALUEdimenset \MARGINtop \vsize
  \MARGINgiventrue \MARGINtopgiventrue}
\NEWpropnewtag img margin-top {%
  \VALUEdimenset \IMAGEmargintop \vsize}

\NEWpropunsupported marker-offset

\NEWpropunsupported marks

\NEWpropunsupported max-height
\NEWpropunsupported max-width

\NEWpropunsupported min-height
\NEWpropunsupported min-width

\NEWpropproprietary -moz-opacity \empty

\NEWpropnew orphans {%
  \VALUEset \test
    \ifx \test \CONSTnumberone \global \clubpenalty = 9999
    \else \ifx \test \CONSTnumbertwo \global \clubpenalty = 10000 \fi \fi}

\NEWpropunsupported outline
\NEWpropunsupported outline-color
\NEWpropunsupported outline-style
\NEWpropunsupported outline-width

\NEWpropunsupported overflow
\NEWpropproprietary overflow-x \empty
\NEWpropproprietary overflow-y \empty

\NEWpropquiet padding \PADDINGset

\NEWpropnew padding-bottom {\VALUEdimenset \PADDINGbottom \vsize}
\NEWpropnew padding-left {\VALUEdimenset \PADDINGleft \hsize}
\NEWpropnew padding-top {\VALUEdimenset \PADDINGtop \vsize}
\NEWpropnew padding-right {\VALUEdimenset \PADDINGright \hsize}

\NEWpropunsupported page % Fixme: check vs. @page

\NEWpropunsupported page-break-after

\NEWpropnew page-break-before \OUTPUTbreak
\NEWpropnewtag h1 page-break-before \OUTPUTbreakh

\NEWpropnew page-break-inside \TABLEsplitset

\NEWpropunsupported pause
\NEWpropunsupported pause-after
\NEWpropunsupported pause-before

\NEWpropunsupported pitch
\NEWpropunsupported pitch-range

\NEWpropunsupported play-during

\NEWpropunsupported position

\NEWpropunsupported quotes

\NEWpropunsupported richness

\NEWpropunsupported right

\NEWpropunsupported rotation-code 

\NEWpropmessage size
\NEWpropnewtag @page size \OUTPUTsize
\NEWpropnewtag select size \empty

\NEWpropunsupported speak
\NEWpropunsupported speak-header
\NEWpropunsupported speak-numeral
\NEWpropunsupported speak-punctuation
\NEWpropunsupported speech-rate

\NEWpropunsupported stress

\NEWpropunsupported table-layout

\NEWpropnew text-align \ALIGNtextbyvalue
\NEWpropnewtag pre text-align {%
  \VERIFYerrorunsuppattprop \CONSTtextalign \ALIGNtextleft}

\NEWpropnew text-decoration {\VALUEset \test
  \ifx \test \CONSTnone \FONTdecorationfalse \fi}

\NEWpropnew text-indent {%
  \TEXTindentgiventrue \VALUEdimenset \TEXTindent \hsize}

\NEWpropproprietary text-justify \empty

\NEWpropunsupported text-shadow
\NEWpropunsupported text-transform

\NEWpropunsupported top

\NEWpropunsupported unicode-bidi

\NEWpropnew vertical-align \BOXvalignset

\NEWpropunsupported visibility

\NEWpropunsupported voice-family

\NEWpropunsupported volume

\NEWpropunsupported white-space

\NEWpropnew widows \VALUEwidows

\NEWpropproprietary vspace \empty

\NEWpropnew width {\TAGtableATTwidth \BOXspancolexec}
\NEWpropnewtag img width \TAGimgATTwidth

\NEWpropunsupported word-spacing

\NEWpropunsupported z-index

\message {...}

\echo {- Gedcom XML elements:} %==============================================

% New 2007/03/08:

% Elements <caption>, <link>, <title> used in HTML too

\ELEMENTnew email % Fixme: partly doubles <uri>, so outsource
  \beforestart \GAPwrite \nobreak \ANCHORedfalse
  \openstart \ELEMENTblockfalse \ELEMENTvalueget
    \ELEMENTblockindent %%%
    \ELEMENTnewgenericpseudo \CONSTbefore \afterstart 
  \beforeend \ANCHORinit
    \edef \TAGuritest {\CONSTspace \the \GAP \CONSTspace}%
    \expandafter \TAGuriurlhrefget \TAGuritest 
    \ANCHORbegin \GAPwrite
  \ANCHORend 
  \closeend \ANCHORedfalse \afterend   
  
% Fixme: A few element definitions let :after and :before unsupported:

\def \TAGexternalid {% Fixme: unsupported
  \ELEMENTcount \Message {\CONSTexternalid \CONSTspace /}}     

\ELEMENTnew gedcom % like <html> + <body>
  \beforestart \GEDCOMtrue
  \openstart \METApdfinfocreator \METApdfcatalogmenu 
    \OUTPUTbody \CONSTgedcom \afterstart 
  \beforeend \ELEMENTnewgenericpseudo \CONSTafter 
    \GAPwrite %%%
    \par \LINEupskip %%% Fixme: same as <body>
    \ifOPENobject \else 
      \global \COLORfalse    
      \global \COLORbgfalse       
      \vfill \break \fi
  \closeend \ENDtrue \CHAINcheck 
    \ifOPENobject \strut \hfill \par \fi \afterend  
  
\ELEMENTnew uri % Fixme: partly doubles <email>, so outsource
  \beforestart \GAPwrite \nobreak \ANCHORedfalse
  \openstart \ELEMENTblockfalse \ELEMENTvalueget
    \ELEMENTblockindent %%%
    \ELEMENTnewgenericpseudo \CONSTbefore \afterstart 
  \beforeend \ANCHORinit
    \edef \TAGuritest {\CONSTspace \the \GAP \CONSTspace}%
    \expandafter \TAGuriurlhrefget \TAGuritest   
    \glet \ANCHORext \URLhref
    \glet \ANCHORint \URLhref
    \ANCHORbegindohrefext
    \GAPwrite \ANCHORend
    \ifx \URLhref \CONSTdot \else  \TAGuriimage \fi
  \closeend \ANCHORedfalse \afterend   
  
  \def \TAGuriurlhrefget #1#2 #3{%
    \xdef \URLhref {#1#2}%
    \global \GAP = {#1#2}#3}
    
    \new \ifTAGuriimage
  
    \def \TAGuriimage {%  Fixme: rename
      \TAGuriimagefalse     
      \expandafter \TAGurigetjpeg \URLhref .jpeg\relax
      \expandafter \TAGurigetJPEG \URLhref .JPEG\relax
      \expandafter \TAGurigetjpg \URLhref .jpg\relax
      \expandafter \TAGurigetJPG \URLhref .JPG\relax
      \expandafter \TAGurigetpdf \URLhref .pdf\relax
      \expandafter \TAGurigetPDF \URLhref .PDF\relax
      \expandafter \TAGurigetpng \URLhref .png\relax
      \expandafter \TAGurigetPNG \URLhref .PNG\relax
      \ifTAGuriimage
        \ELEMENTblockindent %%%
        \IMAGEinit \let \IMAGEalt \empty 
        \ALIGNfalse \IMAGErun 
        \ifIMAGEabsent \strut \LINEupskip \fi \fi }
        
      \def \TAGurigetjpeg #1.jpeg#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotjpeg}    
      \def \TAGurigetJPEG #1.JPEG#2\relax {%      
        \TAGuricheckimage {#2}\CONSTdotjpeg}
    
      \def \TAGurigetjpg #1.jpg#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotjpg}    
      \def \TAGurigetJPG #1.JPG#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotjpg}
    
      \def \TAGurigetpdf #1.pdf#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotpdf}    
      \def \TAGurigetPDF #1.PDF#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotpdf}
    
      \def \TAGurigetpng #1.png#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotpng}    
      \def \TAGurigetPNG #1.PNG#2\relax {%
        \TAGuricheckimage {#2}\CONSTdotpng}
      
        \def \TAGuricheckimage #1#2{%
          \lowercase {\def \test {#1}}% 
          \ifx \test #2\TAGuriimagetrue \fi}

% Fixme: elements should be generated by reading the document type declaration

% Top-level:
\ELEMENTnewgeneric ContactRec
\ELEMENTnewgeneric EventRec
\ELEMENTnewgeneric FamilyRec
\ELEMENTnewgeneric GroupRec
\ELEMENTnewgeneric HeaderRec
\ELEMENTnewgeneric IndividualRec
\ELEMENTnewgeneric LDSOrdRec
\ELEMENTnewgeneric MultiMediaRec
\ELEMENTnewgeneric RepositoryRec
\ELEMENTnewgeneric SourceRec

% Sub-level:
\ELEMENTnewgeneric Addressee
\ELEMENTnewgeneric Article
\ELEMENTnewgeneric ArticleDoc
\ELEMENTnewgeneric Association
\ELEMENTnewgeneric AssocIndiv
\ELEMENTnewgeneric Author
\ELEMENTnewgeneric AuthorDoc
\ELEMENTnewgeneric BasedOn
\ELEMENTnewgeneric BirthDateDoc
\ELEMENTnewgeneric BirthPlaceDoc
\ELEMENTnewgeneric CallNbr
\ELEMENTnewgeneric Changed
\ELEMENTnewgeneric Child
\ELEMENTnewgeneric ChildNbr
\ELEMENTnewgeneric Citation
\ELEMENTnewgeneric CitationText
\ELEMENTnewgeneric Contact
\ELEMENTnewgeneric Coordinates
\ELEMENTnewgeneric Copyright
\ELEMENTnewgeneric Date
\ELEMENTnewgeneric Day
\ELEMENTnewgeneric DeathDateDoc
\ELEMENTnewgeneric DeathPlaceDoc
\ELEMENTnewgeneric DeathStatus
\ELEMENTnewgeneric Description
\ELEMENTnewgeneric DupIndiv
\ELEMENTnewgeneric Event
\ELEMENTnewgeneric Extract
\ELEMENTnewgeneric FamilyNbr
\ELEMENTnewgeneric FamParticipant
\ELEMENTnewgeneric FileCreation
\ELEMENTnewgeneric Format
\ELEMENTnewgeneric Gender
\ELEMENTnewgeneric GivenName
\ELEMENTnewgeneric GivenNameDoc
\ELEMENTnewgeneric GivenNameDoc
\ELEMENTnewgeneric HusbFath
\ELEMENTnewgeneric HusbFathLiving
\ELEMENTnewgeneric IndivDoc
\ELEMENTnewgeneric IndivName
\ELEMENTnewgeneric IndivParticipant
\ELEMENTnewgeneric IndNameVariation
\ELEMENTnewgeneric Level
\ELEMENTnewgeneric Living
\ELEMENTnewgeneric MaidenName
\ELEMENTnewgeneric MailAddress
\ELEMENTnewgeneric MarrDateDoc
\ELEMENTnewgeneric MarrPlaceDoc
\ELEMENTnewgeneric Member
\ELEMENTnewgeneric Month
\ELEMENTnewgeneric MultiMedia
\ELEMENTnewgeneric Name
\ELEMENTnewgeneric NameDoc
\ELEMENTnewgeneric NameSuffix
\ELEMENTnewgeneric Note
\ELEMENTnewgeneric OrdStat
\ELEMENTnewgeneric OrganizationName
\ELEMENTnewgeneric ParentGroup
\ELEMENTnewgeneric Participant
\ELEMENTnewgeneric PersonalTitle
\ELEMENTnewgeneric Phone
\ELEMENTnewgeneric Place
\ELEMENTnewgeneric PlacePart
\ELEMENTnewgeneric PlaceVariation
\ELEMENTnewgeneric Product
\ELEMENTnewgeneric ProductId
\ELEMENTnewgeneric Publishing
\ELEMENTnewgeneric PublishingDoc
\ELEMENTnewgeneric References
\ELEMENTnewgeneric ReferencesDoc
\ELEMENTnewgeneric Relationship
\ELEMENTnewgeneric RelativeDoc
\ELEMENTnewgeneric Religion
\ELEMENTnewgeneric RelToFath
\ELEMENTnewgeneric RelToMoth
\ELEMENTnewgeneric Repository
\ELEMENTnewgeneric ResidenceDoc
\ELEMENTnewgeneric Role
\ELEMENTnewgeneric SameIndiv
\ELEMENTnewgeneric Source
\ELEMENTnewgeneric Start
\ELEMENTnewgeneric Stop
\ELEMENTnewgeneric Submitter
\ELEMENTnewgeneric Supplier
\ELEMENTnewgeneric SurName
\ELEMENTnewgeneric SurNameDoc
\ELEMENTnewgeneric TempleCode
\ELEMENTnewgeneric TitleDoc
\ELEMENTnewgeneric Units
\ELEMENTnewgeneric Version
\ELEMENTnewgeneric WhenRecDoc
\ELEMENTnewgeneric WhenRecorded
\ELEMENTnewgeneric WhereInDoc
\ELEMENTnewgeneric WhereInMM
\ELEMENTnewgeneric WhereInSource
\ELEMENTnewgeneric WifeMoth
\ELEMENTnewgeneric WifeMothLiving
\ELEMENTnewgeneric Year

% Gedcom attributes: 

\NEWattdef calendar \empty
\NEWattdef date \empty
\NEWattdef level \empty
\NEWattdef ref \empty
\NEWattdef time \empty
\NEWattdef translationtype \empty
\NEWattdef vitaltype \empty

%#############################################################################

% Compatibility with external files: -----------------------------------------

% In prologue.tex, epilogue.tex, font.cfg, plugin.cfg, typeset.cfg,
% charsets.tex, these names are used:

\let \CELLdefaultno \SPANcolpredefault
\let \CODEPAGEloadthem \CODEPAGEload
\let \ERRORabsent \VERIFYerrorabsent % script.htm
\let \FSIZE \SIZE 
\let \FSIZEbase \SIZEbase 
\let \GLYPHSadd \GLYPHadd
\let \GLYPHSnamesload \GLYPHnamesload
\let \KERNINGloadtables \KERNINGget
\let \HEX \DATAhex
\let \HEXinput \DATAhexinput
\let \HEXoutput \DATAhexoutput
\let \MAPfontadd \MAPadd 
\let \MAPfontaddalias \MAPaddalias 
\let \MAPfontaddencoding \MAPaddencoding 
\let \MAPfontaddfamily \MAPaddfamily 
\let \MAPfontaddfamilystd \MAPaddfamilystd 
\let \MAPfontaddfamilyuni \MAPaddfamilyuni  
\let \MAPfontaddmates \MAPaddmates 
\let \MAPfontaddpair \MAPaddpair  
\let \MAPfontaddspecific \MAPaddspecific 
\let \PAGEheight \OUTPUTheight
\let \PAGEwidth \OUTPUTwidth
\let \PAGEmarginbottom \OUTPUTmarginbottom
\let \PAGEmarginleft \OUTPUTmarginleft
\let \PAGEmarginright \OUTPUTmarginright
\let \PAGEmargintop \OUTPUTmargintop
\let \UNICODEencswrite \UNICODEwrite 
\let \UNICODEslotsload \UNICODEwriteslot 
\nec \UNICODEslottempo  
\let \VALcolor \CONSTcolor
\let \VALfontfamily \CONSTfontfamily
\let \VALfontsize \CONSTfontsize
\let \VALfontstyle \CONSTfontstyle
\let \VALheight \CONSTheight
\let \VALlineheight \CONSTlineheight
\let \VALmargin \CONSTmargin
\let \VALpadding \CONSTpadding
\let \VALsize \CONSTsize
\let \VALtextalign \CONSTtextalign
\let \VALtextindent \CONSTtextindent
\let \VALwidth \CONSTwidth

% Setup: ---------------------------------------------------------------------

\CODEPAGEgetdefaultname 
\FONTfallbackset

\fillmessage 6a{typeset}3 \input typeset.cfg \fillmessage 6-{/typeset}2
\fillmessage 6b{alias}5 \input alias.cfg \fillmessage 6-{/alias}4
\message {fallback}\message {fonts:}
\message {cmr}\message {(default),}
\message {\FONTfallbackmonospace}\message {(monospace),}
\message {\FONTfallbacksansserif}\message {(sans-serif),}
\message {\FONTfallbackserif}\message {(serif);}
\FILEsearch {files.cfg}\ifFILEexist
  \fillmessage 6c{files}5 \input files.cfg \fillmessage 6-{/files}4 \fi
\fillmessage 4-{/interface}2 \input plugin.cfg
\fillmessage 2-{/initialize}3
\GMSendabout \GMSgoodbye 

% Load third-party macros and start shredder: --------------------------------

\input epilogue.cfg