%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 \& \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. \writestatus{loading}{ConTeXt Structure Macros / Registers} \registerctxluafile{strc-reg}{1.001} \unprotect \startcontextdefinitioncode % todo: tag:: becomes rendering % todo: language, character, linked, location % todo: fonts etc at sublevels (already defined) % \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 % \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} % tzt variant with n entries, parameters and userdata (altnum) \installcorenamespace{register} \installcommandhandler\??register {register} \??register \let\strc_registers_setup_saved\setupregister \unexpanded\def\setupregister % maybe we should drop the plural form {\dotripleempty\strc_registers_setup} \def\strc_registers_setup[#1][#2][#3]% {\ifthirdargument \def\strc_registers_setup_step##1{\strc_registers_setup_saved[#1:##1][#3]}% \processcommalist[#2]\strc_registers_setup_step \else\ifsecondargument \strc_registers_setup_saved[#1][#2]% \else \strc_registers_setup_saved[#1]% \fi\fi} \unexpanded\def\setupregisters {\dosingleempty\strc_registers_setup_root} \def\strc_registers_setup_root[#1]% {\strc_registers_setup_saved[#1]\relax} \setupregister [\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=\emwidth, \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]% % yes or no shared ? \setupregister [\c!label=, \c!entries=, \c!alternative=] \definemixedcolumns [\v!register] [\c!n=\registerparameter\c!n, \c!balance=\registerparameter\c!balance, \c!align=\registerparameter\c!align, \c!tolerance=\registerparameter\c!tolerance] %D \starttyping %D \setupregister[index][1][textcolor=darkred] %D \setupregister[index][2][textcolor=darkgreen,textstyle=bold] %D %D \placeregister[index][n=1] \blank[3*big] %D %D test \index{test+one} test \index{test+two} more \index{more} %D \stoptyping \newconditional\c_strc_registers_defining \setnewconstant\c_strc_registers_maxlevel \plusfive \ifdefined\Word \else \unexpanded\def\Word#1{#1} \fi \appendtoks \ifconditional\c_strc_registers_defining \else % todo: dosingle ... \settrue\c_strc_registers_defining \definemixedcolumns[\currentregister][\v!register]% first as otherwise it overloads start/stop \ctxcommand{defineregister("\currentregister","\registerparameter\c!referencemethod")}% \normalexpanded{\presetheadtext[\currentregister=\Word{\currentregister}]}% \setuevalue{\currentregister}{\dodoubleempty\strc_registers_insert_entry[\currentregister]}% \setuevalue{\e!see\currentregister}{\dodoubleempty\strc_registers_insert_see[\currentregister]}% %setuevalue{\e!coupled\currentregister}{\dolinkedregister{\currentregister}}% % historic ballast \setuevalue{\e!place\currentregister}{\placeregister[\currentregister]}% \setuevalue{\e!complete\currentregister}{\completeregister[\currentregister]}% \setuevalue{\e!setup\currentregister\e!endsetup}{\setupregister[\currentregister]}% \dorecurse\c_strc_registers_maxlevel{% weird, expanded should not be needed \normalexpanded{\defineregister[\currentregister:\recurselevel][\currentregister]}% %\defineregister[\currentregister:\recurselevel][\currentregister]% \letregisterparameter{\c!entries:\recurselevel}\empty % needed as we use detokenize (ok, we can \letregisterparameter{\c!keys :\recurselevel}\empty % avoid it, but it's faster too) }% % \setfalse\c_strc_registers_defining \fi \to \everydefineregister \appendtoks \ctxcommand{setregistermethod("\currentregister","\registerparameter\c!referencemethod")}% \to \everysetupregister %D Registering: \def\strc_registers_register_page_entry {\iftrialtypesetting \expandafter\gobblethreearguments \else \expandafter\strc_registers_register_page_entry_indeed \fi} \def\strc_registers_register_page_expand_xml_entries {\xmlstartraw \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% \xmlstopraw \globallet\currentregistercoding\s!xml} \def\strc_registers_register_page_expand_yes_entries {\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% \globallet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_nop_entries {\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}% \globallet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_xml {\xmlstartraw \xdef\currentregisterentries{\registerparameter\c!entries}% \xmlstopraw \globallet\currentregistercoding\s!xml} \def\strc_registers_register_page_expand_yes {\xdef\currentregisterentries{\registerparameter\c!entries}% \globallet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_nop {\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% \globallet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_xml_keys {\xmlstartraw \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% \xmlstopraw} \def\strc_registers_register_page_expand_yes_keys {\xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}} \def\strc_registers_register_page_entry_indeed#1#2#3% register data userdata {\begingroup \edef\currentregister{#1}% %\setupcurrentregister[\c!entries=,\c!label=,\c!keys=,\c!alternative=,#2]% \setupcurrentregister[#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 \strc_registers_register_page_expand_xml_entries \else\ifx\currentregisterexpansion\v!yes \strc_registers_register_page_expand_yes_entries \else \strc_registers_register_page_expand_nop_entries \fi\fi \else \ifx\currentregisterexpansion\s!xml \strc_registers_register_page_expand_xml \else\ifx\currentregisterexpansion\v!yes \strc_registers_register_page_expand_yes \else \strc_registers_register_page_expand_nop \fi\fi \fi \ifx\currentregisterkeys\empty \ifx\currentregistercoding\s!xml \strc_registers_register_page_expand_xml_keys \else \strc_registers_register_page_expand_yes_keys \fi \fi \setnextinternalreference % we could consider storing register entries in a list which we % could then sort \xdef\currentregisternumber{\ctxcommand{storeregister{ % '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 \ifx\currentreferencecoding\s!xml xmlroot = "\xmldocument", % only useful when text \fi \ifx\currentregisterxmlsetup\empty \else xmlsetup = "\currentregisterxmlsetup", \fi }, references = { % internal = \nextinternalreference, % section = structures.sections.currentid(), % hm, why then not also lastsection the same way \ifx\currentregisterlabel\empty \else label = "\currentregisterlabel", \fi }, % \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) } }}% % \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% in previous \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\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 \signalcharacter % no \strut as it will be removed during cleanup \endgroup} \unexpanded\def\strc_registers_insert_entry[#1][#2]% {\def\currentregister{#1}% \doifelse{\registerparameter\c!ownnumber}\v!yes \strc_registers_insert_entry_yes \strc_registers_insert_entry_nop {#2}} \def\strc_registers_insert_entry_nop#1#2% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}} \def\strc_registers_insert_entry_yes#1#2#3% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}} \unexpanded\def\startregister{\doquadrupleempty\strc_registers_start_entry} \unexpanded\def\stopregister {\dodoubleargument\strc_registers_stop_entry} % a synonym, so that we can nest with overlap without syntax check problems \let\openregisterrange \startregister \let\closeregisterrange\stopregister \def\strc_registers_start_entry[#1][#2][#3][#4]#5% {\iffourthargument % #1=register #2=tag #3=own #4=sortkey #5=entry \doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,\c!alternative=#3,\c!keys={#4},\c!entries={#5}}{}}% \else % #1=register #2=tag #3=sortkey #5=entry \doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,\c!keys={#3},\c!entries={#5}}{}}% \fi} \def\strc_registers_stop_entry[#1][#2]% {\normalexpanded{\ctxlatecommand{extendregister("#1","#2")}}} \def\setregisterentry {\dotripleempty\strc_registers_set_entry} \def\finishregisterentry{\dotripleempty\strc_registers_finish_entry} % not yet document, not sure if this will stay: \def\strc_registers_set_entry [#1][#2][#3]{\doflushatpar{\strc_registers_register_page_entry{#1}{#2}{#3}}} \def\strc_registers_finish_entry[#1][#2][#3]{\strc_registers_finish_entry_indeed{#1}{#2}{#3}} \def\strc_registers_finish_entry_indeed#1#2#3% register data userdata {\begingroup \edef\currentregister{#1}% \setupcurrentregister[\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{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", { metadata = { \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi }, userdata = \!!bs\detokenize{#3}\!!es })% }}% \else \normalexpanded{\ctxcommand{extendregister("\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 = \!!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 % some overlap with previous \unexpanded\def\setstructurepageregister {\dotripleempty\strc_registers_set} \def\strc_registers_set[#1][#2][#3]% [register][settings][userdata] {\doflushatpar{\strc_registers_register_page_entry{#1}{#2}{#3}}} \unexpanded\def\startstructurepageregister{\doquadrupleempty\strc_registers_start} \unexpanded\def\stopstructurepageregister {\dodoubleargument\strc_registers_stop} \let\openstructurepageregisterrange \startstructurepageregister \let\closestructurepageregisterrange\stopstructurepageregister \def\strc_registers_start[#1][#2][#3][#4]% [register][tag][settings][userdata] {\doflushatpar{\strc_registers_register_page_entry{#1}{\c!label=#2,#3}{#4}}} \def\strc_registers_stop[#1][#2]% {\normalexpanded{\ctxlatelua{structures.registers.extend("#1","#2")}}} % So far. \unexpanded\def\strc_registers_insert_see[#1][#2]#3#4% {\doflushatpar{\strc_registers_insert_see_indeed{#1}{#2}{#3}{#4}}} \def\strc_registers_insert_see_indeed#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{\ctxcommand{storeregister{ 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 \!!bs\currentregisterentries\!!es, \!!bs#2\!!es }, seeword = { text = \!!bs\currentregisterseeword\!!es }, } }}% \endgroup} %D Rendering: % todo: c!language ipv s!language \let\utilityregisterlength\!!zerocount \def\determineregistercharacteristics {\dodoubleempty\strc_registers_determine_characteristics} \def\strc_registers_determine_characteristics[#1][#2]% {\begingroup \edef\currentregister{#1}% \setupregister[\currentregister][#2]% \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxcommand{analyzeregister('\currentregister',{ language = "\registerparameter\s!language", method = "\registerparameter\c!method", numberorder = "\registerparameter\c!numberorder", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", pagenumber = \ifx\registerpageseparatorsymbol\empty false\else true\fi, })}}}% brrr \ifcase\utilityregisterlength\relax \resetsystemmode\v!register \else \setsystemmode \v!register \fi} \newtoks\everyplaceregister \appendtoks \dontcomplain \to \everyplaceregister \unexpanded\def\placeregister {\dodoubleempty\strc_registers_place} % \def\strc_registers_place[#1][#2]% % {\iffirstargument % \begingroup % %\forgetall % \edef\currentregister{#1}% % \setupregister[\currentregister][#2]% % \the\everyplaceregister % \ifnum\registerparameter\c!n>\plusone % \startcolumns % [\c!n=\registerparameter\c!n, % \c!balance=\registerparameter\c!balance, % \c!align=\registerparameter\c!align, % \c!tolerance=\registerparameter\c!tolerance]% % \strc_registers_place_indeed % \stopcolumns % \else % \strc_registers_place_indeed % \fi % \endgroup % \fi} \def\strc_registers_place[#1][#2]% {\iffirstargument \begingroup %\forgetall \edef\currentregister{#1}% \setupregister[\currentregister][#2]% \the\everyplaceregister \ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone \startmixedcolumns[\currentregister] \strc_registers_place_indeed \stopmixedcolumns \else \strc_registers_place_indeed \fi \endgroup \fi} % \def\strc_registers_place_columns % {\startmixedcolumns[\currentregister] % \startpacked[\v!blank]% % \strc_registers_place_indeed % \stoppacked % \stopmixedcolumns} % % \def\strc_registers_place_normal % {\startpacked[\v!blank]% % \strc_registers_place_indeed % \stoppacked} \def\strc_registers_place_indeed {\ctxcommand{processregister('\currentregister',{ language = "\registerparameter\s!language", method = "\registerparameter\c!method", numberorder = "\registerparameter\c!numberorder", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", pagenumber = \ifx\registerpageseparatorsymbol\empty false\else true\fi, },{ 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", })}} \def\strc_registers_limited_entry#1% {\limitatetext{#1}\currentregistermaxwidth\unknown}% \appendtoks \edef\currentregistermaxwidth{\registerparameter\c!maxwidth}% \ifx\currentregistermaxwidth\empty \let\limitedregisterentry\firstofoneargument \else \let\limitedregisterentry\strc_registers_limited_entry \fi \to \everyplaceregister \unexpanded\def\completeregister {\dodoubleempty\strc_registers_complete} \def\strc_registers_complete[#1][#2]% {\iffirstargument \begingroup \edef\currentregister{#1}% \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\currentregister}},reference=\currentregister]}% \placeregister[\currentregister][#2]% \page[\v!yes]% \stopnamedsection \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): \installcorenamespace{registerindicator} \def\defaultregistercharacter#1% {\edef\currentregistercharacter{#1}% \ifx\currentregistercharacter\empty % skip \else\ifx\currentregistercharacter\s!unknown % skip \else \edef\p_indicator{\registerparameter\c!indicator}% \ifx\p_indicator\v!yes \strc_registers_place_character_yes \else \strc_registers_place_character_nop \fi \fi\fi} \def\strc_registers_place_character_yes {\expandnamespaceparameter\??registerindicator\registerparameter\c!alternative\v!a{\currentregistercharacter}} \def\strc_registers_place_character_nop {\registerparameter\c!before \goodbreak} % a = \setvalue{\??registerindicator a}#1% {\registerparameter\c!before % bugged, why does leftskip gets set: \vskip\lineheight\goodbreak\vskip-\lineheight \begingroup \useregisterstyleandcolor\c!style\c!color \dontleavehmode \strut \iflocation \dosetdirectpagereference{\currentregister:\v!section:#1}% \fi \registerparameter\c!command{#1}% \endgroup \blank[\v!samepage]% \registerparameter\c!after \par \nobreak} % b = \setvalue{\??registerindicator b}#1% will be shared with a {\registerparameter\c!before \begingroup \useregisterstyleandcolor\c!style\c!color \dontleavehmode \strut \iflocation \dosetdirectpagereference{\currentregister:\v!section:#1}% \fi \registerparameter\c!command{#1}% \endgroup \registerparameter\c!after \nobreak} \setvalue{\??registerindicator A}#1{\getvalue{\??registerindicator a}{\WORD{#1}}} \setvalue{\??registerindicator B}#1{\getvalue{\??registerindicator 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. \newconditional\c_strc_registers_page_done \newdimen \d_strc_registers_distance \unexpanded\def\startregisteroutput {\endgraf \begingroup \d_strc_registers_distance\registerparameter\c!distance\relax \dostarttagged\t!register\currentregister \forgeteverypar \forgetparindent \forgetparskip} \unexpanded\def\stopregisteroutput {\endgraf \dostoptagged \endgroup} % \unexpanded\def\startregisterentries#1% depth % {\endgraf % \begingroup % \dostarttagged\t!registerentries\empty % \let\savedcurrentregister\currentregister % \edef\currentregister{\currentregister:#1}% % \useregisterstyleandcolor\c!textstyle\c!textcolor % \advance\leftskip\numexpr#1-\plusone\relax\dimexpr\d_strc_registers_distance\relax % \hangindent\registerparameter\c!distance\relax % \hangafter\plusone % \let\currentregister\savedcurrentregister} \newdimen\d_strc_registers_hangindent \newcount\c_strc_registers_hangafter \unexpanded\def\startregisterentries#1% depth {\endgraf \begingroup \scratchcounter\ifnum#1>\c_strc_registers_maxlevel\c_strc_registers_maxlevel\else#1\fi\relax \dostarttagged\t!registerentries\empty \let\savedcurrentregister\currentregister \edef\currentregister{\currentregister:\number\scratchcounter}% \useregisterstyleandcolor\c!textstyle\c!textcolor \ifnum\scratchcounter>\plusone \advance\leftskip\d_strc_registers_distance\relax \fi \d_strc_registers_hangindent\registerparameter\c!distance\relax \c_strc_registers_hangafter \plusone \blank[\v!samepage]% \let\currentregister\savedcurrentregister} \unexpanded\def\stopregisterentries {\endgraf \dostoptagged \endgroup} \unexpanded\def\startregisterentry#1% todo: level {\begingroup \hangindent\d_strc_registers_hangindent \hangafter \c_strc_registers_hangafter} \unexpanded\def\stopregisterentry {\endgraf \endgroup} \unexpanded\def\startregistersection#1% title {\dostarttagged\t!registersection\empty \dostarttagged\t!registertag\empty \registercharacter{#1}\endgraf \dostoptagged} \unexpanded\def\stopregistersection {\dostoptagged \endgraf} \unexpanded\def\startregisterpages {\begingroup \dostarttagged\t!registerpages\empty \setfalse\c_strc_registers_page_done \useregisterstyleandcolor\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterpages {\dostoptagged \endgroup} \unexpanded\def\startregisterseewords {\ifhmode\crlf\fi \begingroup \setfalse\c_strc_registers_page_done \dostarttagged\t!registerpage\empty \useregisterstyleandcolor\c!pagestyle\c!pagecolor} \unexpanded\def\stopregisterseewords {\dostoptagged \endgroup} \unexpanded\def\registerpageseparator% todo: , configurable {\ifconditional\c_strc_registers_page_done \registerpageseparatorsymbol \else \hskip\d_strc_registers_distance\relax \settrue\c_strc_registers_page_done \fi} \unexpanded\def\registeronepagerangeseparator {|\endash|} % todo use \prewordbreak \def\withregisterpagecommand#1#2#3#4% {\def\currentregisterpageindex{#2}% \iflocation \goto{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]% \else \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}% \fi} \unexpanded\def\registeronepage#1#2#3#4% #1:processor content {\registerpageseparator \dostarttagged\t!registerpage\empty \withregisterpagecommand{#1}{#2}{#3}{#4}% \dostoptagged} \unexpanded\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} \let\strc_register_injector_process\relax \let\strc_register_injector_show \relax \unexpanded\def\defaultregisterentry#1#2#3#4% #1:processor #2:internal #3:seeindex #4:word {\def\currentregisterpageindex{#2}% \strc_register_injector_process \iflocation \def\currentregisterseeindex{#3}% \doifelse{\registerparameter\c!interaction}\v!text {\directgoto{\setlocationcolor\doapplyregisterentrycommand{#1}{#4}}[internal(#2)]} {\doapplyregisterentrycommand{#1}{#4}}% \else \let\currentregisterseeindex\empty \doapplyregisterentrycommand{#1}{#4}% \fi} \unexpanded\def\doapplyregisterentrycommand#1#2% processor text {\dostarttagged\t!registerentry\empty \ifx\currentregisterseeindex\empty \else \dontleavehmode \strc_register_injector_show \dosetdirectpagereference{seeindex:\currentregisterseeindex}% maybe some day we will support an area \fi \applyprocessor{#1}{\registerparameter\c!textcommand{\limitedregisterentry{\registerparameter\c!deeptextcommand{#2}}}}% \dostoptagged} \unexpanded\def\doapplyregisterseecommand#1#2% {\ifx\currentregisterseeindex\empty % \dontleavehmode \applyprocessor{#1}{#2}% \else \goto{\applyprocessor{#1}{#2}}[seeindex:\currentregisterseeindex]% \fi} \unexpanded\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\c_strc_registers_page_done \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{\ctxcommand{registeruserdata(#1,"#2")}} \def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1} % not yet ok : new internal handler names \unexpanded\def\registerpagebuttonsymbol {\vrule\s!width\emwidth\s!height\exheight\s!depth\zeropoint\relax} \installcorenamespace{registersymbol} \setvalue{\??registersymbol n}% {\def\registerpageseparatorsymbol{,\space}} \setvalue{\??registersymbol a}% {\def\registerpageseparatorsymbol{,\space}} % now done via conversion \setvalue{\??registersymbol\v!none}% {\let\registerpageseparatorsymbol\empty \let\registeronepage \gobblefourarguments \let\registerpagerange \gobblesevenarguments} \setvalue{\??registersymbol 1}% {\let\registerpageseparatorsymbol\space \def\registeronepage {\symbol[1]\gobblefourarguments}% \def\registerpagerange{\symbol[1]\gobblesevenarguments}} \setvalue{\??registersymbol 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\??registersymbol n\endcsname \else\ifcsname\??registersymbol\currentregisterpagesymbol\endcsname \csname\??registersymbol\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] \stopcontextdefinitioncode \protect \endinput