diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx | 643 |
1 files changed, 546 insertions, 97 deletions
diff --git a/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx b/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx index 87f493d0d82..e0a1c013d7f 100644 --- a/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx +++ b/Master/texmf-dist/source/latex/tagpdf/tagpdf-checks.dtx @@ -22,59 +22,442 @@ % % for those people who are interested. % +% +%<*driver> +\RequirePackage{pdfmanagement-testphase} +\DeclareDocumentMetadata{} +\makeatletter +\declare@file@substitution{doc.sty}{doc-v3beta.sty} +\makeatother +\documentclass{l3doc} +\usepackage{array,booktabs,caption} +\hypersetup{pdfauthor=Ulrike Fischer, + pdftitle=tagpdf-checks module (tagpdf)} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> % \fi +% \title{^^A +% The \pkg{tagpdf-checks} module\\ Messages and check code ^^A +% \\ Part of the tagpdf package +% } +% +% \author{^^A +% Ulrike Fischer\thanks +% {^^A +% E-mail: +% \href{mailto:fischer@troubleshooting-tex.de} +% {fischer@troubleshooting-tex.de}^^A +% }^^A +% } +% +% \date{Version 0.9, released 2021-06-29} +% \maketitle +% \begin{documentation} +% \section{Commands} +% \begin{function}[pTF,EXP]{\tag_if_active:} +% This command tests if tagging is active. It only gives true if all tagging has +% been activated, \emph{and} if tagging hasn't been stopped locally. +% \end{function} +% \begin{function}[EXP]{\tag_get:n} +% \begin{syntax} +% \cs{tag_get:n}\Arg{keyword} +% \end{syntax} +% This is a generic command to retrieve data. Currently +% the only sensible values for the argument \meta{keyword} +% are |mc_tag| and |struct_tag|. +% \end{function} +% +% \section{Description of log messages} +% \subsection{\cs{ShowTagging} command} +% \begin{tabular}{lll} +% Argument & type & note\\ +% \cs{ShowTagging}{mc-data = num} & log+term & lua-only\\ +% \cs{ShowTagging}{mc-current} & log+term & \\ +% \cs{ShowTagging}{struck-stack= [log\verb+|+show]} & log or term+stop \\ +% \end{tabular} +% +% \subsection{Messages in checks and commands} +% \scriptsize +% \begin{tabular}{llll} +% command & message & action & remark\\ +% |\@@_check_structure_has_tag:n| +% & |struct-missing-tag| +% & error +% \\ +% |\@@_check_structure_tag:N| +% & |role-unknown-tag| +% & warning +% \\ +% |\@@_check_info_closing_struct:n| +% & |struct-show-closing| +% & info +% & log-level>0 +% \\ +% |\@@_check_no_open_struct:| +% & struct-faulty-nesting +% & error +% & TODO: error only with 1? +% \\ +% |\@@_check_struct_used:n| +% & |struct-used-twice| +% & warning +% \\ +% |\@@_check_add_tag_role:nn| +% & |role-missing|, |role-tag|, |role-unknown| +% & warning, info (>0), warning +% \\ +% |\@@_check_mc_if_nested:|, +% & |mc-nested| +% & warning +% \\ +% |\@@_check_mc_if_open:| +% & |mc-not-open| +% & warning +% & only generic (?) +% \\ +% |\@@_check_mc_pushed_popped:nn| +% & |mc-pushed|, |mc-popped| +% & info (2), info+|seq_log| (>2) +% \\ +% |\@@_check_mc_tag:N| +% & |mc-tag-missing|, |role-unknown-tag| +% & error (missing), warning (unknown). +% \\ +% |\@@_check_mc_used:n| +% & |mc-used-twice| +% & warning +% & TODO: review the sense of this test! +% \\ +% |\@@_check_show_MCID_by_page:| +% & +% & +% & currently unused +% \\ +% |\tag_mc_use:n| +% & |mc-label-unknown|, |mc-used-twice| +% & warning +% & in mc-shared +% \\ +% |\role_add_tag:nn| +% & |new-tag| +% & info (>0) +% & in roles +% \\ +% & |sys-no-interwordspace| +% & warning +% & space module, only xetex/dvi +% \\ +% |\@@_struct_write_obj:n| +% & |struct-no-objnum| +% & error +% & in struct module +% \\ +% |\tag_struct_begin:n| +% & |struct-faulty-nesting| +% & error +% \\ +% |\@@_struct_insert_annot:nn| +% & |struct-faulty-nesting| +% & error +% \\ +% |tag_struct_use:n| +% & |struct-label-unknown| +% & warning +% \\ +% |attribute-class|, |attribute| +% & |attr-unknown| +% & error +% \\ +% |\@@_tree_fill_parenttree:| +% & |tree-mcid-index-wrong| +% & warning +% TODO: should trigger a standard rerun message. +% \end{tabular} % +% \normalsize +% \subsection{Warning messages from the lua-code} +% The messages are triggered if the log-level is at least equal to the number. +% +% \begin{tabular}[t]{>{\ttfamily}lll} +% message & log-level & remark \\\hline +% WARN TAG-NOT-TAGGED: &1 \\ +% WARN TAG-OPEN-MC: &1 \\ +% WARN SHIPOUT-MC-OPEN: &1 \\ +% WARN SHIPOUT-UPS: &0 & shouldn't happen \\ +% WARN TEX-MC-INSERT-MISSING:&0 & shouldn't happen \\ +% WARN TEX-MC-INSERT-NO-KIDS:&2 & e.g. from empty hbox +% \end{tabular} +% +% \subsection{Info messages from the lua-code} +% The messages are triggered if the log-level is at least equal to the number. +% |TAG| messages are from the traversing function, |TEX| from code used in the tagpdf-mc module. +% |PARENTREE| is the code building the parenttree. +% +% \begin{longtable}{>{\ttfamily}lll} +% message & log-level & remark \\\hline\endhead +% INFO SHIPOUT-INSERT-LAST-EMC & 3 & finish of shipout code \\ +% INFO SPACE-FUNCTION-FONT & 3 & interwordspace code \\ +% INFO TAG-ABSPAGE & 3 \\ +% INFO TAG-ARGS & 4 \\ +% INFO TAG-ENDHEAD & 4 \\ +% INFO TAG-ENDHEAD & 4 \\ +% INFO TAG-HEAD & 3 \\ +% INFO TAG-INSERT-ARTIFACT & 3 \\ +% INFO TAG-INSERT-BDC & 3 \\ +% INFO TAG-INSERT-EMC & 3 \\ +% INFO TAG-INSERT-TAG & 3 \\ +% INFO TAG-KERN-SUBTYPE & 4\\ +% INFO TAG-MATH-SUBTYPE & 4 \\ +% INFO TAG-MC-COMPARE & 4 \\ +% INFO TAG-MC-INTO-PAGE & 3 \\ +% INFO TAG-NEW-MC-NODE & 4 \\ +% INFO TAG-NODE & 3 \\ +% INFO TAG-NO-HEAD & 3 \\ +% INFO TAG-NOT-TAGGED & 2 & replaced by artifact\\ +% INFO TAG-QUITTING-BOX & 4 \\ +% INFO TAG-STORE-MC-KID & 4 \\ +% INFO TAG-TRAVERSING-BOX 3 \\ +% INFO TAG-USE-ACTUALTEXT & 3 \\ +% INFO TAG-USE-ALT & 3 \\ +% INFO TAG-USE-RAW & 3 \\ +% INFO TEX-MC-INSERT-KID & 3 \\ +% INFO TEX-MC-INSERT-KID-TEST & 4 \\ +% INFO TEX-MC-INTO-STRUCT & 3 \\ +% INFO TEX-STORE-MC-DATA & 3 \\ +% INFO TEX-STORE-MC-KID & 3 \\ +% INFO PARENTTREE-CHUNKS & 3 \\ +% INFO PARENTTREE-NO-DATA & 3\\ +% INFO PARENTTREE-NUM & 3 \\ +% INFO PARENTTREE-NUMENTRY & 3 \\ +% INFO PARENTTREE-STRUCT-OBJREF & 4 +% \end{longtable} + +% \end{documentation} +% \begin{implementation} % \begin{macrocode} %<@@=tag> -%<*checks> -\ProvidesExplPackage {tagpdf-checks-code} {2021-06-14} {0.82} - {part of tagpdf - code related to checks and messages} - - -%messages - -% mc -\msg_new:nnn { tag } {mc-nested} { nested~marked~content~found~-~mcid~#1 } -\msg_new:nnn { tag } {mc-tag-missing} { required~tag~missing~-~mcid~#1 } -\msg_new:nnn { tag } {mc-label-unknown} { label~#1~unknown~-~rerun } -\msg_new:nnn { tag } {mc-used-twice} { mc~#1~has~been~already~used } -\msg_new:nnn { tag } {mc-not-open} { there~is~no~mc~to~end~at~#1 } -\msg_new:nnn { tag } {mc-pushed} { #1~has~been~pushed~to~the~mc~stack} -\msg_new:nnn { tag } {mc-popped} { #1~has~been~removed~from~the~mc~stack } - -% structures -\msg_new:nnn { tag } {struct-no-objnum} { objnum~missing~for~structure~#1 } -\msg_new:nnn { tag } {struct-faulty-nesting} { there~is~no~open~structure~on~the~stack } -\msg_new:nnn { tag } {struct-missing-tag} { a~structure~must~have~a~tag! } -\msg_new:nnn { tag } {struct-show-closing} { closing~structure~#1~tagged~\prop_item:cn{g_@@_struct_#1_prop}{S} } -\msg_new:nnn { tag } {struct-used-twice} { structure~with~label~#1~has~already~been~used} -\msg_new:nnn { tag } {struct-label-unknown} { structure~with~label~#1~is~unknown~rerun} - -% attributes +%<*header> +\ProvidesExplPackage {tagpdf-checks-code} {2021-06-29} {0.9} + {part of tagpdf - code related to checks, conditionals, debugging and messages} +%</header> +% \end{macrocode} +% \section{Messages} +% \subsection{Messages related to mc-chunks} +% \begin{macro}{mc-nested} +% This message is issue is a mc is opened before the previous has been closed. +% This is not relevant for luamode, as the attributes don't care about this. +% It is used in the |\@@_check_mc_if_nested:| test. +% \begin{macrocode} +%<*package> +\msg_new:nnn { tag } {mc-nested} { nested~marked~content~found~-~mcid~#1 } +% \end{macrocode} +% \end{macro} +% \begin{macro}{mc-tag-missing} +% If the tag is missing +% \begin{macrocode} +\msg_new:nnn { tag } {mc-tag-missing} { required~tag~missing~-~mcid~#1 } +% \end{macrocode} +% \end{macro} +% \begin{macro}{mc-label-unknown} +% If the label of a mc that is used in another place is not known (yet) +% or has been undefined as the mc was already used. +% \begin{macrocode} +\msg_new:nnn { tag } {mc-label-unknown} + { label~#1~unknown~or~has~been~already~used.\\ + Either~rerun~or~remove~one~of~the~uses. } +% \end{macrocode} +% \end{macro} +% \begin{macro}{mc-used-twice} +% An mc-chunk can be inserted only in one structure. This indicates wrong coding +% and so should at least give a warning. +% \begin{macrocode} +\msg_new:nnn { tag } {mc-used-twice} { mc~#1~has~been~already~used } +% \end{macrocode} +% \end{macro} +% \begin{macro}{mc-not-open} +% This is issued if a |\tag_mc_end:| is issued wrongly, wrong coding. +% \begin{macrocode} +\msg_new:nnn { tag } {mc-not-open} { there~is~no~mc~to~end~at~#1 } +% \end{macrocode} +% \end{macro} +% \begin{macro}{mc-pushed,mc-popped} +% Informational messages about mc-pushing. +% \begin{macrocode} +\msg_new:nnn { tag } {mc-pushed} { #1~has~been~pushed~to~the~mc~stack} +\msg_new:nnn { tag } {mc-popped} { #1~has~been~removed~from~the~mc~stack } +% \end{macrocode} +% \end{macro} +% \begin{macro}{mc-current} +% Informational messages about current mc state. +% \begin{macrocode} +\msg_new:nnn { tag } {mc-current} + { current~MC:~ + \bool_if:NTF\g_@@_in_mc_bool + {abscnt=\@@_get_mc_abs_cnt:,~tag=\g_@@_mc_key_tag_tl} + {no~MC~open,~current~abscnt=\@@_get_mc_abs_cnt:"} + } +% \end{macrocode} +% \end{macro} +% \subsection{Messages related to mc-chunks} +% \begin{macro}{struct-no-objnum} +% Should not happen \ldots +% \begin{macrocode} +\msg_new:nnn { tag } {struct-no-objnum} { objnum~missing~for~structure~#1 } +% \end{macrocode} +% \end{macro} +% \begin{macro}{struct-faulty-nesting} +% This indicates that there is somewhere one |\tag_struct_end:| too much. +% This should be normally an error. +% \begin{macrocode} +\msg_new:nnn { tag } + {struct-faulty-nesting} + { there~is~no~open~structure~on~the~stack } +% \end{macrocode} +% \end{macro} +% \begin{macro}{struct-missing-tag} +% A structure must have a tag. +% \begin{macrocode} +\msg_new:nnn { tag } {struct-missing-tag} { a~structure~must~have~a~tag! } +% \end{macrocode} +% \end{macro} +% \begin{macro}{struct-used-twice} +% \begin{macrocode} +\msg_new:nnn { tag } {struct-used-twice} + { structure~with~label~#1~has~already~been~used} +% \end{macrocode} +% \end{macro} +% \begin{macro}{struct-label-unknown} +% label is unknown, typically needs a rerun. +% \begin{macrocode} +\msg_new:nnn { tag } {struct-label-unknown} + { structure~with~label~#1~is~unknown~rerun} +% \end{macrocode} +% \end{macro} +% \begin{macro}{struct-show-closing} +% Informational message shown if log-mode is high enough +% \begin{macrocode} +\msg_new:nnn { tag } {struct-show-closing} + { closing~structure~#1~tagged~\prop_item:cn{g_@@_struct_#1_prop}{S} } +% \end{macrocode} +% \end{macro} +% +% \subsection{Attributes} +% Not much yet, as attributes aren't used so much. +% \begin{macro}{attr-unknown} +% \begin{macrocode} \msg_new:nnn { tag } {attr-unknown} { attribute~#1~is~unknown} - - -%Roles +% \end{macrocode} +% \end{macro} +% +% \subsection{Roles} +% \begin{macro}{role-missing,role-unknown,role-unknown-tag} +% Warning message if either the tag or the role is missing +% \begin{macrocode} \msg_new:nnn { tag } {role-missing} { tag~#1~has~no~role~assigned } \msg_new:nnn { tag } {role-unknown} { role~#1~is~not~known } \msg_new:nnn { tag } {role-unknown-tag} { tag~#1~is~not~known } +% \end{macrocode} +% \end{macro} +% \begin{macro}{role-tag,new-tag} +% Info messages. +% \begin{macrocode} \msg_new:nnn { tag } {role-tag} { mapping~tag~#1~to~role~#2 } \msg_new:nnn { tag } {new-tag} { adding~new~tag~#1 } - - -% trees -\msg_new:nnn { tag } {tree-mcid-index-wrong} {something~is~wrong~with~the~mcid} - -% obj -\msg_new:nnn { tag } {obj-write-num} {write~obj~#1~to~pdf} - -% engine problem -\msg_new:nnn { tag } {sys-no-interwordspace} {engine~#1~doesn't~support~the~interword~spaces} - -%checks -%structures - -\cs_new:Nn \@@_check_structure_has_tag:n %#1 struct num %_protected? +% \end{macrocode} +% \end{macro} +% +% \subsection{Miscellaneous} +% \begin{macro}{tree-mcid-index-wrong} +% Used in the tree code, typically indicates the document must be rerun. +% \begin{macrocode} +\msg_new:nnn { tag } {tree-mcid-index-wrong} + {something~is~wrong~with~the~mcid--rerun} +% \end{macrocode} +% \end{macro} +% \begin{macro}{sys-no-interwordspace} +% Currently only pdflatex and lualatex have some support for real spaces. +% \begin{macrocode} +\msg_new:nnn { tag } {sys-no-interwordspace} + {engine/output~mode~#1~doesn't~support~the~interword~spaces} +% \end{macrocode} +% \end{macro} +% \section{Retrieving data} +% \begin{macro}[EXP]{\tag_get:n} +% This retrieves some data. +% This is a generic command to retrieve data. Currently +% the only sensible values for the argument are |mc_tag| and |struct_tag|. +% \begin{macrocode} +\cs_new:Npn \tag_get:n #1 { \use:c {@@_get_data_#1: } } +% \end{macrocode} +% \end{macro} +% +% \section{User conditionals} +% \begin{macro}[pTF]{\tag_if_active:} +% This is a test it tagging is active. This allows packages +% to add conditional code. +% The test is true if all booleans, the global and the two local one are true. +% +% \begin{macrocode} +\prg_new_conditional:Npnn \tag_if_active: { p , T , TF, F } + { + \bool_lazy_all:nTF + { + {\g_@@_active_struct_bool} + {\g_@@_active_mc_bool} + {\g_@@_active_tree_bool} + {\l_@@_active_struct_bool} + {\l_@@_active_mc_bool} + } + { + \prg_return_true: + } + { + \prg_return_false: + } + } +% \end{macrocode} +% \end{macro} +% +% \section{Internal checks} +% These are checks used in various places in the code. +% +% \subsection{checks for active tagging} +% \begin{macro}[TF]{\@@_check_if_active_mc:,\@@_check_if_active_struct:} +% Structures must have a tag, so we check if the S entry is in the property. +% It is an error if this is missing. The argument is a number. +% \begin{macrocode} +\prg_new_conditional:Npnn \@@_check_if_active_mc: {T,F,TF} + { + \bool_lazy_and:nnTF { \g_@@_active_mc_bool } { \l_@@_active_mc_bool } + { + \prg_return_true: + } + { + \prg_return_false: + } + } +\prg_new_conditional:Npnn \@@_check_if_active_struct: {T,F,TF} + { + \bool_lazy_and:nnTF { \g_@@_active_struct_bool } { \l_@@_active_struct_bool } + { + \prg_return_true: + } + { + \prg_return_false: + } + } +% \end{macrocode} +% \end{macro} +% \subsection{Checks related to stuctures} +% \begin{macro}{\@@_check_structure_has_tag:n} +% Structures must have a tag, so we check if the S entry is in the property. +% It is an error if this is missing. The argument is a number. +% The tests for existence and type is split in structures, +% as the tags are stored differently to the mc case. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_structure_has_tag:n #1 %#1 struct num { \prop_if_in:cnF { g_@@_struct_#1_prop } {S} @@ -82,37 +465,50 @@ \msg_error:nn { tag } {struct-missing-tag} } } - -\cs_new:Nn \@@_check_structure_tag:N %_protected? +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_structure_tag:N} +% This checks if the name of the tag is known, +% either because it is a standard type or has been rolemapped. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_structure_tag:N #1 { \prop_if_in:NoF \g_@@_role_tags_prop {#1} { \msg_warning:nnx { tag } {role-unknown-tag} {#1} } } - -\cs_new:Nn \@@_check_structure_tag:NN %_protected? +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_info_closing_struct:n} +% This info message is issued at a closing structure, the use should be guarded by +% log-level. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_info_closing_struct:n #1 %#1 struct num { - \exp_args:NNx - \prop_if_in:NnF \g_@@_role_tags_prop {#1/#2} + \int_compare:nNnT {\l_@@_loglevel_int} > { 0 } { - \msg_warning:nnx { tag } {role-unknown-tag} {#1} + \msg_info:nnn { tag } {struct-show-closing} {#1} } } -\cs_new_protected:Nn \@@_check_info_closing_struct:n %#1 struct num - { - \msg_info:nnn { tag } {struct-show-closing} {#1} - } - \cs_generate_variant:Nn \@@_check_info_closing_struct:n {o,x} - -\cs_new_protected:Nn \@@_check_no_open_struck: +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_no_open_struct:} +% This checks if there is an open structure. It should be used when trying to +% close a structure. It errors if false.% +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_no_open_struct: { \msg_error:nn { tag } {struct-faulty-nesting} } - -\cs_new_protected:Nn \@@_check_struct_used:n %#1 label +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_struct_used:n} +% This checks if a stashed structure has already been used. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_struct_used:n #1 %#1 label { \prop_get:cnNT {g_@@_struct_\@@_ref_value:enn{tagpdfstruct-#1}{tagstruct}{unknown}_prop} @@ -122,10 +518,14 @@ \msg_warning:nnn { tag } {struct-used-twice} {#1} } } - -%roles - -\cs_new_protected:Nn \@@_check_add_tag_role:nn %#1 tag, #2 role +% \end{macrocode} +% \end{macro} +% +% \subsection{Checks related to roles} +% \begin{macro}{\@@_check_add_tag_role:nn} +% This check is used when defining a new role mapping. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_add_tag_role:nn #1 #2 %#1 tag, #2 role { \tl_if_empty:nTF {#2} { @@ -134,16 +534,26 @@ { \prop_get:NnNTF \g_@@_role_tags_prop {#2} \l_tmpa_tl { - \msg_info:nnnn { tag } {role-tag} {#1} {#2} + \int_compare:nNnT {\l_@@_loglevel_int} > { 0 } + { + \msg_info:nnnn { tag } {role-tag} {#1} {#2} + } } { \msg_warning:nnn { tag } {role-unknown} {#2} } } } - -%mc -\cs_new_protected:Nn \@@_check_mc_if_nested: +% \end{macrocode} +% \end{macro} +% +% \subsection{Check related to mc-chunks} +% +% \begin{macro}{\@@_check_mc_if_nested:,\@@_check_mc_if_open:} +% Two tests if a mc is currently open. One for the true (for begin +% code), one for the false part (for end code). +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_mc_if_nested: { \@@_mc_if_in:T { @@ -151,15 +561,21 @@ } } -\cs_new_protected:Nn \@@_check_mc_if_open: +\cs_new_protected:Npn \@@_check_mc_if_open: { \@@_mc_if_in:F { \msg_warning:nnx { tag } {mc-not-open} { \@@_get_mc_abs_cnt: } } } - -\cs_new_protected:Nn \@@_check_mc_pushed_popped:nn +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_mc_pushed_popped:nn} +% This creates an information message if mc's are pushed or popped. +% The first argument is a word (pushed or popped), the second the tag name. +% With larger log-level the stack is shown too. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_mc_pushed_popped:nn #1 #2 { \int_compare:nNnT { \l_@@_loglevel_int } ={ 2 } @@ -167,13 +583,16 @@ \int_compare:nNnT { \l_@@_loglevel_int } > { 2 } { - \msg_warning:nnx {tag}{mc-#1}{#2} - \seq_log:N \g_@@_mc_stack_seq + \msg_info:nnx {tag}{mc-#1}{#2} + \seq_log:N \g_@@_mc_stack_seq } } - - -\cs_new:Nn \@@_check_mc_tag:N %protected?? +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_mc_tag:N} +% This checks if the mc has a (known) tag. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_mc_tag:N #1 %#1 is var with a tag name in it { \tl_if_empty:NT #1 { @@ -184,22 +603,56 @@ \msg_warning:nnx { tag } {role-unknown-tag} {#1} } } - -\seq_new:N \g_@@_check_mc_used_seq -\cs_new_protected:Nn \@@_check_mc_used:n +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\g_@@_check_mc_used_intarray, \@@_check_init_mc_used:} +% This variable holds the list of used mc numbers. +% Everytime we store a mc-number we will add one the relevant array index +% If everything is right at the end there should be only 1 until the max count +% of the mcid. 2 indicates that one mcid was used twice, 0 that we lost one. +% In engines other than luatex the total number of all intarray entries +% are restricted so we use only a rather small value of 65536, and we initialize +% the array only at first used, guarded by the log-level. +% This check is probably only needed for debugging. +% TODO does this really make sense to check? When can it happen?? +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_init_mc_used: { - \seq_if_in:NnTF \g_@@_check_mc_used_seq {#1} - { - \msg_warning:nnn { tag } {mc-used-twice} {#1} - } + \intarray_new:Nn \g_@@_check_mc_used_intarray { 65536 } + \cs_gset_eq:NN \@@_check_init_mc_used: \prg_do_nothing: + } +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\@@_check_mc_used:n} +% This checks if a mc is used twice. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_mc_used:n #1 %#1 mcid abscnt + { + \int_compare:nNnT {\l_@@_loglevel_int} > { 2 } { - \seq_gput_right:Nx \g_@@_check_mc_used_seq {#1} + \@@_check_init_mc_used: + \intarray_gset:Nnn \g_@@_check_mc_used_intarray + {#1} + { \intarray_item:Nn \g_@@_check_mc_used_intarray {#1} + 1 } + \int_compare:nNnT + { + \intarray_item:Nn \g_@@_check_mc_used_intarray {#1} + } + > + { 1 } + { + \msg_warning:nnn { tag } {mc-used-twice} {#1} + } } } - - - -\cs_new_protected:Nn \@@_check_show_MCID_by_page: +% \end{macrocode} +% \end{macro} +% \begin{macro}{\@@_check_show_MCID_by_page:} +% This allows to show the mc on a page. Currently unused. +% \begin{macrocode} +\cs_new_protected:Npn \@@_check_show_MCID_by_page: { \tl_set:Nx \l_@@_tmpa_tl { @@ -245,14 +698,10 @@ \seq_show:N \l_tmpa_seq } } - -\cs_new:Nn \@@_check_record_pdfobj_num:n %protected? - { - \int_compare:nT { \l_@@_loglevel_int >= 3 } - { - \msg_info:nnx { tag } {obj-write-num} {#1} - } - } - -%</checks> % \end{macrocode} +% \end{macro} +% \begin{macrocode} +%</package> +% \end{macrocode} +% \end{implementation} +% \PrintIndex |