%D \module %D [ file=strc-reg, %D version=2008.10.20, %D title=\CONTEXT\ Structure Macros, %D subtitle=Registers, %D author=Hans Hagen, %D date=\currentdate, %D copyright=PRAGMA-ADE / Hans Hagen] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Structure Macros / Registers} \registerctxluafile{strc-reg}{1.001} \unprotect \def\c!keys {keys} \def\c!entries{entries} % todo: tag:: becomes rendering % todo: language, character, linked, location %D Helper: % \def\doflushatpar{\ifvmode\expandafter\dogotopar\else\expandafter\firstofoneargument\fi} \def\doflushatpar{\ifvmode\expandafter\flushatnextpar\else\expandafter\firstofoneargument\fi} % \starttext % \placeregister[index] % \chapter{a} \index{93} \index{456} \index{***} \index{*} \index{@} % test \index{aa} test \startregister[index][x]{bb} test \page test \page test \page test \stopregister[index][x] % test \index{aa} test \setregisterentry[index][label=x,entries=bb] test \page test \page test \page test \finishregisterentry[index][label=x] % test \index{aa} test \setregisterentry[index][label=y] test \page test \page test \page test \finishregisterentry[index][label=y,entries=yy] % \stoptext % In plaats van + kan een & worden gebruikt. Ook kan als % eerste karakter worden opgegeven wat de scheider is. % % \index {entry} % \index[key] {entry} % \index[pageclass::] {entry} % \index[pageclass::key]{entry} % \index {textclass::entry} % \index[key] {textclass::entry} % \index[pageclass::] {textclass::entry} % \index[pageclass::key]{textclass::entry} %D Parameters: \let\currentregister\empty % \def\registerparameter#1{\csname\??id\currentregister#1\endcsname} \def\detokenizedregisterparameter#1{\detokenize\expandafter\expandafter\expandafter{\csname\??id#1\endcsname}} % always root \def\registerparameter #1{\csname\doregisterparameter{\??id\currentregister}{#1}\endcsname} \def\registerparameterhash#1{\doregisterparameterhash {\??id\currentregister}#1} \def\doregisterparameter #1#2{\ifcsname#1#2\endcsname#1#2\else\expandafter\doregisterparentparameter \csname#1\s!parent\endcsname{#2}\fi} \def\doregisterparameterhash#1#2{\ifcsname#1#2\endcsname #1\else\expandafter\doregisterparentparameterhash\csname#1\s!parent\endcsname{#2}\fi} \def\doregisterparentparameter #1#2{\ifx#1\relax\s!empty\else\doregisterparameter #1{#2}\fi} \def\doregisterparentparameterhash#1#2{\ifx#1\relax \else\doregisterparameterhash#1{#2}\fi} \def\dosetregisterattributes#1#2% style color {\edef\fontattributehash {\registerparameterhash#1}% \edef\colorattributehash{\registerparameterhash#2}% \ifx\fontattributehash \empty\else\dosetfontattribute \fontattributehash #1\fi \ifx\colorattributehash\empty\else\dosetcolorattribute\colorattributehash#2\fi} %D Setup: \newtoks\everysetupregister \unexpanded\def\setupregisters {\dotripleempty\dosetupregisters} \def\dosetupregisters[#1][#2][#3]% {\ifthirdargument \def\dodosetupregister##1{\getparameters[\??id##1#2][#3]}% \processcommalist[#1]\dodosetupregister \else\ifsecondargument \def\dodosetupregister##1{\edef\currentregister{##1}\getparameters[\??id##1][#2]\the\everysetupregister}% \processcommalist[#1]\dodosetupregister \else \getparameters[\??id][#1]% \fi\fi} \let\setupregister\setupregisters \setupregisters [\c!n=2, \c!balance=\v!yes, % \v!no komt niet zo vaak voor \c!align=\v!flushleft, \c!tolerance=\v!stretch, \c!before=\blank, %\c!after=, %\c!symbol=, \c!compress=\v!no, \c!interaction=\v!pagenumber, \c!alternative=\v!a, \c!distance=1em, \c!style=\v!bold, \c!pagestyle=\v!slanted, \c!indicator=\v!yes, \c!criterium=\v!all, %\c!command=, \c!referencing=\v!on, \c!location=\v!middle, %\c!maxwidth=, \c!number=\v!no, \c!unknownreference=\v!empty, \c!prefix=\v!both, %\c!expansion=, %\c!xmlsetup=, \c!pageprefixconnector=\endash, \c!pagesegments=2:2, \c!file=\jobname, %\c!deeptextcommand=, % undefined by default ! \s!language=\currentmainlanguage]% %D Definition: \unexpanded\def\defineregister {\dodoubleargument\dodefineregister} \def\dodefineregister[#1][#2]% #2? {\setupregister[#1][\s!parent=\??id]% \ctxlua{jobregisters.define('#1')}% \presetheadtext[#1=\Word{#1}]% \setuvalue{#1}{\dodoubleempty\doregister[#1]}% \setuvalue{\e!see#1}{\dodoubleempty\doseeregister[#1]}% % \setuvalue{\e!coupled#1}{\dolinkedregister{#1}}% \setvalue{\e!place#1}{\placeregister[#1]}% \setvalue{\e!complete#1}{\completeregister[#1]}% \setvalue{\e!setup#1\e!endsetup}[##1]{\getparameters[\??id#1][##1]}} %D Registering: \newif\ifwritetoregister \writetoregistertrue % tzt variant met n entries, parameters en userdata (altnum) \getparameters [\??id] [\c!label=, \c!entries=, \c!entries:1=,\c!entries:2=,\c!entries:3=, \c!keys:1=,\c!keys:2=,\c!keys:3=, \c!alternative=] \def\doregisterstructurepageregister {\iftrialtypesetting \expandafter\gobblethreearguments \else \expandafter\dodoregisterstructurepageregister \fi} \def\dodoregisterstructurepageregister#1#2#3% register data userdata {\begingroup \edef\currentregister{#1}% %getparameters[\??id][\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% \getparameters[\??id][#2]% \edef\currentregisterlabel {\registerparameter\c!label}% \edef\currentregisterexpansion{\registerparameter\c!expansion}% \edef\currentregisterownnumber{\registerparameter\c!ownnumber}% \xdef\currentregisterkeys {\registerparameter\c!keys}% \xdef\currentregisterentries {\registerparameter\c!entries}% \xdef\currentregisterxmlsetup {\registerparameter\c!xmlsetup}% \ifx\currentregisterentries\empty \ifx\currentregisterexpansion\s!xml \xmlstartraw \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% \xmlstopraw \globallet\currentregistercoding\s!xml \else \ifx\currentregisterexpansion\v!yes \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% \else \xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}% \fi \globallet\currentregistercoding\s!tex \fi \else \ifx\currentregisterexpansion\s!xml \xmlstartraw \xdef\currentregisterentries{\registerparameter\c!entries}% \xmlstopraw \globallet\currentregistercoding\s!xml \else \ifx\currentregisterexpansion\v!yes \xdef\currentregisterentries{\registerparameter\c!entries}% \else \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% \fi \globallet\currentregistercoding\s!tex \fi \fi \ifx\currentregisterkeys\empty \ifx\currentregistercoding\s!xml \xmlstartraw \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% \xmlstopraw \else \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% \fi \fi \setnextinternalreference % we could consider storing register entries in a list which we % could then sort \xdef\currentregisternumber{\ctxlua{ jobregisters.store { % 'own' should not be in metadata metadata = { kind = "entry", name = "\currentregister", level = structure.sections.currentlevel(), coding = "\currentregistercoding", catcodes = \the\catcodetable, \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text \ifx\currentregisterxmlsetup\empty \else xmlsetup = "\currentregisterxmlsetup", \fi }, references = { internal = \nextinternalreference, section = structure.sections.currentid(), % hm, why then not also lastsection the same way label = "\currentregisterlabel", }, % \ifx\currentregisterentries\empty \else entries = { % we need a special one for xml, this is just a single one \ifx\currentregisterentries\empty { \!!bs\currentregisterentriesa\!!es, \!!bs\currentregisterentriesb\!!es, \!!bs\currentregisterentriesc\!!es }, \else \!!bs\currentregisterentries\!!es, \fi \ifx\currentregisterkeys\empty { \!!bs\currentregisterkeysa\!!es, \!!bs\currentregisterkeysb\!!es, \!!bs\currentregisterkeysc\!!es }, \else \!!bs\currentregisterkeys\!!es, \fi }, % \fi userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) } } }% \ctxlua{jobreferences.setinternalreference(nil,nil,\nextinternalreference)}% \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else \xdef\currentregistersynchronize{\ctxlatelua{jobregisters.enhance("\currentregister",\currentregisternumber)}}% \fi \currentregistersynchronize % here? \attribute\destinationattribute\lastdestinationattribute \forcecolorhack % no \strut as it will be removed during cleanup \endgroup} \def\doregister[#1][#2]% {\def\currentregister{#1}% \doifelse{\registerparameter\c!ownnumber}\v!yes\dodoregister\donoregister{#1}{#2}} \def\donoregister #1#2#3{\doflushatpar{\doregisterstructurepageregister{#1}{\c!keys={#2},\c!entries={#3}}{}}} \def\dodoregister#1#2#3#4{\doflushatpar{\doregisterstructurepageregister{#1}{\c!keys={#2},\c!alternative=#3,\c!entries={#4}}{}}} \unexpanded\def\startregister{\doquadrupleempty\dostartregister} \unexpanded\def\stopregister {\dodoubleargument\dostopregister} % a synonym, so that we can nest with overlap without syntax check problems \let\openregisterrange \startregister \let\closeregisterrange\stopregister \def\dostartregister[#1][#2][#3][#4]#5% {\iffourthargument % #1=register #2=tag #3=own #4=sortkey #5=entry \doflushatpar{\doregisterstructurepageregister{#1}{\c!label=#2,\c!alternative=#3,\c!keys={#4},\c!entries={#5}}{}}% \else % #1=register #2=tag #3=sortkey #5=entry \doflushatpar{\doregisterstructurepageregister{#1}{\c!label=#2,\c!keys={#3},\c!entries={#5}}{}}% \fi} \def\dostopregister[#1][#2]% {\normalexpanded{\ctxlatelua{jobregisters.extend("#1","#2")}}} \def\setregisterentry {\dotripleempty\dosetregisterentry} \def\finishregisterentry{\dotripleempty\dofinishregisterentry} % not yet document, not sure if this will stay: \def\dosetregisterentry [#1][#2][#3]{\doflushatpar{\doregisterstructurepageregister{#1}{#2}{#3}}} \def\dofinishregisterentry[#1][#2][#3]{\dofinishregisterstructurepageregister{#1}{#2}{#3}} \def\dofinishregisterstructurepageregister#1#2#3% register data userdata {\begingroup \edef\currentregister{#1}% \getparameters[\??id][\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% \edef\currentregisterlabel {\registerparameter\c!label}% \edef\currentregisterexpansion{\registerparameter\c!expansion}% \edef\currentregisterownnumber{\registerparameter\c!ownnumber}% \xdef\currentregisterkeys {\registerparameter\c!keys}% \ifx\currentregisterexpansion\s!xml \xmlstartraw \xdef\currentregisterentries{\registerparameter\c!entries}% \xmlstopraw \globallet\currentregistercoding\s!xml \else \ifx\currentregisterexpansion\v!yes \xdef\currentregisterentries{\registerparameter\c!entries}% \else \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% \fi \globallet\currentregistercoding\s!tex \fi \ifx\currentregisterentries\empty \normalexpanded{\ctxlua{jobregisters.extend("\currentregister","\currentregisterlabel", { metadata = { \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi }, userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) })% }}% \else \normalexpanded{\ctxlua{jobregisters.extend("\currentregister","\currentregisterlabel", { metadata = { catcodes = \the\catcodetable, coding = "\currentregistercoding", \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi }, entries = { % we need a special one for xml, this is just a single one \!!bs\currentregisterentries\!!es, \!!bs\currentregisterkeys\!!es }, userdata = structure.helpers.touserdata(\!!bs\detokenize{#3}\!!es) }) }}% \fi \endgroup} % The following variants are meant for (for instance xml). There is some % overlap with previously defined macros. % % \starttext % \setstructurepageregister[index][entries=alpha]a % \setstructurepageregister[index][entries=gamma]g % \setstructurepageregister[index][entries=beta]b % \setstructurepageregister[index][entries:1=alpha,keys:1=z]a % \setstructurepageregister[index][entries:1=gamma,keys:1=x]g % \setstructurepageregister[index][entries:1=beta, keys:1=y]b % \index{alpha}a % \index{gamma}g % \index{beta}b % \placeregister[index][n=1] % \stoptext \def\setstructurepageregister{\dotripleempty\dosetstructurepageregister} \def\dosetstructurepageregister[#1][#2][#3]% [register][settings][userdata] {\doflushatpar{\doregisterstructurepageregister{#1}{#2}{#3}}} \unexpanded\def\startstructurepageregister{\doquadrupleempty\dostartstructurepageregister} \unexpanded\def\stopstructurepageregister {\dodoubleargument\dostopstructurepageregister} \let\openstructurepageregisterrange \startstructurepageregister \let\closestructurepageregisterrange\stopstructurepageregister \def\dostartstructurepageregister[#1][#2][#3][#4]% [register][tag][settings][userdata] {\doflushatpar{\doregisterstructurepageregister{#1}{\c!label=#2,#3}{#4}}} \def\dostopstructurepageregister[#1][#2]% {\normalexpanded{\ctxlatelua{jobregisters.extend("#1","#2")}}} % So far. \def\doseeregister[#1][#2]#3#4% {\doflushatpar{\doprocessseeregister{#1}{#2}{#3}{#4}}} \def\doprocessseeregister#1#2#3#4% register key entry seeword {\begingroup \edef\currentregister{#1}% \edef\currentregisterexpansion{\registerparameter\c!expansion}% \ifx\currentregisterexpansion\s!xml \xmlstartraw \xdef\currentregisterentries{\detokenize{#3}}% not ok yet \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet \xmlstopraw \globallet\currentregistercoding\s!xml \else \ifx\currentregisterexpansion\v!yes \xdef\currentregisterentries{#3}% not ok yet \xdef\currentregisterseeword{#4}% not ok yet \else \xdef\currentregisterentries{\detokenize{#3}}% not ok yet \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet \fi \globallet\currentregistercoding\s!tex \fi \setnextinternalreference % we could consider storing register entries in list \edef\temp{\ctxlua{ jobregisters.store { metadata = { kind = "see", name = "\currentregister", level = structure.sections.currentlevel(), catcodes = \the\catcodetable, }, references = { internal = \nextinternalreference, section = structure.sections.currentid(), }, entries = { % we need a special one for xml, this is just a single one "\currentregisterentries", "#2" }, seeword = { text = "\currentregisterseeword" }, } }}% \endgroup} %D Rendering: \let\utilityregisterlength\!!zerocount \def\determineregistercharacteristics {\dodoubleempty\dodetermineregistercharacteristics} \def\dodetermineregistercharacteristics[#1][#2]% {\begingroup \edef\currentregister{#1}% \setupregister[\currentregister][#2]% \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxlua{jobregisters.analyse('\currentregister',{ language = "\registerparameter\s!language", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", })}}}% brrr \ifcase\utilityregisterlength\relax \resetsystemmode\v!register \else \setsystemmode \v!register \fi} \newtoks\everyplaceregister \appendtoks \dontcomplain \to \everyplaceregister \unexpanded\def\placeregister {\dodoubleempty\doplaceregister} \def\doplaceregister[#1][#2]% {\iffirstargument \begingroup % \forgetall \edef\currentregister{#1}% \setupregister[\currentregister][#2]% \the\everyplaceregister \startcolumns [\c!n=\registerparameter\c!n, \c!balance=\registerparameter\c!balance, \c!align=\registerparameter\c!align, \c!tolerance=\registerparameter\c!tolerance]% \startpacked[\v!blank]% \ctxlua{jobregisters.process('\currentregister',{ language = "\registerparameter\s!language", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", }, { % prefix = "\registerparameter\c!pageprefix", separatorset = "\registerparameter\c!pageprefixseparatorset", conversionset = "\registerparameter\c!pageprefixconversionset", starter = \!!bs\registerparameter\c!pageprefixstarter\!!es, stopper = \!!bs\registerparameter\c!pageprefixstopper\!!es, set = "\registerparameter\c!pageprefixset", segments = "\registerparameter\c!pageprefixsegments", connector = \!!bs\registerparameter\c!pageprefixconnector\!!es, }, { prefix = "\registerparameter\c!pageprefix", separatorset = "\registerparameter\c!pageseparatorset", conversionset = "\registerparameter\c!pageconversionset", starter = \!!bs\registerparameter\c!pagestarter\!!es, stopper = \!!bs\registerparameter\c!pagestopper\!!es, segments = "\registerparameter\c!pagesegments", } )}% \stoppacked \stopcolumns \endgroup \fi} \def\dolimitedregisterentry#1{\limitatetext{#1}\currentregistermaxwidth\unknown}% \appendtoks \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}% \ifx\currentregistermaxwidth\empty \let\limitedregisterentry\firstofoneargument \else \let\limitedregisterentry\dolimitedregisterentry \fi \to \everyplaceregister \def\completeregister {\dodoubleempty\docompleteregister} \def\docompleteregister[#1][#2]% {\iffirstargument \begingroup \edef\currentregister{#1}% % the expansion is needed because we don't want \v!'s in the tuo file (french) \normalexpanded{\systemsuppliedchapter[\currentregister]{\noexpand\headtext{\currentregister}}}% \placeregister[\currentregister][#2]% \page[\v!yes]% \endgroup \fi} % test case for collapsing (experimental, for Steffen Wolfrum) % % \starttext % \placeregister[index][compress=no] \blank[2*big] % \placeregister[index][compress=yes] \blank[2*big] % \placeregister[index][compress=all] \page % \dorecurse{10}{test 1:!\index{test} test \page} % \dorecurse{5} {test 2:\recurselevel \page} % \dorecurse{10}{test 3:!\index{test} test \page} % \dorecurse{5} {test 4:\recurselevel \page} % \dorecurse{1} {test 5:!\index{test} test \page} % \dorecurse{5} {test 6:\recurselevel \page} % \dorecurse{10}{test 7:!\index{test} test \page} % \dorecurse{5} {test 8:\recurselevel \page} % oeps \index{oeps} % xxxx \index{xxxx} % todo \index{todo} % \stoptext %D Character rendering (sections): \def\defaultregistercharacter#1% {\doifsomething{#1} {\doifnot{#1}\s!unknown {\doifelse{\registerparameter\c!indicator}\v!yes {\expandcheckedcsname{\??id:\c!indicator:}{\registerparameter\c!alternative}{a}{#1}} {\noregistercharacter{#1}}}}} \def\noregistercharacter#1% {\registerparameter\c!before \goodbreak} % a = \setvalue{\??id:\c!indicator:a}#1% {\registerparameter\c!before % bugged, why does leftskip gets set: \vskip\lineheight\goodbreak\vskip-\lineheight \begingroup\dosetregisterattributes\c!style\c!color \registerparameter\c!command{\strut#1}% \endgroup \registerparameter\c!after \par\nobreak} % b = \setvalue{\??id:\c!indicator:b}#1% {\registerparameter\c!before \begingroup\dosetregisterattributes\c!style\c!color \registerparameter\c!command{\strut#1}% \endgroup \registerparameter\c!after \nobreak} \setvalue{\??id:\c!indicator:A}#1{\getvalue{\??id:\c!indicator:a}{\WORD{#1}}} \setvalue{\??id:\c!indicator:B}#1{\getvalue{\??id:\c!indicator:b}{\WORD{#1}}} %D The following macros are the interface to the rendering. These are %D generated by \LUA. This might change. %D Beware, we get funny side effects when a dangling \index precedes an %D placeindex as then flushing takes place inside the index. Took me hours %D to notice that. \unexpanded\def\startregisteroutput {\endgraf \begingroup \forgetparindent \forgetparskip} \unexpanded\def\stopregisteroutput {\endgraf \endgroup} \unexpanded\def\startregisterentries#1% depth {\endgraf \begingroup \dosetregisterattributes\c!textstyle\c!textcolor \advance\leftskip\numexpr#1-1\relax\dimexpr\registerparameter\c!distance\relax \hangindent\registerparameter\c!distance\hangafter\plusone} \unexpanded\def\stopregisterentries {\endgraf \endgroup} \unexpanded\def\startregistersection#1% title {\registercharacter{#1}\endgraf} \unexpanded\def\stopregistersection {\endgraf} \newconditional\registerpagedone \unexpanded\def\startregisterpages {\begingroup \setfalse\registerpagedone \dosetregisterattributes\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterpages {\endgroup} \unexpanded\def\startregisterseewords {\begingroup \setfalse\registerpagedone \dosetregisterattributes\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterseewords {\endgroup} \def\registerpageseparator% todo: , configurable {\ifconditional\registerpagedone \registerpageseparatorsymbol \else \hskip\registerparameter\c!distance\relax \settrue\registerpagedone \fi} \def\registeronepagerangeseparator{|\endash|} \def\withregisterpagecommand#1#2#3% {\def\currentregisterpageindex{#1}% \iflocation \goto{\registerparameter\c!pagecommand{#3}}[internal(#1)]% \else \registerparameter\c!pagecommand{#3}% \fi} \def\registeronepage#1#2#3% content {\registerpageseparator \withregisterpagecommand{#1}{#2}{#3}} \def\registerpagerange#1#2#3#4#5#6% content, content todo: -- configurable {\registerpageseparator \withregisterpagecommand{#1}{#2}{#3}% \registeronepagerangeseparator \withregisterpagecommand{#4}{#5}{#6}} \def\registeroneword#1#2#3% content {\registerpageseparator \registerseeword{#3}} \def\defaultregisterentry #1{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#1}}}} \def\defaultregisterseeword#1{\labeltexts\v!see{#1}} \let\registerseeword \defaultregisterseeword \let\registerentry \defaultregisterentry \let\registercharacter\defaultregistercharacter %D A few specific rendering variants: % \def\doregisterpagelocation#1#2% % {\nextregisterpage % \hbox to 1em{\hss\doregisterpagehowto{#1}{#2}\hss}} % todo: \installregisterpagehandler % \def\MyRegisterPageCommand#1% % {#1\currentregisterpageuserdata{whatever}} % % \starttext % \setregisterentry[index][entries=aaa][whatever=f.] test \index{bbb} test % \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand] % \stoptext \def\registerpageuserdata #1#2{\ctxlua{jobregisters.userdata(#1,"#2")}} \def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1} % not yet ok : new internal handler names \def\registerpagebuttonsymbol{\vrule\!!width1em\!!height1ex\!!depth\zeropoint\relax} \setvalue{\??id:\c!symbol:\c!n}% {\def\registerpageseparatorsymbol{, }} \setvalue{\??id:\c!symbol:\c!a}% {\def\registerpageseparatorsymbol{, }} % now done via conversion \setvalue{\??id:\c!symbol:\v!none}% {\let\registerpageseparatorsymbol\empty \let\registeronepage \gobblethreearguments \let\registerpagerange \gobblesixarguments} \setvalue{\??id:\c!symbol:1}% {\let\registerpageseparatorsymbol\space \def\registeronepage {\symbol[1]\gobblethreearguments}% \def\registerpagerange {\symbol[1]\gobblesixarguments}} \setvalue{\??id:\c!symbol:2}% {\let\registerpageseparatorsymbol\space \def\registeronepage {\registerpagebuttonsymbol\gobblethreearguments}% \def\registerpagerange {\registerpagebuttonsymbol\gobblesixarguments}} \def\setregisterpagerendering {\edef\currentregisterpagesymbol{\registerparameter\c!symbol}% \ifx\currentregisterpagesymbol\empty \csname\??id:\c!symbol:\c!n\endcsname \else\ifcsname\??id:\c!symbol:\currentregisterpagesymbol\endcsname \csname\??id:\c!symbol:\currentregisterpagesymbol\endcsname \else \let\registerpageseparatorsymbol\space \def\registeronepage {\registerparameter\c!symbol\gobblethreearguments}% \def\registerpagerange {\registerparameter\c!symbol\gobblesixarguments}% \fi\fi} \appendtoks \setregisterpagerendering \to \everyplaceregister % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %D The following code will be reimplemented (not that hard) when it's needed %D again and/or when I'm bored. % \def\getalllistreferences#1#2% % {\gdefconvertexpanded\currentregisterentry{\getvalue{\??id#1\c!expansion}}{#2}% % \doifdefinedelse{\??id#1\??id\currentregisterentry} % {\edef\alllistreferences% % {\getvalue{\??id#1\??id\currentregisterentry}}% % \beforesplitstring\alllistreferences\at::\to\internallistreference % \aftersplitstring \alllistreferences\at::\to\alllistreferences} % {\let\alllistreferences\empty % \def\internallistreference{0}}} % \def\dosetlinkregister#1% is die page reference echt nodig? % {\setregisterpage{#1}% % \global\let\currentregisterentry\empty % \global\firstsubentrytrue % not needed % \global\firstsubsubentrytrue % not needed too % \setvalue{#1\s!entrya}##1{\dosetlinkregisterentrya{#1}{##1}}% % \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}} % \def\dosetlinkregisterentrya#1#2% % {\global\utilitydonetrue % \c!entryletter % \iflocation % \getalllistreferences{#1}{#2}% % % no \endgraf % \hangindent1em\noindent\c!entryreference % % % %\thisissomeinternal{\s!lin}{\internallistreference}% % % % \pagereference[-:\s!lin:\internallistreference]% -: added % % % \getcommacommandsize[\alllistreferences]% % \getfromcommacommand[\alllistreferences][1]% % \ifnum\commalistsize=1 % \let\firstlistreference\empty % \let\midlistreference\commalistelement % \let\lastlistreference\empty % \else % \let\firstlistreference\commalistelement % \getfromcommacommand[\alllistreferences][\commalistsize]% % \let\lastlistreference\commalistelement % \ifnum\commalistsize=2 % \let\midlistreference\empty % \else % \!!counta\commalistsize % \divide\!!counta 2 % \getfromcommacommand[\alllistreferences][\!!counta]% % \let\midlistreference\commalistelement % \fi % \fi % % aangepast % \def\dodocommand[##1-##2]% % {\gotonextinternal{\s!ind}{##1}{##2}{\box0}}% % \doifelsevalue{\??id#1\c!interaction}\v!pagenumber % {\limitedregisterentry{#1}{#2}} % paginanummer % {{\setbox0\hbox{\limitedregisterentry{#1}{\begstrut#2}}% % \ifx\firstlistreference\empty % tekst,alles % \ifx\midlistreference\empty % \box0 % \else % \expandafter\dodocommand\expandafter[\midlistreference]% % \fi % \else % \expandafter\dodocommand\expandafter[\firstlistreference]% % \fi}}% % \doifvalue{\??id#1\c!number}\v!yes % {\hskip\getvalue{\??id#1\c!distance}(\commalistsize)}% % \doifnotvalue{\??id#1\c!interaction}\v!text % paginanummer,alles % {\def\docommand##1##2% % {{\setbox0\hbox{\showlocation{\hbox to 1em{\hss\symbol[##2]\hss}}}% % \ifx##1\empty % % \hskip\wd0 % (optioneel maken) % \else % \expandafter\dodocommand\expandafter[##1]% % \fi}}% % \hskip\getvalue{\??id#1\c!distance}% % \docommand\firstlistreference\v!previous % \docommand\midlistreference\v!somewhere % \docommand\lastlistreference\v!next}% % % tot hier % \else % % no \endgraf % \noindent\c!entryreference % \limitedregisterentry{#1}{#2}% % \fi % \endgraf} % \def\dosetregister#1% % {\doifelsevalue{\??id#1\c!coupling}\v!yes % {\ifautoregisterhack % \dosetautoregister{#1}% % \else % \dosetlinkregister{#1}% % \fi} % {\dosetpageregister{#1}}} % \def\dosetregister#1% % {\dosetpageregister{#1}} % \newcounter\internallistreference % \def\doloadregisterlinks#1% % {\setregisterpage{#1}% % \global\let\currentregisterentry\empty % \global\firstregisterpagetrue % \setvalue{#1\s!entrya}##1% % {\global\firstregisterpagetrue % \gdefconvertedargument\currentregisterentry{##1}% global nodig? % \doglobal\increment\internallistreference}% % \setvalue{#1\s!from}% % {\getvalue{#1\s!page}}% % \ifautoregisterhack % \setvalue{#1\s!page}##1##2##3##4% % {\doifreglevelelse[##3] % {\global\utilitydonetrue % \iffirstregisterpage % \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname % {\internallistreference::##4}% % \else % catches errors in index % \ifcsname\??id#1\??id\currentregisterentry\endcsname % \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname % {\csname\??id#1\??id\currentregisterentry\endcsname,##4}% % \fi % \fi} % {}}% % \else % \setvalue{#1\s!page}##1##2##3##4% % {\doifreglevelelse[##3] % {\global\utilitydonetrue % \iffirstregisterpage % \global\firstregisterpagefalse % \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname % {\internallistreference::##2-##4}% % \else % catches errors in index % \ifcsname\??id#1\??id\currentregisterentry\endcsname % \@EA\xdef\csname\??id#1\??id\currentregisterentry\endcsname % {\csname\??id#1\??id\currentregisterentry\endcsname,##2-##4}% % \fi % \fi} % {}}% % \fi} % \def\docoupleregister[#1][#2]% % {\iflocation % \ifcase0\countervalue{autolink:#1}\relax % only once % \begingroup % \let\dosetregister\doloadregisterlinks % \def\currentregister{#1}% % \setupregister[#1][#2]% % \mkloadregister\currentregister\dobeforeplaceregister\doafterplaceregister % \endgroup % \ifautoregisterhack % \doinitializeautoregister{#1}% % \else % \doinitializelinkregister{#1}% % \fi % \fi % \fi} % \def\coupleregister % {\dodoubleempty\docoupleregister} % \def\dodocommandprolinrefAA[#1-#2]% % {\def\lastlistreference{#1-#2}} % \def\dodocommandprolinrefA[#1-#2]% % {\def\lastlistreference{#1-#2}% % \ifx\firstlistreference\empty % \let\firstlistreference\lastlistreference % \fi % \ifnum#1<\nextinternalreference\relax % \let\prevlistreference\lastlistreference % \else\ifnum#1>\nextinternalreference\relax % \let\nextlistreference\lastlistreference % \let\dodocommandprolinrefA\dodocommandprolinrefAA % \else % \let\selflistreference\lastlistreference % \fi\fi} % \def\docommandprolinrefA#1% % {\dodocommandprolinrefA[#1]} % \def\dodocommandprolinrefB[#1-#2]% % {\gotonextinternal{\s!ind}{#1}{#2}{\box0}} % \def\docommandprolinrefB#1#2#3% % {\bgroup % \ifx#2\empty % \doifvalue{\??id#1\c!unknownreference}\v!empty{\hskip1em}% % \else % \setbox0\hbox to 1em{\hss\showlocation{\symbol[#3]}\hss}% % \expandafter\dodocommandprolinrefB\expandafter[#2]% % \fi % \egroup} % \def\doprocesslinkregister[#1][#2]#3% % {\hbox % {\doprocesspageregister{}{#2}{}{#3}% % \let\firstlistreference\empty % \let\lastlistreference\empty % \let\selflistreference\empty % \let\prevlistreference\empty % \let\nextlistreference\empty % \getalllistreferences{#1}{#3}% % \ifx\alllistreferences\empty \else % \normalexpanded{\noexpand\rawprocesscommalist[\alllistreferences]}\docommandprolinrefA % \fi % \ifx\prevlistreference\empty % \let\prevlistreference\lastlistreference % \fi % \ifx\nextlistreference\empty % \let\nextlistreference\firstlistreference % \fi % \ifx\prevlistreference\selflistreference % \let\prevlistreference\empty % \let\nextlistreference\empty % \fi % \setalignmentswitch{\getvalue{\??id#1\c!location}}% % \ifcase\alignmentswitch % % links % \docommandprolinrefB{#1}\prevlistreference\v!previous % \docommandprolinrefB{#1}\nextlistreference\v!next % \or % % midden % \docommandprolinrefB{#1}\prevlistreference\v!previous % \or % % rechts % \fi % \doifreferencefoundelse{\s!lin:\internallistreference} % {\gotosomeinternal % \s!lin \internallistreference \currentrealreference % {\showlocation{\limitedregisterentry{#1}{#3}}}} % {\hbox{\limitedregisterentry{#1}{#3}}}% % \ifcase\alignmentswitch % % links % \or % % midden % \docommandprolinrefB{#1}\nextlistreference\v!next % \or % % rechts % \docommandprolinrefB{#1}\prevlistreference\v!previous % \docommandprolinrefB{#1}\nextlistreference\v!next % \fi}} % \def\doprocesslinkedregister[#1][#2]#3% page auto link % {\bgroup % \chardef\registerpagestatus\plusone % \def\currentregister{#1}% % \iflocation % \next is not needed % \ifautoregisterhack % \def\next{\doprocessautoregister[#1][#2]}% % \else % \def\next{\doprocesslinkregister[#1][#2]}% % \fi % \else % \def\next{\doprocesspageregister{}{#2}{}}% % \fi % \next{#3}% % \egroup} % \def\dodolinkedregister[#1][#2]#3% page auto link % {\doflushatpar{\doprocesslinkedregister[#1][#2]{#3}}} % \def\dolinkedregister#1% % {\dodoubleempty\dodolinkedregister[#1]} % \def\dosetautoregister#1% % {\makecounter{autolink:#1}% % \setregisterpage{#1}% % \global\let\currentregisterentry\empty % \global\firstsubentrytrue % not needed % \global\firstsubsubentrytrue % not needed too % \setvalue{#1\s!entrya}##1{\dosetautoregisterentrya{#1}{##1}}% % \setvalue{#1\s!entry }##1{\dosetpageregisterletter{#1}{##1}}} % \def\dosetautoregisterentrya#1#2% % {\global\utilitydonetrue % \c!entryletter % \iflocation % \getalllistreferences{#1}{#2}% % \endgraf\hangindent1em\noindent\c!entryreference % \pagereference[-:\s!lin:\internallistreference]% % \pluscounter{autolink:#1}% % \bgroup % %\setupinteraction[\c!color=,\c!contrastcolor=,\c!style=]% kan sneller % \resetinteractionparameter\c!color % \resetinteractionparameter\c!contrastcolor % \resetinteractionparameter\c!style % \gotobox % {\limitedregisterentry{#1}{\begstrut#2}}% % [JS(SetRegisterEntry{\v!register,\countervalue{autolink:#1},#2,{\alllistreferences}})]% % \egroup % \else % \endgraf\noindent\c!entryreference % \limitedregisterentry{#1}{#2}% % \fi} % \def\doprocessautoregister[#1][#2]#3% % {\hbox % {\doprocesspageregister{}{#2}{}{#3}% % \doifreferencefoundelse{\s!lin:\internallistreference} % {\gotosomeinternal \s!lin % {\internallistreference}{\currentrealreference} % {\showlocation{\limitedregisterentry{#1}{#3}}}} % {\hbox{\limitedregisterentry{#1}{#3}}}}} % \appendmacro aan openpaginaactie (in shipout) %D The first implementation used one main field with clones. %D In a 2500 page document this resulted in a rather (anoying) %D long start||up time. This \quote {every page its own field} %D solution, combined with a \quote {page open action}, works %D much faster, but is conceptually pretty weak. % \def\complexregisterfield[#1]% % {\definefield[#1:\realfolio][line][\v!register]% % \field[#1:\realfolio]} % \def\simpleregisterfield % {\complexregisterfield[\v!register]} % \definecomplexorsimple\registerfield % \appendtoks % % for now % \setupfield % [\v!register] % [\c!width=10em, % \c!height=3ex, % \c!align=\v!middle, % \c!option=\v!readonly, % \c!location=\v!low] % \to \everydump % \def\doinitializeautoregister#1% % {\useJSscripts[reg]% % \useJSpreamblenow{LinkedRegisters}% % \setupinteraction[\c!openpageaction=JS(UpdateRegisterField{\v!register})]% % \definereference[\v!reset\v!register][JS(ResetRegisterEntry{\v!register})]% % \definereference[\v!first\v!register][JS(GotoFirstRegisterEntry{\v!register})]% % \definereference[\v!previous\v!register][JS(GotoPreviousRegisterEntry{\v!register})]% % \definereference[\v!next\v!register][JS(GotoNextRegisterEntry{\v!register})]% % \definereference[\v!last\v!register][JS(GotoLastRegisterEntry{\v!register})]} % \def\doinitializelinkregister#1% % {} % todo ruwe register %D Default index: \defineregister [\v!index] [\v!indices] % \setupregister[index][koppeling=ja] % % \stelveldenin % [register][achtergrond=raster,kader=uit] % % \stelvoettekstenin % [{\field[index]}] % % \stelhoofdtekstenin % [{\naar {first}[eersteindex]\quad % \naar{previous}[vorigeindex]\quad % \naar {next}[volgendeindex]\quad % \naar {last}[laatsteindex]\quad\quad % \naar {index}[index]}] % % \starttekst % % oeps~~~\gekoppeldeindex{oeps} \blanko % flop~~~\gekoppeldeindex{flop} \blanko % test~~~\gekoppeldeindex{test} \pagina % flop~~~\gekoppeldeindex{flop} \blanko % test~~~\gekoppeldeindex{test} \pagina % oeps~~~\gekoppeldeindex{oeps} \blanko % test~~~\gekoppeldeindex{test} \pagina % flop~~~\gekoppeldeindex{flop} \blanko % oeps~~~\gekoppeldeindex{oeps} \pagina % % \volledigeindex \protect \endinput