%D \module %D [ file=strc-sec, %D version=2008.10.20, %D title=\CONTEXT\ Structure Macros, %D subtitle=Sectioning, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D In retrospect I should have gone futher and move more to the %D \LUA\ end but here we are now. Maybe some day. \writestatus{loading}{ConTeXt Structure Macros / Sectioning} \unprotect \startcontextdefinitioncode \installcorenamespace{structure} \installdirectcommandhandler \??structure {structure} % unchecked, so we need to initialize used parameters \setupstructure % not a user command so we might need to change the name [\c!number=, \c!level=, \c!name=, \c!title=, \c!bookmark=, % no real need, default to empty anyway \c!marking=, % no real need, default to empty anyway \c!list=, % no real need, default to empty anyway \c!referencetext=, % no real need, default to empty anyway \c!label=, % no real need, default to empty anyway \c!coupling=, \c!ownnumber=, % \c!interaction=\v!list, \c!sectionseparatorset=\s!default, \c!sectionconversionset=\s!default, \c!sectionstopper=, \c!sectionstarter=, \c!sectionsegments=, \c!sectionresetset=, \c!reference=, \c!backreference=, \c!expansion=\v!no, \c!xmlsetup=, \s!catcodes=, \c!saveinlist=\v!yes] % maybe flags for list, bm, mark \def\m_strc_references_prefix_yes{+} \def\m_strc_references_prefix_nop{-} \mutable\let\currentstructurereferenceprefix\empty \mutable\let\currentstructurereferencetext \empty \installglobalmacrostack\currentstructurereferenceprefix \def\strc_sectioning_set_reference_prefix {\ifempty\currentstructurereferenceprefix % nothing \orelse\ifx\currentstructurereferenceprefix\m_strc_references_prefix_yes \global\advance\prefixcounter \plusone % temp here \setupglobalreferenceprefix[\the\prefixcounter]% \orelse\ifx\currentstructurereferenceprefix\m_strc_references_prefix_nop \setupglobalreferenceprefix[]% \else \setupglobalreferenceprefix[\currentstructurereferenceprefix]% \fi \glet\currentstructurereferenceprefix\referenceprefix} % why xdef ? \setupstructure [\c!label={\headparameter{\currentsectionblock\c!label}}, \c!incrementnumber=\ifconditional\c_strc_sectioning_increment\v!yes\else\v!no\fi, % not that needed \c!saveinlist=\ifconditional\c_strc_sectioning_to_list\v!yes\else\v!no\fi, \c!level=\currentheadlevel, \c!number=\ifconditional\c_strc_sectioning_increment\ifconditional\headshownumber\v!yes\else\v!no\fi\else\v!no\fi, \c!expansion=\headparameter\c!expansion, \c!xmlsetup=\headparameter\c!xmlsetup, \s!catcodes=\headparameter\s!catcodes, \c!sectionresetset=\headparameter\c!sectionresetset, \c!sectionseparatorset=\headparameter\c!sectionseparatorset, \c!sectionconversionset=\headparameter\c!sectionconversionset, \c!sectionconversion=\headparameter\c!conversion, % just for compatibility \c!sectionstarter=\headparameter\c!sectionstarter, \c!sectionstopper=\headparameter\c!sectionstopper, \c!sectionset=\headparameter\c!sectionset, \c!sectionsegments=\headparameter\c!sectionsegments, \c!reference=\headparameter\c!reference, \c!referenceprefix=\headparameter\c!referenceprefix, \c!criterium=\headparameter\c!criterium] % see lists/neat-001.tex for usage of: \permanent\def\namedstructureheadlocation#1% expandable, maybe [#1] {\csname\??savedinternalreference\ifcsname\??savedinternalreference#1\endcsname#1\else\s!default\fi\endcsname} \mutable\let\currentheadbackreference \empty \mutable\let\currentheaddefault \empty \mutable\let\currentheadincrement \empty \mutable\let\currentheadinteraction \empty \mutable\let\currentheadlabeltag \empty \mutable\let\currentheadnumber \!!zerocount \mutable\let\currentheadrenderingalternative\empty \mutable\let\currentheadrenderingsetup \empty \mutable\let\currentheadtext \empty % zeros: % % \setuphead[subsection][criterium=all] % % \dorecurse{3} { % \chapter{Blabla} \subsection{bla 1 1} \subsection{bla 1 2} % \section{bla 2} \subsection{bla 2 1} \subsection{bla 2 2} % } \protected\def\strc_sectioning_register#1#2#3% #1=interfaced-settings, #2=optional user data (not yet supported) {\begingroup \setupstructure[\c!name={#1},#2]% \xdef\currentstructurename {\structureparameter\c!name}% \xdef\currentstructurecoupling {\structureparameter\c!coupling}% \xdef\currentstructureownnumber {\structureparameter\c!ownnumber}% optional own number \xdef\currentstructurelevel {\structureparameter\c!level}% \edef\currentstructureexpansion {\structureparameter\c!expansion}% \xdef\currentstructurexmlsetup {\structureparameter\c!xmlsetup}% \xdef\currentstructurecatcodes {\structureparameter\s!catcodes}% \xdef\currentstructurelabel {\structureparameter\c!label}% \xdef\currentstructurereference {\structureparameter\c!reference}% \xdef\currentstructurereferenceprefix{\structureparameter\c!referenceprefix}% \xdef\currentstructurebackreference {\structureparameter\c!backreference}% \xdef\currentstructureshownumber {\structureparameter\c!number}% \xdef\currentstructuresaveinlist {\structureparameter\c!saveinlist}% \xdef\currentstructureincrementnumber{\structureparameter\c!incrementnumber}% \xdef\currentstructureplaceholder {\structureparameter\c!placeholder}% \ifx\currentstructureexpansion\s!xml \xmlstartraw \xdef\currentstructuretitle {\structureparameter\c!title}% \xdef\currentstructurebookmark {\structureparameter\c!bookmark}% \xdef\currentstructuremarking {\structureparameter\c!marking}% \xdef\currentstructurelist {\structureparameter\c!list}% \xdef\currentstructurereferencetext{\structureparameter\c!referencetext}% \xmlstopraw \iflocation \ifempty\currentstructurebookmark \xdef\currentstructurebookmark{\prerolltostring{\currentstructuretitle}}% \fi \fi \ifempty\currentstructurelist \glet\currentstructurelist\currentstructuretitle \fi \glet\currentstructurecoding\s!xml \else \ifx\currentstructureexpansion\v!yes \xdef\currentstructuretitle {\structureparameter\c!title}% \xdef\currentstructurebookmark {\structureparameter\c!bookmark}% \xdef\currentstructuremarking {\structureparameter\c!marking}% \xdef\currentstructurelist {\structureparameter\c!list}% \xdef\currentstructurereferencetext{\structureparameter\c!referencetext}% \iflocation \ifempty\currentstructurebookmark \xdef\currentstructurebookmark{\prerolltostring{\currentstructuretitle}}% \fi \fi \else \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% \xdef\currentstructurebookmark {\detokenizedstructureparameter\c!bookmark}% \xdef\currentstructuremarking {\detokenizedstructureparameter\c!marking}% \xdef\currentstructurelist {\detokenizedstructureparameter\c!list}% \xdef\currentstructurereferencetext{\detokenizedstructureparameter\c!referencetext}% \iflocation \ifempty\currentstructurebookmark \xdef\currentstructurebookmark{\prerolltostring{\structureparameter\c!title}}% \fi \fi \fi \ifempty\currentstructurelist \glet\currentstructurelist\currentstructuretitle \fi \glet\currentstructurecoding\s!tex \fi \iflocation \ifempty\currentstructurebookmark \orelse \ifx\currentstructurebookmark\currentstructuretitle \else %\showmessage\m!structures3{{\currentstructurebookmark}}% comma interference \writestatus{\m!structures}{bookmark:\space\currentstructurebookmark}% \fi \fi \setnextinternalreference \storeinternalreference\currentstructurename{\the\locationcount}% \strc_sectioning_set_reference_prefix \clf_setsectionentry references { internal \locationcount % block {\currentsectionblock} prefix {\currentstructurereferenceprefix} reference {\currentstructurereference} backreference {\currentstructurebackreference} } directives { resetset {\structureparameter\c!sectionresetset} } metadata { kind {section} name {\currentstructurename} catcodes \ifempty\currentstructurecatcodes\catcodetable\else\csname\currentstructurecatcodes\endcsname\fi\space coding {\currentstructurecoding} \ifx\currentstructurecoding\s!xml xmlroot {\xmldocument} \fi \ifempty\currentstructurexmlsetup \else xmlsetup {\currentstructurexmlsetup} \fi \ifx\currentstructuresaveinlist\v!no nolist \space true\space \fi \ifx\currentstructureincrementnumber\v!yes increment {\currentstructureincrementnumber} \fi } titledata { label {\detokenize\expandafter{\currentstructurelabel}} title {\detokenize\expandafter{\currentstructuretitle}} \ifx\currentstructurebookmark\currentstructuretitle \else bookmark {\detokenize\expandafter{\currentstructurebookmark}} \fi \ifx\currentstructuremarking\currentstructuretitle \else marking {\detokenize\expandafter{\currentstructuremarking}} \fi \ifx\currentstructuresaveinlist\v!no \else \ifx\currentstructurelist\currentstructuretitle \else list {\detokenize\expandafter{\currentstructurelist}} \fi \fi \ifx\currentstructurereferencetext\currentstructuretitle \else reference {\detokenize\expandafter{\currentstructurereferencetext}} \fi } numberdata { % block {\currentsectionblock} \ifx\currentstructureshownumber\v!no hidenumber \space true\space % space needed for parser \fi separatorset {\structureparameter\c!sectionseparatorset} conversionset {\structureparameter\c!sectionconversionset} conversion {\structureparameter\c!sectionconversion} starter {\structureparameter\c!sectionstarter} stopper {\structureparameter\c!sectionstopper} set {\structureparameter\c!sectionset} segments {\structureparameter\c!sectionsegments} ownnumber {\currentstructureownnumber} language {\currentlanguage}% for the moment, needed for bookmarks conversion criterium {\structureparameter\c!criterium} } userdata {\detokenize{#3}}% will be converted to table at the lua end \relax \xdef\currentstructurelistnumber{\clf_currentsectiontolist}% % \currentstructuresynchronize has to be called someplace, since it introduces a node \setstructuresynchronization\currentstructurelistnumber \endgroup} \mutable\let\currentsectioncountervalue \!!zerocount % redefined later \mutable\let\previoussectioncountervalue\!!zerocount % redefined later % We can access the (stored) data with the following macros. % % \def\MyHeadCommand #1#2{\framed{#1}\framed{#2 / \structureuservariable{subtitle}}} % \def\MyListCommand#1#2#3{\externalfigure[\structurelistuservariable{figure}][height=5mm]#2} % % \setuphead[chapter][command=\MyHeadCommand] % \setuplist[chapter][alternative=command,command=\MyListCommand] % % \starttext % \setupheadertexts[chapter] % \setupinteraction[state=start] % \placebookmarks[chapter] % \placelist[chapter] % \startchapter[ownnumber=10,title=Ton,list=Hans,marking=Kees,bookmark=Bram][figure=cow.pdf,subtitle=oeps] % \stopchapter % \stoptext % todo: #1 => "#1" ... adapt lua code for name and number \permanent\def\structurenumber {\clf_structurenumber} \permanent\def\structuretitle {\clf_structuretitle} \permanent\def\structurevariable #1{\clf_structurevariable {#1}} \permanent\def\structureuservariable #1{\clf_structureuservariable {#1}} \permanent\def\structurecatcodedget #1{\clf_structurecatcodedget {#1}} % bad name \permanent\def\structuregivencatcodedget #1#2{\clf_structuregivencatcodedget {#1}#2 } % bad name \permanent\def\structureautocatcodedget #1#2{\clf_structureautocatcodedget {#1}{#2}} \permanent\def\namedstructurevariable #1#2{\clf_namedstructurevariable {#1}{#2}} \permanent\def\namedstructureuservariable#1#2{\clf_namedstructureuservariable{#1}{#2}} % compatibility issue: % % \def\setfullsectionnumber #1{} % \def\preparefullnumber #1{} % \def\fullsectionnumber {1--1--1} % \def\makesectionnumber [#1]{} % \def\makesectionformat {} % \def\sectionformat {1--1-1-1-1-1-1} % \def\composedsectionnumber{} % \def\@@kolist{} % \setuphead[section] [separator=\separatorlist{?,!,*}] % \setuphead[subsection][separator=\separatorlist{??,!!,**}] % % \let\spr\separatorlist % this will enable this feature % % \setuphead[section] [separator={?,!,*}] % \setuphead[subsection][separator={??,!!,**}] % % \setupheads[separator={A,B,C,D,E,F}] % \chapter{test} % \section{test} \subsection{test} \subsection{test} % \section{test} \subsection{test} \subsection{test} % lua interface / names and interface might change % \newconditional\c_strc_rendering_continuous % not used (mkii ?) \permanent\def\setstructurelevel #1#2{\clf_setstructurelevel {#1}{#2}} % name, level|parent \permanent\def\getstructurelevel #1{\clf_getstructurelevel {#1}} % name \permanent\def\setstructurenumber #1#2{\clf_setstructurenumber #1{#2}} % level, number (+/-) \permanent\def\getstructurenumber #1{\clf_getstructurenumber \numexpr#1\relax} % level \permanent\def\getsomestructurenumber #1#2{\clf_getsomestructurenumber #1{#2}} % level, what \permanent\def\getfullstructurenumber #1{\clf_getfullstructurenumber \numexpr#1\relax} % level \permanent\def\getsomefullstructurenumber#1#2{\clf_getsomefullstructurenumber #1{#2}} % level, what \permanent\def\getspecificstructuretitle #1{\clf_getspecificstructuretitle {#1}{\headparameter\s!catcodes}} % structure heads (like \startchapter) % \c!deeptextcommand, \c!deepnumbercommand: undefined ! % \c!before \c!after \c!distance % \c!page \c!header \c!text \c!footer=, % \c!numbercommand \c!textcommand \c!ownnumber \c!number % \c!file \c!grid \c!margintext % \c!expansion \c!xmlsetup \s!catcode \installcorenamespace{head} \installcorenamespace{headlevel} \installcorenamespace{headincrement} \installcorenamespace{headplace} \installcorenamespace{headmarkyes} \installcorenamespace{headmarknop} \installcommandhandler \??head {head} \??head \installmacrostack\currenthead \installmacrostack\currentheadparent \setuphead [% %\c!after=, %\c!align=, %\c!aligntitle=, \c!alternative=\v!normal, %\c!before=, %\c!color=, %\c!command=, \c!continue=\v!yes, %\c!coupling=, %\c!deepnumbercommand=, %\c!deeptextcommand=, %\c!default=, \c!distance=\zeropoint, \c!textdistance=\zeropoint, \c!textwidth=\zeropoint, % signal too \c!numberwidth=\zeropoint, % signal too \c!width=\zeropoint, % signal too \c!expansion=\v!no, %\c!file=, %\c!footer=, %\c!grid=, \c!hang=\v!none, %\c!header=, \c!incrementnumber=\v!yes, \c!indentnext=\v!no, %\c!label=, %\c!limittext=\languageparameter\c!limittext, \c!margin=\zeropoint, %\c!margintext=, \c!number=\v!yes, \c!numbercolor=\headparameter\c!color, \c!textcolor=\headparameter\c!color, \c!numberstyle=\headparameter\c!style, \c!textstyle=\headparameter\c!style, %\c!numbercommand=, %\c!textcommand=, \c!ownnumber=\v!no, %\c!page=, \c!placehead=\v!yes, \c!sectionconversionset=\s!default, \c!sectionnumber=\v!yes, %\c!sectionsegments=, \c!sectionseparatorset=\s!default, \c!sectionset=\v!all, \c!interlinespace=, %\c!sectionstopper=, %\c!sectionstarter=, %\c!strut=, %\c!style=, %\c!text=, %\c!tolerance=, %\c!beforesection=\directsetup{document:\currenthead:start}, % these might become defaults i.e. acpect document: namespace %\c!insidesection=\directsetup{document:\currenthead:inside}, % these might become defaults i.e. acpect document: namespace %\c!aftersection=\directsetup{document:\currenthead:stop}, % these might become defaults i.e. acpect document: namespace ] \aliased\let\setupheads\setuphead % will go \appendtoks \ifempty\currentheadparent \edef\currentheaddefault{\headparameter\c!default}% \edef\currentheadsection{\headparameter\c!section}% \ifx\currenthead\currentheaddefault \let\currentheadparent\currentheadsection \orelse\ifempty\currentheaddefault \let\currentheadparent\currentheadsection \else \let\currentheadparent\currentheaddefault \fi \normalexpanded {% \setheadparameter{\c!label}{\currenthead}% \setheadparameter{\c!coupling}{\currenthead}% \setheadparameter{\s!parent}{\??head\currentheadparent}% \definemarking[\currenthead] [\currentheadsection]% \definemarking[\currenthead\v!number][\currentheadsection]% \setupmarking [\currenthead] [\c!filtercommand=\noexpand\sectionheadmarkingtitle {\currenthead}]% \setupmarking [\currenthead\v!number][\c!filtercommand=\noexpand\sectionheadmarkingnumber{\currenthead}]% }% \doifelselist\currenthead\donothing {\definelist[\currenthead][\c!prefix=\v!no]}% % we can't do this now for backward compatibility reasons % \doifelselist\currenthead\donothing % {\normalexpanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}% \else \normalexpanded {% \setheadparameter{\c!label}{\currenthead}% \setheadparameter{\c!coupling}{\currentheadparent}% \definemarking[\currenthead] [\currentheadparent]% \definemarking[\currenthead\v!number][\currentheadparent\c!number]% }% \doifelselist\currenthead\donothing {\normalexpanded{\definelist[\currenthead][\currentheadparent][\c!prefix=\v!no]}}% \fi \presetlabeltext[\currenthead=]% \the\everysetuphead \to \everydefinehead \newtoks\everyredefinehead \appendtoks \the\everyredefinehead \to \everydefinehead \appendtoks \setstructurelevel\currenthead{\thenamedheadlevel\currenthead}% \to \everyredefinehead \mutable\let\currentsectionheadcoupling\empty \mutable\let\currentsectionheadsection \empty \mutable\let\currentsectionlevel \empty \appendtoks % beware, this is a global register \begingroup \edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}% \edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}% \edef\currentsectionlevel {\sectionlevel \currentsectionheadsection}% \clf_registersection {\currenthead} { coupling {\currentsectionheadcoupling} section {\currentsectionheadsection} level \space \currentsectionlevel \space % space needed for parser parent {\currentheadparent} }% \endgroup \to \everyredefinehead \appendtoks \frozen\instance\protected\edefcsname\e!start\currenthead\endcsname{\strc_sectioning_start[\currenthead]}% \frozen\instance\protected\edefcsname\e!stop \currenthead\endcsname{\strc_sectioning_stop [\currenthead]}% \to \everydefinehead % so \subject as well as \section will need two commands when ownnumber % is used (one can disable it anyway for subject) .. this is not downward % compatible but better \appendtoks \ifempty\currenthead \else \doifelse{\headparameter\c!ownnumber}\v!yes {\instance\protected\edefcsname\currenthead\endcsname{\strc_sectioning_handle_own[\currenthead]}} {\instance\protected\edefcsname\currenthead\endcsname{\strc_sectioning_handle_nop[\currenthead]}}% \fi \to \everysetuphead \permanent\protected\def\doredefinehead#1#2% called at lua end {\push_macro_currenthead \push_macro_currentheadparent \edef\currenthead{#1}% \edef\currentheadparent{#2}% \the\everyredefinehead\relax \pop_macro_currentheadparent \pop_macro_currenthead} \mutable\let\currentnamedsection\empty \installmacrostack\currentnamedsection % structure sections (the parents of chapter etc) \aliased\let\firstsectionname\empty \aliased\let\lastsectionname \empty %aliased\let\resetallstructuremarks \relax %aliased\let\resetcurrentstructuremarks \relax \aliased\let\resetcurrentstructuremarkswithpage\relax \permanent\protected\def\resetallstructuremarks {\resetmarking[\firstsectionname]} % will become option (was \v!section-1) \permanent\protected\def\resetcurrentstructuremarks {\resetmarking[\lastsectionname]} % will become option %permanent\protected\def\resetcurrentstructuremarkswithpage{\resetmarking[\lastsectionname]} % will become option % We could use a commandhandler here but sections are somewhat special in the % sense that we have two ways of chaining: the main section (levels) as well % as rendering (head). % -2 = text % -1 = manual % 0 = block % +1 = structurelevel 1 .. n \newcount\maxstructuredepth \permanent\def\sectionlevel#1% {\csname\??headlevel\ifcsname\??headlevel#1\endcsname#1\else\v!none\fi\endcsname} \permanent\def\namedsectionlevel#1#2% direct indirect {\csname\??headlevel \ifcsname\??headlevel#1\endcsname #1% \orelse\ifcsname\??headlevel#2\endcsname #2% \else \v!none \fi \endcsname} \permanent\def\xthenamedheadlevel#1% {\namedsectionlevel{#1}{\sectionheadsection{\sectionheadcoupling{#1}}}} \defcsname\??headlevel\v!block\endcsname{0} \defcsname\??headlevel\v!none \endcsname{-1} \defcsname\??headlevel\v!text \endcsname{-2} \defcsname\??headlevel\v!head \endcsname{-3} \newtoks\everydefinesection \mutable\let\currentsection\empty % historic alias \permanent\protected\def\definesection[#1]% {\ifcsname\??headlevel#1\endcsname \else \edef\currenthead{#1}% \let\currentsection\currenthead % just an alias \global\advance\maxstructuredepth\plusone \setevalue{\??headlevel#1}{\the\maxstructuredepth}% \setstructurelevel{#1}{\sectionlevel{#1}}% \normalexpanded{\setheadparameter{\s!parent}{\??head\lastsectionname}}% TO BE CHECKED, WE HAVE A HELPER \the\everydefinesection % so far for these default inheritances \definemarking[#1]% \ifnum\maxstructuredepth>\plusone \normalexpanded{\relatemarking[#1][\lastsectionname]}% so, the parent will reset the child \fi \enforced\permanent\xdef\lastsectionname{#1}% \ifempty\firstsectionname \enforced\glet\firstsectionname\lastsectionname \fi \fi} \permanent\tolerant\protected\def\setupsection[#1]#*[#2]#*[#3]% {\ifparameter#1\else \push_macro_currenthead \edef\currenthead{\ifcsname\??headlevel#1\endcsname#1\else\sectionheadsection{#1}\fi}% \ifparameter#3\or \edef\currenthead{\currenthead#2}% not used at any more in mkiv (sets now) \setupcurrenthead[#3]% \else \setupcurrenthead[#2]% \fi \pop_macro_currenthead \fi} % we share the parameters as sections are roots of heads so eventually we can % consider \definesection -> \definehead with one argument \appendtoks % This is a rather practical default that we don't want to % be part of the parent chain lookup mechanism; it's also % mkii compatible. Somewhat weird that it's part of the % top level structure but it will be flattened anyway. % \let\currenthead\currentsection % hm \setheadparameter\c!textstyle {\directheadparameter\c!style}% \setheadparameter\c!textcolor {\directheadparameter\c!color}% \setheadparameter\c!numberstyle{\directheadparameter\c!style}% \setheadparameter\c!numbercolor{\directheadparameter\c!color}% \to \everydefinesection % head -> head \permanent\def\sectionheadmarkingtitle #1#2{\clf_markingtitle {#1}{#2}} % can be done at lua end \permanent\def\sectionheadmarkingnumber#1#2{\clf_markingnumber{#1}{#2}} % can be done at lua end \permanent\def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling} \permanent\def\sectionheadsection #1{\namedheadparameter{#1}\c!section} % head construction \newconditional\currentstructureown \newtoks\everybeforehead % hook, todo: before/after keys \newtoks\everyafterhead % hook, todo: before/after keys \permanent\tolerant\protected\def\strc_sectioning_handle_own[#1]#*[#2]#:#*#=#*#=% [ref] {nr} {title} {\settrue\currentstructureown \triggerautostructurelevel \strc_sectioning_handle{#1}{\c!reference={#2},\c!ownnumber={#3},\c!title={#4}}{}} % name ref nr title -- \permanent\tolerant\protected\def\strc_sectioning_handle_nop[#1]#*[#2]% [ref] {title} / for taco: [key=value] variant {\setfalse\currentstructureown \triggerautostructurelevel \ifhastok={#2}% \expandafter\strc_sectioning_handle_nop_indeed_yes \else \expandafter\strc_sectioning_handle_nop_indeed_nop \fi {#1}{#2}} \def\strc_sectioning_handle_nop_indeed_yes#1#2% {\strc_sectioning_handle{#1}{#2}{}} \def\strc_sectioning_handle_nop_indeed_nop#1#2#3% {\strc_sectioning_handle{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title -- \permanent\tolerant\protected\def\strc_sectioning_start[#1]#*[#2]#*[#3]% for the moment no grouping, too annoying with page breaks {\push_macro_currentnamedsection \push_macro_currentstructurereferenceprefix \edef\currentnamedsection{#1}% \setfalse\currentstructureown %\globalpushmacro\currenthead % this does not work out well \xdef\currenthead{#1}% \setsystemmode\currenthead % new, also here now \headparameter\c!beforesection % beware, no users vars set yet \the\everybeforehead \strc_sectioning_handle{#1}{#2}{#3}% name -- -- -- userdata (we might move the tagged to here) % potential: \bgroup (can be optional: grouped = yes) \headparameter\c!insidesection} \permanent\protected\def\strc_sectioning_stop[#1]% !!! also used at lua end {\dostoptagged \dostoptagged % potential: \egroup %\globalpopmacro\currenthead % so we do a hard recover \xdef\currenthead{#1}% recover \headparameter\c!aftersection \the\everyafterhead \resetsystemmode\currenthead \pop_macro_currentstructurereferenceprefix \pop_macro_currentnamedsection} % new, also here now \aliased\let\dostarthead\strc_sectioning_start % used at lua end \aliased\let\dostophead \strc_sectioning_stop % used at lua end % todo: add grouping but where: before/after trickery .. probably inside because one can always add % grouping to the before/after settings \aliased\let\startnamedsection\strc_sectioning_start \permanent\protected\def\stopnamedsection {\normalexpanded{\strc_sectioning_stop[\currentnamedsection]}} % \newconditional\structurereversesectionnumbers % todo: key/val \newconditional\c_strc_sectioning_to_list \newconditional\c_strc_sectioning_increment \newconditional\c_strc_sectioning_place \newconditional\c_strc_sectioning_empty \newconditional\c_strc_sectioning_hidden \newconditional\c_strc_sectioning_section \newconditional\headshownumber % public \newconditional\headisdisplay % public \newconditional\headissomewhere % public \defcsname\??headincrement\v!yes \endcsname{\settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list} \defcsname\??headincrement\v!no \endcsname{\setfalse\c_strc_sectioning_increment\setfalse\c_strc_sectioning_to_list} \defcsname\??headincrement\v!list \endcsname{\setfalse\c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list} \defcsname\??headincrement\s!empty\endcsname{\settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list} \protected\def\strc_sectioning_initialize_increment {\edef\currentheadincrement{\headparameter\c!incrementnumber}% \ifcsname\??headincrement\currentheadincrement\endcsname \lastnamedcs \else \settrue \c_strc_sectioning_increment\settrue \c_strc_sectioning_to_list % \filterheadnumber \fi} \permanent\protected\def\filterheadnumber {\settrue\c_strc_sectioning_increment \settrue\c_strc_sectioning_to_list \ifempty\currentproduct % todo : filter from other toc (number, file, title) % use : \currentheadincrement as spec \fi} \defcsname\??headplace\v!yes\endcsname {\setfalse\c_strc_sectioning_empty \settrue \c_strc_sectioning_place \setfalse\c_strc_sectioning_hidden \setfalse\c_strc_sectioning_section} \defcsname\??headplace\v!empty\endcsname {\settrue \c_strc_sectioning_empty \settrue \c_strc_sectioning_place \setfalse\c_strc_sectioning_hidden \setfalse\c_strc_sectioning_section} \defcsname\??headplace\v!no\endcsname {\settrue \c_strc_sectioning_empty \setfalse\c_strc_sectioning_place \setfalse\c_strc_sectioning_hidden \setfalse\c_strc_sectioning_section} \defcsname\??headplace\v!hidden\endcsname {\settrue \c_strc_sectioning_empty \setfalse\c_strc_sectioning_place \settrue \c_strc_sectioning_hidden \setfalse\c_strc_sectioning_section} \defcsname\??headplace\v!section\endcsname {\settrue \c_strc_sectioning_empty \setfalse\c_strc_sectioning_place \settrue \c_strc_sectioning_hidden \settrue \c_strc_sectioning_section} \protected\def\strc_sectioning_initialize_placement {\expandnamespaceparameter\??headplace\headparameter\c!placehead\v!yes} \newmode\v!sectionnumber \def\strc_sectioning_set_head_number_content % was: \dosetstructureheadnumbercontent {\setsystemmode\v!sectionnumber \settrue\headshownumber} % why ? \def\strc_sectioning_reset_head_number_content % was: \doresetstructureheadnumbercontent {\resetsystemmode\v!sectionnumber \setfalse\headshownumber} % why ? \protected\def\strc_sectioning_initialize_number {\edef\p_number{\sectionblockparameter\c!number}% \ifx\p_number\v!yes \edef\p_number{\headparameter\c!number}% \ifx\p_number\v!yes \settrue\headshownumber \else \setfalse\headshownumber \fi \else \setfalse\headshownumber \fi} % Beware, we do need some node for anchoring marks and normally a zwnj will % do but it interferes so we deal with it at the \LUA\ end. \newtoks\everyheadsynchronization % \appendtoks % \currentstructuresynchronize % \to \everyheadsynchronization \aliased\let\currentstructuresynchronize\donothing \appendtoks \currentstructuresynchronize \enforced\glet\currentstructuresynchronize\donothing \to \everyheadsynchronization \permanent\protected\def\theheadsynchronization % public {% no, interferes: \signalcharacter \the\everyheadsynchronization} % BEWARE: \marking[section]{my text} does not work as we use list indices instead % so we need a 'keep track of raw set option' (or maybe a funny internal prefix) \permanent\protected\def\setheadmarking % li:: so that we can use \marking[section]{Taco needed this} {\strc_sectioning_delayed_flush \normalexpanded{\setmarking[\currenthead]{li::\currentstructurelistnumber}}} \mutable\let\deepstructurenumbercommand\relax \mutable\let\deepstructuretitlecommand \relax \permanent\protected\def\fullheadnumber {\edef\currentheadlabeltag{\currentsectionblock\c!label}% \dostarttagged\t!sectionnumber\empty \labeltexts {\headparameter\currentheadlabeltag} {\ifrelax\deepstructurenumbercommand \structurenumber \else \normalexpanded{\noexpand\deepstructurenumbercommand{\structurenumber}}% \fi}% \dostoptagged} \permanent\protected\def\fullheadtitle {\dostarttagged\t!sectiontitle\empty \ifrelax\deepstructuretitlecommand \structuretitle \else \normalexpanded{\noexpand\deepstructuretitlecommand{\structuretitle}}% \fi \dostoptagged} \mutable\let\currenthead \empty \mutable\let\currentheadcoupling\empty \mutable\let\currentheadsection \empty \mutable\let\currentheadlevel \!!zerocount \mutable\let\currentheadcounter \!!zerocount \let\strc_show_used\relax \installtextracker {structures.showused} {\let\strc_show_used\clf_showstructure} {\let\strc_show_used\relax} \appendtoks \strc_show_used \to \everystoptext \protected\def\strc_sectioning_report{\clf_reportstructure} \ifdefined\strc_rendering_initialize_style_and_color \else \protected\def\strc_rendering_initialize_style_and_color#1#2% {\dontconvertfont \useheadstyleandcolor\c!style\c!color \useheadstyleandcolor#1#2% \setupinterlinespace} \fi \permanent\tolerant\protected\def\placeheadtext[#1]% {\dontleavehmode \begingroup \protected\def\\{\space}% messy here, but the default (and needs to be grouped) \global\settrue\headisdisplay % triggers interlinespace checking \edef\currenthead{#1}% maybe only when #1 is given \strc_rendering_initialize_style_and_color\c!textstyle\c!textcolor \relax \getspecificstructuretitle{\thenamedheadlevel{#1}}% \endgraf \endgroup} \permanent\tolerant\protected\def\placeheadnumber[#1]% {\dontleavehmode \begingroup \global\settrue\headisdisplay % triggers interlinespace checking \edef\currenthead{#1}% maybe only when #1 is given \strc_rendering_initialize_style_and_color\c!numberstyle\c!numbercolor \relax \getfullstructurenumber{\thenamedheadlevel{#1}}% \endgraf \endgroup} \ifdefined\triggerautostructurelevel \else \let\triggerautostructurelevel\relax \fi \newtoks\everybeforesectionheadhandle \newtoks\everyaftersectionheadhandle \mutable\let\getheadnumber\empty \mutable\let\getheadtitle \empty \mutable\let\getheadsyncs \empty \def\strc_sectioning_handle#1#2#3% name data userdata (we can move #1 to the caller) {\xdef\currenthead {#1}% \xdef\currentheadcoupling{\sectionheadcoupling\currenthead}% \xdef\currentheadsection {\sectionheadsection \currentheadcoupling}% \xdef\currentheadlevel {\sectionlevel \currentheadsection}% % %\writestatus\m!system{setup: \currenthead,\currentheadcoupling,\currentheadsection,\currentheadlevel}% % \strc_sectioning_initialize_autolevel \strc_sectioning_initialize_increment \strc_sectioning_initialize_placement \strc_sectioning_initialize_number % \the\everybeforesectionheadhandle % % todo: also mark (for header) % % we might remove the lower level % % not here, after optional \page: \strc_sectioning_register{#1}{#2}{#3}% % % \xdef\currentheadcounter{\currentsectioncountervalue}% lua call % % \currentstructuresynchronize % will move % \let\getheadnumber\empty \let\getheadtitle \empty \let\getheadsyncs \empty \ifconditional\c_strc_sectioning_increment \ifconditional\c_strc_sectioning_place \strc_sectioning_before_yes \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchronization \let\getheadtitle\fullheadtitle \ifconditional\headshownumber \let\getheadnumber\fullheadnumber \strc_rendering_place_head_number_and_text \else \strc_rendering_place_head_text \fi \dostoptagged \strc_sectioning_after_yes \orelse\ifconditional\c_strc_sectioning_hidden \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchronization \ifconditional\c_strc_sectioning_section \strc_rendering_place_head_section \else \strc_rendering_place_head_hidden % only something when tracing \fi \dostoptagged \else \strc_sectioning_before_nop % toegevoegd ivm subpaginanr / tug sheets \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchronization \strc_rendering_place_head_empty % just flush 'm \dostoptagged \strc_sectioning_after_nop \fi \else \ifconditional\c_strc_sectioning_place \strc_sectioning_before_yes \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchronization \let\getheadtitle\fullheadtitle \strc_rendering_place_head_text \dostoptagged \strc_sectioning_after_yes \orelse\ifconditional\c_strc_sectioning_hidden \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \let\getheadsyncs\theheadsynchronization \dostarttagged\t!sectioncaption\empty \ifconditional\c_strc_sectioning_section \strc_rendering_place_head_section \else \strc_rendering_place_head_hidden % only something when tracing \fi \dostoptagged \else % do nothing / should be vbox to 0pt \strc_sectioning_before_nop \strc_sectioning_register{#1}{#2}{#3}% after optional \page \strc_sectioning_report \dostarttagged\t!sectioncaption\empty \let\getheadsyncs\theheadsynchronization \strc_rendering_place_head_empty % just flush 'm \dostoptagged \strc_sectioning_after_nop \fi \fi % \the\everyaftersectionheadhandle % \setfalse\c_strc_sectioning_ignore_page % ignorespaces prevents spaces creeping in when after=\dontleavehmode \dostarttagged\t!sectioncontent\empty \ifempty\currentstructureplaceholder \ifconditional\headisdisplay \doubleexpandafter\ignorespaces \else \doubleexpandafter\ignorepars \fi \else \expandafter\strc_sectioning_placeholder \fi} %D \starttyping %D \startsubject[placeholder=todo,title=one] %D whatever one %D \stopsubject %D \stoptyping \def\strc_sectioning_placeholder {\placeholder[\currentstructureplaceholder]% \gobblenested{\e!start\currenthead}{\e!stop\currenthead}{\e!stop\currenthead}} % typesetting (the getters are public) \protected\def\strc_rendering_place_head_number_and_text {\setheadmarking \getheadnumber/\getheadtitle \getheadsyncs} \protected\def\strc_rendering_place_head_text {\setheadmarking \getheadtitle \getheadsyncs} \protected\def\strc_rendering_place_head_empty {\setheadmarking \getheadsyncs} \installcorenamespace{hiddenheadattr} \installcorenamespace{hiddenheadsync} % todo: when in the page builder we need to resolve the marking immediately % because otherwise we have an async \newbox\b_sectioning_delayed \def\strc_sectioning_delayed_flush {\ifvoid\b_sectioning_delayed\else \smashedbox\b_sectioning_delayed \fi} \protected\def\strc_rendering_place_head_section % see hidden below {\global\setbox\b_sectioning_delayed\hpack\bgroup \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% \hpack\headreferenceattributes{}% also does the mark \theheadsynchronization \egroup} \protected\def\strc_rendering_place_head_hidden % maybe trialtypesetting check {\xdefcsname\??hiddenheadattr\currenthead\endcsname {\headreferenceattributes}% can be used when making a box \xdefcsname\??hiddenheadsync\currenthead\endcsname {\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference \theheadsynchronization}} % and it's a node anyway \permanent\def\synchronizehead #1{\begincsname\??hiddenheadsync#1\endcsname} \permanent\def\theheadreferenceattributes#1{\begincsname\??hiddenheadattr#1\endcsname} \permanent\protected\def\placerawheaddata [#1]{\synchronizehead{#1}} \permanent\protected\def\placerawheadtext [#1]{\getspecificstructuretitle{\thenamedheadlevel{#1}}} \permanent\protected\def\placerawheadnumber[#1]{\getfullstructurenumber{\thenamedheadlevel{#1}}} \permanent\protected\def\repeathead[#1]% {\begingroup \setupinteraction[\c!state=\v!stop]% \def\currenthead{#1} \strc_sectioning_initialize_placement \strc_sectioning_initialize_number \dostarttagged\t!sectioncaption\empty \let\getheadsyncs \relax \def\getheadtitle {\getmarking[#1]} \def\getheadnumber{\getmarking[#1\v!number]} \strc_sectioning_before_yes \ifconditional\headshownumber \strc_rendering_place_head_number_and_text \else \strc_rendering_place_head_text \fi \dostoptagged \strc_sectioning_after_yes \endgroup} % \setuphead[chapter][placehead=hidden] % \chapter {test} % % %(\synchronizehead{chapter}) % \getheadsyncs % %(\getfullstructurenumber{\thenamedheadlevel{chapter}}) % %(\getspecificstructuretitle{\thenamedheadlevel{chapter}}) % % (\placerawheaddata [chapter]) % (\placerawheadnumber[chapter]) % (\placerawheadtext [chapter]) % pagebreaks \letcsname\??headmarknop\v!page \endcsname\donothing \defcsname\??headmarknop\v!reset \endcsname{\resetcurrentstructuremarks} \letcsname\??headmarknop\s!unknown\endcsname\donothing \letcsname\??headmarkyes\v!page \endcsname\donothing % to be checked: {\resetcurrentstructuremarks} \defcsname\??headmarkyes\v!reset \endcsname{\resetcurrentstructuremarks} \letcsname\??headmarkyes\s!unknown\endcsname\donothing \def\strc_sectioning_check_layout {\edef\p_page{\headparameter\c!page}% \ifempty\p_page \strc_sectioning_check_layout_nop \else \strc_sectioning_check_layout_yes \fi} \def\strc_sectioning_check_layout_nop {\expandnamespaceparameter\??headmarknop\headparameter\c!marking\s!unknown} \def\strc_sectioning_check_layout_yes {\page[\p_page]% \expandnamespaceparameter\??headmarkyes\headparameter\c!marking\s!unknown \edef\p_header{\headparameter\c!header}% \ifempty\p_header \else \doifelselayouttextline\v!header{\normalexpanded{\setuplayouttext[\v!header][\c!state=\p_header]}}\donothing \fi \edef\p_text{\headparameter\c!text}% \ifempty\p_text \else \doifelselayouttextline\v!text {\normalexpanded{\setuplayouttext[\v!text ][\c!state=\p_text ]}}\donothing \fi \edef\p_footer{\headparameter\c!footer}% \ifempty\p_footer \else \doifelselayouttextline\v!footer{\normalexpanded{\setuplayouttext[\v!footer][\c!state=\p_footer]}}\donothing \fi} \newcount \c_strc_sectioning_preceding_level \c_strc_sectioning_preceding_level\plusone \newconditional\c_strc_sectioning_auto_break \settrue\c_strc_sectioning_auto_break \newconditional\c_strc_sectioning_ignore_page \newsignal \d_strc_sectioning_continuous_signal \protected\def\strc_sectioning_inject_continuous_signal {\ifhmode \hskip\d_strc_sectioning_continuous_signal\relax \fi} % \let\dotagsectionlevel\relax \def\strc_sectioning_before_yes {\strc_sectioning_check_before\strc_sectioning_handle_page_yes \headparameter\c!inbetween \dostarttaggedchained\t!section\currenthead\??head % \dotagsectionlevel } \def\strc_sectioning_before_nop {\strc_sectioning_check_before\strc_sectioning_handle_page_nop \headparameter\c!inbetween \dostarttagged\currenthead\empty} % this is a weird one .. needs checking \def\strc_sectioning_empty_correction {\ifconditional\c_strc_sectioning_empty % this needs checking \penalty\plustenthousand \vskip-\lineheight \kern\zeropoint \prevdepth\strutdepth \fi} \def\strc_sectioning_after_nop {} \def\strc_sectioning_check_before#1% {\ifhmode \scratchcounter\lastpenalty \unpenalty % no beauty in this \ifdim\lastskip=\d_strc_sectioning_continuous_signal % no page break \ifconditional\c_strc_sectioning_ignore_page \setfalse\c_strc_sectioning_ignore_page \else \global\c_strc_sectioning_preceding_level\currentheadlevel \nobreak \fi % \global\settrue\c_strc_rendering_continuous \else \penalty\scratchcounter % \global\setfalse\c_strc_rendering_continuous #1% \fi \else % \global\setfalse\c_strc_rendering_continuous #1% \fi} %permanent\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax} %permanent\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax} \permanent\def\currentsectioncountervalue {\clf_depthnumber\numexpr\thenamedheadlevel\currenthead\relax} %permanent\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\currenthead+\minusone\relax} \permanent\def\previoussectioncountervalue{\clf_depthnumber\numexpr\thenamedheadlevel\previoushead\relax} \mutable\let\previoushead\empty \def\strc_sectioning_handle_page_nop {\edef\p_continue{\headparameter\c!continue}% \ifx\p_continue\v!yes \ifx\currenthead\previoushead % not really needed \strc_sectioning_check_layout \orelse\ifnum\previoussectioncountervalue=\zerocount \strc_sectioning_check_layout \orelse\ifnum\currentsectioncountervalue>\zerocount \strc_sectioning_check_layout \fi \else \strc_sectioning_check_layout \fi \glet\previoushead\currenthead} \def\strc_sectioning_handle_page_yes {\ifconditional\c_strc_sectioning_ignore_page \setfalse\c_strc_sectioning_ignore_page \else % beware, these numbers are not yet know here \strc_sectioning_handle_page_nop \edef\p_aligntitle{\headparameter\c!aligntitle}% \ifx\p_aligntitle\v!float \ifconditional\c_strc_sectioning_auto_break \spac_vspacing_same_page\currentheadlevel\zerocount \fi \headparameter\c!before\relax \indent \else \page_otr_command_flush_side_floats \ifconditional\c_strc_sectioning_auto_break \spac_vspacing_same_page\currentheadlevel\zerocount \fi \headparameter\c!before\relax \fi \global\c_strc_sectioning_preceding_level\currentheadlevel \fi \glet\previoushead\currenthead} \def\strc_sectioning_depth_correction {\ifvmode \edef\p_depthcorrection{\headparameter\c!depthcorrection}% \ifx\p_depthcorrection\v!strut \prevdepth\strutdepth \fi \fi} \def\strc_sectioning_after_yes {\ifconditional\headisdisplay \ifconditional\c_strc_sectioning_auto_break \spac_vspacing_same_page\currentheadlevel\plusone \fi \strc_sectioning_empty_correction \headparameter\c!after \strc_sectioning_depth_correction \fi} \protected\def\strc_sectioning_prevent_page_break % see strc-con {\ifconditional\c_strc_sectioning_auto_break \spac_vspacing_same_page\currentheadlevel\plustwo \fi} % We do support negative numbers but it can have side effects that we won't catch: % % \chapter{some} \setupheadnumber[chapter][3] \chapter{more} % \setupheadnumber[section][8] \section{b} \section{c} \setupheadnumber[section][-1] \section{d} \permanent\def\thenamedheadlevel#1% {\sectionlevel{\sectionheadsection{\sectionheadcoupling{#1}}}} \permanent\tolerant\protected\def\setupheadnumber[#1]#*[#2]% todo: reset if at other level {\setstructurenumber{\thenamedheadlevel{#1}}{\number#2}} \permanent\protected\def\determineheadnumber[#1]% {\xdef\currentheadnumber{\getstructurenumber{\thenamedheadlevel{#1}}}} % The previous macro is been replaced by the expandable: \permanent\def\namedheadnumber #1{\getstructurenumber {\thenamedheadlevel{#1}}} \permanent\def\somenamedheadnumber#1#2{\getsomestructurenumber{\thenamedheadlevel{#1}}{#2}} \permanent\tolerant\protected\def\headnumber[#1]#*[#2]% {\getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}} \permanent\tolerant\protected\def\someheadnumber[#1]#*[#2]% {\dontleavehmode \begingroup \edef\currenthead{#1}% \getsomefullstructurenumber{\thenamedheadlevel{#1}}{#2}% \endgroup} % \mutable\def\currentheadtext{obsolete,\space use marks} % list references, will be redone in lua when we need it % \let\startlistreferences\relax % \let\stoplistreferences \relax % experimental \newconditional\c_strc_sectioning_auto_levels \appendtoks \settrue\c_strc_sectioning_auto_levels \to \everyenableelements \protected\def\strc_sectioning_initialize_autolevel {\ifconditional\c_strc_sectioning_auto_levels \clf_autonextstructurelevel\currentheadlevel\relax \global\setfalse\c_strc_sectioning_auto_levels \fi} \permanent\protected\def\triggerautostructurelevel {\global\settrue\c_strc_sectioning_auto_levels} \permanent\protected\def\finalizeautostructurelevels {\clf_autofinishstructurelevels} \permanent\protected\def\finalizeautostructurelevel {\dostoptagged \dostoptagged} \appendtoks \finalizeautostructurelevels \to \everystoptext \stopcontextdefinitioncode \protect \endinput