
\ifdefined\minimpdfloaded
    \message{(skipped)}
    \expandafter\endinput\fi
\chardef\minimpdfloaded = \catcode`\:
\catcode`\: = 11

\input minim-alloc
\input minim-hooks

% Abbreviations used throughout this document:
%   se   structure element
%   mci  marked content item

\newcount \writedocumentstructure
\newcount \writehyphensandspaces
\newcount \strictstructuretagging

\writedocumentstructure = 0
\writehyphensandspaces  = 1
\strictstructuretagging = 0

% 1 the attributes

% By three attributes do we determine the document structure.
%
%   One for marking the current structure element:
%   - is the index of the lua-side se table
%   - assignments are always local
\newattribute \tagging:current:se  \tagging:current:se = 1
%
%   One for ordering children of structure elements:
%   - assignments are always global
%   - should generally increase monotously
%   - should change (increase) at every se boundary
\newattribute \tagging:element:order \tagging:element:order = 1
%
%   One for marking the status:
%   - assignments are generally local
%   - if set, disables tagging and content marking in pre_shipout
%   - values >10 indicate artifacts
\newattribute \tagging:current:status \tagging:current:status = \unset
%
%   A fourth attribute keeps track of the current language
%   - assignments are local
%   - sets language of structure elements
\newattribute \tagging:current:language \tagging:current:language = \language

\directlua { require('minim-pdf') }

% 1 artifacts and content items

% \stoptagging ... \starttagging
%     disables marking structure elements
\newif\iftagging:enabled \tagging:enabledtrue
\protected\def\starttagging{\tagging:enabledtrue
    \ifnum0<\tagging:current:status
        \tagging:current:status\unset\fi}
\protected\def\stoptagging{\tagging:enabledfalse
    \ifnum\unset=\tagging:current:status
        \tagging:current:status1\relax\fi}

% \markartifact {Layout} {...}
% \startartifact {Pagination /Subtype/Header} ... \stopartifact
\long\def\markartifact#1#2{\startartifact{#1}#2\stopartifact}
\protected\def\startartifact{\begingroup\tagging:enabledfalse
    \tagging:current:status=\tagging:current:artifact
    \global\advance\tagging:current:artifact1\relax
    \tagging:mci:incr\tagging:art:markstart}
\protected\def\stopartifact{\tagging:art:markstop\tagging:mci:incr\endgroup}
\newcount\tagging:current:artifact \tagging:current:artifact = 11

% \startcontentitem ... \stopcontentitem
\protected\def\startcontentitem{\iftagging:enabled\tagging:mci:incr\tagging:mci:markstart\fi}
\protected\def\stopcontentitem{\iftagging:enabled\tagging:mci:markstop\tagging:mci:incr\fi}

% \startsinglecontentitem ... \stopsinglecontentitem
\protected\def\startsinglecontentitem{\begingroup \startcontentitem\stoptagging}
\protected\def\stopsinglecontentitem{\endgroup\stopcontentitem}

% \ensurecontentitem
\protected\def\ensurecontentitem{\iftagging:enabled\tagging:mci:content\fi}
\protected\def\tagging:mci:incr{\global\advance\tagging:element:order1\relax}

% 1 structure elements

% \savecurrentelement ... \continueelement
% \savecurrentelementto\name ... \continueelementfrom\name
\protected\def\savecurrentelementto#1{\global\chardef#1\tagging:current:se}
\protected\def\continueelementfrom#1{\tagging:current:se#1\tagging:mci:incr}
\def\savecurrentelement{\savecurrentelementto\tagging:saved:se}
\def\continueelement{\continueelementfrom\tagging:saved:se}

% \markelement {Tag} {...}
% \startelement {Tag} ... \stopelement {Tag}
% \ensurestopelement {Tag}
\long\protected\def\markelement#1#2{\iftagging:enabled
    \startelement{#1}#2\stopelement{#1}\else#2\fi}
\protected\def\startelement{\iftagging:enabled \tagging:mci:incr
    \expandafter\tagging:startelement\else
    \expandafter\tagging:ignore\fi}
\protected\def\stopelement{\iftagging:enabled \tagging:mci:incr
    \expandafter\tagging:stopelement\else
    \expandafter\tagging:ignore\fi}
\protected\def\ensurestopelement{\iftagging:enabled \tagging:mci:incr
    % n.b. this can cause problems if you skip levels
    \expandafter\tagging:ensurestopelement\else
    \expandafter\tagging:ignore\fi}
\def\tagging:ignore#1#{\ignore}

% \addstructuretype [options] Existing Alias
\protected\def\addstructuretype{\withoptions[]\addstructure:type}
\def\addstructure:type[#1]{\struct:addalias{return {#1}}}

% \setalttext {...}
\protected\def\setalttext{\iftagging:enabled
    \expandafter\tagging:alt\else
    \expandafter\tagging:ignore\fi}
% \setactualtext {...}
\protected\def\setactualtext{\iftagging:enabled
    \expandafter\tagging:actual\else
    \expandafter\tagging:ignore\fi}

% \tagattribute Owner Key /verbatim_value
\protected\def\tagattribute{\iftagging:enabled
    \expandafter\tagging:attribute\else
    \expandafter\tagging:ignore:attribute\fi}

% \settagid {name}
\protected\def\settagid{\iftagging:enabled
    \expandafter\tagging:tagid\else
    \expandafter\tagging:ignore\fi}

% \showstructure
\newtoks\tagging:showtoks
\protected\def\showstructure{%
    \tagging:getshowstructure
    \showthe\tagging:showtoks}

% 1 auto-marking paragraphs

% \nextpartag {H}
% \nextpartag {}    % no tag inserted for next paragraph
% \markparagraphs(true|false)
\newif\ifmarkparagraphs \markparagraphstrue
\newtoks\nextpartag \nextpartag{P}
\toksapp\minim:ateverypar{\iftagging:enabled \ifmarkparagraphs
    \expandafter\ifx\expandafter\relax\the\nextpartag\relax\else
        \startelement{\the\nextpartag}\fi
    \nextpartag{P}\fi \fi}

% 1 tagging tables

% \marktable \halign
%       {\marktablerow\marktablecell#&\marktablecell#\cr
%    \marktableheader
%       Header & cells \cr
%    \marktablebody
%       ... & ... \cr ...
%    \marktablefooter
%       ... & ... \cr ... }
%
% lots of variables and constants
\newcount\tagging:tablec % global; only used for cel ids
\newcount\tagging:tablerow
\newcount\tagging:tablecol
\newcount\tagging:tablecolspan \tagging:tablecolspan 1
\newcount\tagging:tablerowspan \tagging:tablerowspan 1
\newcount\tagging:i
\def\tagging:TH{{TH}\markcolumnhead}
\def\tagging:TD{{TD}}
% initialising variables
\def\marktable{\startelement{Table}%
    \global\advance\tagging:tablec1
    \tagging:tablerow0
    \tagging:tablecol0
    \def\tagging:tablecolheaders{}%
    \def\tagging:tablerowheaders{}%
    \let\tagging:cell\tagging:TD}
% the header
\def\marktableheader{%
    \noalign{\global\let\tagging:cell\tagging:TH
        \startelement{THead}%
        \savecurrentelementto\tagging:tpart}}
% the body
\def\marktablebody{%
    \noalign{\global\let\tagging:cell\tagging:TD
        \startelement{TBody}%
        \savecurrentelementto\tagging:tpart}}
% the footer
\def\marktablefooter{%
    \noalign{\startelement{TFoot}%
        \savecurrentelementto\tagging:tpart}}
% rows
\def\marktablerow{%
    \global\advance\tagging:tablerow1
    \global\tagging:tablecol0
    \unless\ifdefined\tagging:tpart
        \startelement{TBody}%
        \savecurrentelementto\tagging:tpart\fi
    \continueelementfrom\tagging:tpart
    \startelement{TR}%
    \savecurrentelementto\tagging:row}
% cells
\def\marktablecell{%
    \global\advance\tagging:tablecol1
    \continueelementfrom\tagging:row
    \expandafter\startelement\tagging:cell%
    \tagging:assignheaders}

% spans
\def\markcolumnspan#1{%
    \tagattribute Table ColSpan #1\relax
    \tagging:tablecolspan#1\relax
    % adjust the column number
    \global\advance\tagging:tablecol\numexpr#1-1\relax}
\def\markrowspan#1{%
    % note that the row number is not adjusted: \marktablerow must be present 
    % somewhere on every row to increment it.
    \tagattribute Table RowSpan #1\relax
    \tagging:tablerowspan#1\relax}

% headers
\def\markcolumnhead{%
    \tagging:setcelid
    \tagattribute Table Scope /Column\relax
    \tagging:i=1 \loop
        \xdef\tagging:tablecolheaders{\tagging:tablecolheaders
            {\the\numexpr\tagging:tablecol-\tagging:tablecolspan+\tagging:i}{\tagging:thecelid}}%
         \advance\tagging:i1 \unless\ifnum\tagging:i>\tagging:tablecolspan\repeat}
\def\markrowhead{%
    \tagging:setcelid
    \tagattribute Table Scope /Row\relax
    \tagging:i=0 \loop
        \xdef\tagging:tablerowheaders{\tagging:tablerowheaders
            {\the\numexpr\tagging:tablerow+\tagging:i}{\tagging:thecelid}}%
         \advance\tagging:i1 \ifnum\tagging:i<\tagging:tablerowspan\repeat}
\def\tagging:setcelid{%
    % assign an identifier to the cell structure element
    \edef\tagging:thecelid{t\the\tagging:tablec r\the\tagging:tablerow c\the\tagging:tablecol}%
    \expandafter\settagid\expandafter{\tagging:thecelid}}

% assign cells to their headers
\def\tagging:assignheaders{%
    \def\tagging:tmp{[}%
    \expandafter\tagging:assignheaders:do\expandafter\tagging:tablecol
        \tagging:tablecolheaders{}{}%
    \expandafter\tagging:assignheaders:do\expandafter\tagging:tablerow
        \tagging:tablerowheaders{}{}%
    \ifx\tagging:tmp\tagging:noheaders\else
        \tagattribute Table Headers {\tagging:tmp\space]}\fi}
\def\tagging:assignheaders:do#1#2#3{%
    \ifx\tagging:noheaders#3\tagging:noheaders
        \expandafter\tagging:assignheaders:done
    \else
        \ifnum#1=#2\relax
            % no cell is its own header
            \edef\tagging:cmp:a{\tagging:thecelid}%
            \edef\tagging:cmp:b{#3}%
            \unless\ifx\tagging:cmp:a\tagging:cmp:b
                \edef\tagging:tmp{\tagging:tmp\space\pdfstring{#3}}%
            \fi
        \fi
    \fi\tagging:assignheaders:do{#1}}
\def\tagging:noheaders{[}%]
\def\tagging:assignheaders:done#1#2{}
\def\tagging:thecelid{}

% \automarktable \halign ... { ... }
\def\automarktable#1#{\marktable
    \def\tagging:table{\tagging:mktrow{#1}}%
    \afterassignment\tagging:table
    \let\tagging:tmp= }% eats a bgroup
\def\tagging:mktrow#1#2&#3\cr{\iftrue
    \tagging:mktcell{#1\bgroup % \halign ...
        \marktablerow\marktablecell#2}\fi
        #3&\tagging:mktrow&\cr}
\def\tagging:mktcell#1#2\fi#3&{\fi
    % the next ifx is true on the last (artificial) template cell
    \ifx\tagging:mktrow#3\tagging:mkthdr{#1}\fi
    % the next ifx detects a double && (repeated template)
    \ifx\tagging:mktrow#3\tagging:mktrow
        \tagging:mktcell{#1&}\else
        \tagging:mktcell{#1&\marktablecell#3}\fi}
\def\tagging:mkthdr#1#2\cr#3\cr{\fi#1\cr
    \marktableheader#3\cr\marktablebody}

% 1 tagging helper macros

% \marktableaslist \halign ... { ... }
\def\marktableaslist#1#{\startelement{L}%
    \def\tagging:table{\tagging:mktlist{#1}}%
    \afterassignment\tagging:table
    \let\tagging:tmp= }% eats a bgroup
\def\tagging:mktlist#1#2&{#1\bgroup
    \startelement{LI}\savecurrentelementto\tagging:li
    \startelement{Lbl}#2&\continueelementfrom\tagging:li
    \startelement{LBody}\savecurrentelementto\tagging:lbody}

% \marktocentry {destination}{label}{title}{filler}{page}
\def\marktocentry#1#2#3#4#5{%
    \ifx\marktocentry#1\marktocentry
        \def\marktocentry:link##1{##1}\else
        \def\marktocentry:link##1{\hyperlink
            alt{\csname minim:str:page\endcsname#5}
            dest{#1}##1\endlink}\fi
    \markelement{TOCI}{\nextpartag{}\quitvmode
        \ifx\marktocentry#2\marktocentry\else
            \markelement{Lbl}{\marktocentry:link{#2}}\fi
        \markelement{Reference}{\marktocentry:link{#3%
            \ifx\marktocentry#4\marktocentry\else
                \markartifact{Layout}{#4}\fi#5}}}}
\def\minim:str:page{Page }

% \marknoteref {*}
\def\marknoteref#1{%
    \startelement ref{\newdestinationname}{Reference}%
    {\stopformulatagging#1}\stopelement{Reference}}
% \marknotelbl {*}
\def\marknotelbl#1{%
    \startelement id{\lastdestinationname}{Note}%
    \aftergroup\tagging:ensurestopNote
    \markelement{Lbl}{{\stopformulatagging#1}}}
\def\tagging:ensurestopNote{\ensurestopelement{Note}}

% 1 tagging formulas

% \autotagformulas
% \stopformulatagging ... \startformulatagging
% \formulafilename
\newif \iftagging:indisplay
\newif \iftagging:toplevelmath \tagging:toplevelmathtrue
\newif \iftagging:formulaenabled
\newif \iftagging:tagthisformula \tagging:tagthisformulatrue
\let\startformulatagging = \tagging:formulaenabledtrue
\let\stopformulatagging = \tagging:formulaenabledfalse
\newcount \tagging:formulanr
\def\formulafilename{unnumbered-equation-\the\tagging:formulanr}
\def\autotagformulas{\startformulatagging
    \everymath\expandafter{\the\everymath
        \tagging:formula\tagging:startformula}%
    \everydisplay\expandafter{\the\everydisplay \tagging:indisplaytrue
        \tagging:formula\tagging:startdisplay}}
\def\tagging:formula#1{%
    \iftagging:enabled \iftagging:formulaenabled \iftagging:toplevelmath
        \tagging:toplevelmathfalse #1\fi\fi\fi}
\def\tagging:startformula\fi\fi\fi#1${\tagging:makeformula{#1}{$}}
\def\tagging:startdisplay\fi\fi\fi#1$${\tagging:makeformula{#1}{$$}}
\def\tagging:makeformula#1#2{\fi\fi\fi
    \tagging:tagformula{#1}%
    \scantextokens{#1}#2}
\def\tagging:tagformula#1{%
    \iftagging:formulaenabled
        \global\advance\tagging:formulanr1\relax
        \startelement attr Layout Placement \iftagging:indisplay/Block\else/Inline
            % some html converters ignore Placement attributes
            attr CSS-2.00 display (inline)\fi{Formula}%
        \formulasource:set{#1}\fi}
\def\tagging:formulasource#1{%
    $\iftagging:indisplay$\fi
    \unexpanded{#1}%
    $\iftagging:indisplay$\fi}

% \includeformulasources {alttext,actualtext,attachment}
\def\formulasource:set#1{%
    \begingroup
        % strip \setalttext, \setactualtext
        \def\setalttext##1{}\def\setactualtext##1{}%
        \xdef\formulasource:thesource{#1}%
    \endgroup
    \expandafter\splitcommalist
        \expandafter\formulasource:do
            \expandafter{\the\includeformulasources}}
\def\formulasource:do#1{%
    \expandafter\expandafter \csname formulasource:#1\endcsname
        \expandafter{\formulasource:thesource}}
\def\formulasource:actualtext#1{%
    \setactualtext{\tagging:formulasource{#1}}}
\def\formulasource:alttext#1{%
    \setalttext{\tagging:formulasource{#1}}}
\def\formulasource:attachment#1{%
    \ifnum3=\pdfaconformancelevel
        \embedfile mimetype text/x-tex
            relation Source desc {Equation source}
            name {\formulafilename.tex}
            string {\tagging:formulasource{#1}}\fi}
\def\formulasource:none#1{}
\newtoks\includeformulasources
\includeformulasources{actualtext,attachment}

% for compatibility with earlier versions (DO NOT USE)
\def\formulasource:none#1{}
\def\formulasource:both#1{%
    \formulasource:actualtext{#1}%
    \formulasource:attachment{#1}}

% 1 hyperlinks

% provided by the lua module:
%    \newdestinationname
%    \lastdestinationname

% \nameddestination {name}
\def\nameddestination{\ifhmode\expandafter\linkdest:h\else\expandafter\linkdest:v\fi}
\def\linkdest:h#1{\vadjust pre{\linkdest:v{#1}}}
\def\linkdest:v#1{\pdfextension dest name {#1} xyz\nobreak}

% \hyperlink <args> ... \endlink
%   args: alt {...} attr {...} <type>
%   type: dest {name} | url {url} | next | prev | first | last
\protected\def\endlink{\pdfextension endlink\stopelement{Link}\relax}
\protected\def\startlink{\startelement{Link}\pdfextension startlink}
\protected\def\hyperlink{\quitvmode\startlink\hyper:makelink}

% \hyperlinkstyle { ... }
\def\minim:linkattr{\the\hyperlinkstyle\the\minim:pdfalinkattr}
\newtoks\hyperlinkstyle
\newtoks\minim:pdfalinkattr
\hyperlinkstyle{/Border [0 0 0]}

% 1 languages

% provided by the lua module:
%    \setdocumentlanguage {name or code}
%    \setlanguagecode {name} {code}

% \newnamedlanguage {name} {lhm} {rhm}
\def\newnamedlanguage#1#2#3{%
    \expandafter\newlanguage\csname lang@#1\endcsname
    \expandafter\chardef\csname lhm@#1\endcsname=#2\relax
    \expandafter\chardef\csname rhm@#1\endcsname=#3\relax
    \csname lu@texhyphen@loaded@\the\csname lang@#1\endcsname\endcsname}

% \newnameddialect {language} {dialect}
\def\newnameddialect#1#2{%
    \expandafter\chardef\csname lang@#2\endcsname\csname lang@#1\endcsname
    \expandafter\chardef\csname lhm@#2\endcsname\csname lhm@#1\endcsname
    \expandafter\chardef\csname rhm@#2\endcsname\csname rhm@#1\endcsname}

% and provide several dummy languages
\ifcsname lang@nohyph\endcsname \else
    \newnamedlanguage {nohyph} 1 1 \fi
\ifcsname lang@nolang\endcsname \else
    \newnameddialect {nohyph} {nolang} \fi
\ifcsname lang@uncoded\endcsname \else
    \newnameddialect {nohyph} {uncoded} \fi
\ifcsname lang@undetermined\endcsname \else
    \newnameddialect {nohyph} {undetermined} \fi

% 1 embedded files

% provided by the lua module
%    \embedfile <options>

% \setembeddedfilesmodate { yyyy-mm-dd }
\newtoks\setembeddedfilesmoddate
    \setembeddedfilesmoddate{}
\newtoks\embeddedfiles:moddate
\def\minim:makedefaultmoddate{%
    \expandafter\edef\expandafter
        \minim:tmp\expandafter{\the\setembeddedfilesmoddate}%
    \embeddedfiles:moddate\expandafter{\minim:tmp}}

% 1 declarations of pdf/a conformance

\newcount \pdfaconformancelevel
\pdfaconformancelevel = 0
\newcount \pdfuaconformancelevel
\pdfuaconformancelevel = 0

% \pdfalevel 2b
\def\pdfalevel#1#2{%
    \minim:pdfalinkattr{ /F 4}% hyperlinks must be printed
    \global\pdfaconformancelevel=#1\relax
    \ifcsname minim:pdfa:#1#2\endcsname \lastnamedcs\else
        \errmessage{Unknown pdf/a standard pdf/a-#1}\fi}

\def\minim:pdfasettings#1#2#3{%
    \pdfvariable minorversion #1\relax
    \minim:default:rgb:profile
    \if#2A\writedocumentstructure1\fi
    \input minim-xmp
    \pdfvariable omitcidset 1
    \setmetadata pdfaid:conformance{#2}%
    \setmetadata pdfaid:part{#3}}

\expandafter\def\csname minim:pdfa:1a\endcsname{\minim:pdfasettings 4A1}
\expandafter\def\csname minim:pdfa:1b\endcsname{\minim:pdfasettings 4B1}
\expandafter\def\csname minim:pdfa:2a\endcsname{\minim:pdfasettings 7A2}
\expandafter\def\csname minim:pdfa:2b\endcsname{\minim:pdfasettings 7B2}
\expandafter\def\csname minim:pdfa:2u\endcsname{\minim:pdfasettings 7U2}
\expandafter\def\csname minim:pdfa:3a\endcsname{\minim:pdfasettings 7A3}
\expandafter\def\csname minim:pdfa:3b\endcsname{\minim:pdfasettings 7B3}
\expandafter\def\csname minim:pdfa:3u\endcsname{\minim:pdfasettings 7U3}

% \pdfualavel 1
\def\pdfualevel{\input minim-xmp
    \setmetadata pdfuaid:part {1}
    \tagging:enablepdfua
    \global\pdfuaconformancelevel= }

% 

\catcode`\: = \minimpdfloaded

