%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 % 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!pagenumber=\v!yes, \c!pageprefixconnector=\endash, \c!pagesegments=2:2, \c!file=\jobname, %\c!deeptextcommand=, % undefined by default ! \c!method=, % no default as we have them in the module, maybe some day in lang-* \c!numberorder=\v!numbers, % \v!characters \s!language=\currentmainlanguage]% %D Definition: \unexpanded\def\defineregister {\dodoubleargument\dodefineregister} \def\dodefineregister[#1][#2]% #2? {\setupregister[#1][\s!parent=\??id]% \ctxlua{structures.registers.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{ structures.registers.store { % 'own' should not be in metadata metadata = { kind = "entry", name = "\currentregister", level = structures.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 = structures.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 = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) } } }% \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}% \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else \xdef\currentregistersynchronize{\ctxlatelua{structures.registers.enhance("\currentregister",\currentregisternumber)}}% \fi \currentregistersynchronize % here? % needs thinking ... bla\index{bla}. will break before the . but adding a % penalty is also no solution \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{structures.registers.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 % I hate this kind of mess ... but it's a user request. \ifx\currentregisterentries\empty \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", { metadata = { \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi }, userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) })% }}% \else \normalexpanded{\ctxlua{structures.registers.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 = structures.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{structures.registers.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{ structures.registers.store { metadata = { kind = "see", name = "\currentregister", level = structures.sections.currentlevel(), catcodes = \the\catcodetable, }, references = { internal = \nextinternalreference, section = structures.sections.currentid(), }, entries = { % we need a special one for xml, this is just a single one "\currentregisterentries", "#2" }, seeword = { text = "\currentregisterseeword" }, } }}% \endgroup} %D Rendering: % todo: c!language ipv s!language \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{structures.registers.analyze('\currentregister',{ language = "\registerparameter\s!language", method = "\registerparameter\c!method", numberorder = "\registerparameter\c!numberorder", 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{structures.registers.process('\currentregister',{ language = "\registerparameter\s!language", method = "\registerparameter\c!method", numberorder = "\registerparameter\c!numberorder", 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 {\doregistercharacter{#1}} {\noregistercharacter{#1}}}}} % \def\doregistercharacter#1% % {\expandcheckedcsname % why no \executeifdefined % {\??id:\c!indicator:}% % {\registerparameter\c!alternative}% % {a}% % {#1}} \def\doregistercharacter#1% {\expandcheckedcsname % why no \executeifdefined {\??id:\c!indicator:}% {\registerparameter\c!alternative}% {a}% {#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 \dontleavehmode \strut \iflocation \pagereference[\currentregister:\v!section:#1]% \fi \registerparameter\c!command{#1}% \endgroup \registerparameter\c!after \par \nobreak} % b = \setvalue{\??id:\c!indicator:b}#1% will be shared with a {\registerparameter\c!before \begingroup \dosetregisterattributes\c!style\c!color \dontleavehmode \strut \iflocation \pagereference[\currentregister:\v!section:#1]% \fi \registerparameter\c!command{#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 \dostarttagged\t!register\currentregister \forgetparindent \forgetparskip} \unexpanded\def\stopregisteroutput {\endgraf \dostoptagged \endgroup} \unexpanded\def\startregisterentries#1% depth {\endgraf \begingroup \dostarttagged\t!registerentries\empty \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 \dostoptagged \endgroup} \unexpanded\def\startregistersection#1% title {\dostarttagged\t!registersection\empty \dostarttagged\t!registertag\empty \registercharacter{#1}\endgraf \dostoptagged} \unexpanded\def\stopregistersection {\dostoptagged \endgraf} \newconditional\registerpagedone \unexpanded\def\startregisterpages {\begingroup \dostarttagged\t!registerpages\empty \setfalse\registerpagedone \dosetregisterattributes\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterpages {\dostoptagged \endgroup} \unexpanded\def\startregisterseewords {\ifhmode\crlf\fi \begingroup \setfalse\registerpagedone \dostarttagged\t!registerpage\empty \dosetregisterattributes\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterseewords {\dostoptagged \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#4% {\def\currentregisterpageindex{#2}% \iflocation \goto{\registerparameter\c!pagecommand{#4}}[internal(#2)]% \else \registerparameter\c!pagecommand{#4}% \fi} \def\registeronepage#1#2#3#4% #1:processor content {\registerpageseparator \dostarttagged\t!registerpage\empty \withregisterpagecommand{#1}{#2}{#3}{#4}% \dostoptagged} \def\registerpagerange#1#2#3#4#5#6#7% #1:processor content, content todo: -- configurable {\registerpageseparator \dostarttagged\t!registerpagerange\empty \dostarttagged\t!registerfrompage\empty \withregisterpagecommand{#1}{#2}{#3}{#4}% \dostoptagged \registeronepagerangeseparator \dostarttagged\t!registertopage\empty \withregisterpagecommand{#1}{#5}{#6}{#7}% \dostoptagged \dostoptagged} \def\doapplyregisterentrycommand#1#2% processor text {\dostarttagged\t!registerentry\empty \ifx\currentregisterseeindex\empty \else \dontleavehmode \pagereference[seeindex:\currentregisterseeindex]% maybe some day we will support an area \fi \applyprocessor{#1}{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#2}}}}% \dostoptagged} \def\defaultregisterentry#1#2#3#4% #1:processor #2:internal #3:seeindex #4:word {\def\currentregisterpageindex{#2}% \iflocation \def\currentregisterseeindex{#3}% \doifelse{\registerparameter\c!interaction}\v!text {\directgoto{\setlocationcolor\??ia\doapplyregisterentrycommand{#1}{#4}}[internal(#2)]} {\doapplyregisterentrycommand{#1}{#4}}% \else \let\currentregisterseeindex\empty \doapplyregisterentrycommand{#1}{#4}% \fi} \unexpanded\def\doapplyregisterseecommand#1#2% {\ifx\currentregisterseeindex\empty % \dontleavehmode \applyprocessor{#1}{#2}% \else \goto{\applyprocessor{#1}{#2}}[seeindex:\currentregisterseeindex]% \fi} \def\defaultregisterseeword#1#2#3#4#5#6% i n #3:processor #4:internal #5:seeindex #6:word {%\registerpageseparator \def\currentregisterpageindex{#4}% \dostarttagged\t!registersee\empty \settrue\registerpagedone \iflocation \def\currentregisterseeindex{#5}% \else \let\currentregisterseeindex\empty \fi \ifnum#1=\plusone \labeltexts\v!see{\doapplyregisterseecommand{#3}{#6}}% \else\ifnum#1=#2\relax \labeltexts\v!and{\doapplyregisterseecommand{#3}{#6}}% \else ,\space\doapplyregisterseecommand{#3}{#6}% \fi\fi \dostoptagged} \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{structures.registers.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 \gobblefourarguments \let\registerpagerange \gobblesevenarguments} \setvalue{\??id:\c!symbol:1}% {\let\registerpageseparatorsymbol\space \def\registeronepage {\symbol[1]\gobblefourarguments}% \def\registerpagerange {\symbol[1]\gobblesevenarguments}} \setvalue{\??id:\c!symbol:2}% {\let\registerpageseparatorsymbol\space \def\registeronepage {\registerpagebuttonsymbol\gobblefourarguments}% \def\registerpagerange {\registerpagebuttonsymbol\gobblesevenarguments}} \def\setregisterpagerendering {\doifelse{\registerparameter\c!pagenumber}\v!no {\let \currentregisterpagesymbol\v!none} {\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\gobblefourarguments}% \def\registerpagerange {\registerparameter\c!symbol\gobblesevenarguments}% \fi\fi} \appendtoks \setregisterpagerendering \to \everyplaceregister %D The linked register code will be reimplemented (not that hard) when it's needed %D again and/or when I'm bored. %D Default index: \defineregister [\v!index] [\v!indices] \protect \endinput