summaryrefslogtreecommitdiff
path: root/tex/context/base/strc-lst.mkvi
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/strc-lst.mkvi')
-rw-r--r--tex/context/base/strc-lst.mkvi1199
1 files changed, 1199 insertions, 0 deletions
diff --git a/tex/context/base/strc-lst.mkvi b/tex/context/base/strc-lst.mkvi
new file mode 100644
index 000000000..b0c2aa8c8
--- /dev/null
+++ b/tex/context/base/strc-lst.mkvi
@@ -0,0 +1,1199 @@
+%D \module
+%D [ file=strc-lst,
+%D version=2008.10.20,
+%D title=\CONTEXT\ Structure Macros,
+%D subtitle=Lists,
+%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 / Lists}
+
+\registerctxluafile{strc-lst}{1.001}
+
+% clean up in progress ...
+%
+% also (long term) todo:
+%
+% autocrossdocument
+% auto refs to lists (chain)
+%
+% TODO: strut=yes|no
+
+\unprotect
+
+\ifdefined\c!renderingsetup \else \def\c!renderingsetup{renderingsetup} \fi % maybe not interfaced
+\ifdefined\c!filler \else \def\c!filler {filler} \fi
+
+%D Lists are mostly used for tables of contents but are in fact a rather generic
+%D feature of \CONTEXT. We seperate between storage and rendering and the current
+%D implementation is a reworked version of all that was added in steps. As lists
+%D are used frequently compatibility is an important aspect. A couple of rendering
+%D alternatives are provided here but more are possible.
+
+\installcorenamespace{list}
+
+\installframedcommandhandler \??list {list} \??list
+
+\let\setuplists\setuplist % yes or no
+
+\setuplist
+ [\c!height=\v!broad,
+ \c!depth=\v!broad,
+ \c!offset=.25\emwidth,
+ \c!state=\v!start,
+ \c!coupling=\v!off,
+ \c!criterium=\v!local,
+ \c!number=\zerocount,
+ \c!width=3\emwidth,
+ %\c!maxwidth=,
+ \c!distance=\zeropoint,
+ \c!margin=\zeropoint,
+ \c!alternative=\c!b,
+ \c!style=\v!normal,
+ %\c!color=,
+ \c!textstyle=\listparameter\c!style, % \currentliststyleparameter (but then we need to set it in every ...)
+ \c!numberstyle=\listparameter\c!style, % \currentliststyleparameter
+ \c!pagestyle=\listparameter\c!style, % \currentliststyleparameter
+ \c!textcolor=\listparameter\c!color, % \currentlistcolorparameter (but then we need to set it in every ...)
+ \c!numbercolor=\listparameter\c!color, % \currentlistcolorparameter
+ \c!pagecolor=\listparameter\c!color, % \currentlistcolorparameter
+ \c!numbercommand=\firstofoneargument,
+ \c!textcommand=\firstofoneargument,
+ \c!pagecommand=\firstofoneargument,
+ \c!pagenumber=\v!yes,
+ \c!headnumber=\v!yes, % old (keep for a while)
+% \c!headnumber=\v!yes, % old (keep for a while)
+% \c!sectionnumber=\listparameter\c!headnumber, % use this instead
+ \c!interaction=\v!all, % was \v!sectionnumber, % or make this headnumber (or accept both)
+ \c!label=\v!no,
+ %\c!extras=,
+ %\c!aligntitle=,
+ %\c!before=,
+ %\c!after=,
+ %\c!inbetween=,
+ %\c!symbol=,
+ %\c!expansion=,
+ \c!limittext=\languageparameter\c!limittext] % not used currently
+
+%D Helpers:
+
+\unexpanded\def\usenestedliststyleandcolor#style#color% will change
+ {\useliststyleandcolor#style#color%
+ \ifx\currentcolorparameter\empty \else
+ \resetinteractionparameter\c!color
+ \resetinteractionparameter\c!contrastcolor
+ \fi}
+
+\unexpanded\def\doifelselist#tag% can also move to \installcommandhandler
+ {\ifcsname\namedlisthash{#tag}\s!parent\endcsname
+ \expandafter\firstoftwoarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+%D Regular list entries are bound to a specific location in order to
+%D get the right pagenumber etc.\ associated. When pushing something
+%D inbetween (in mkiv) it ends up directtly in the list. This is the
+%D default because otherwise users will wonder why spacing might get
+%D messed up (due to an unseen but present node). It is possible to
+%D force a location by explicitly setting \type {location} to \type
+%D {here}.
+%D
+%D Another way to force a certain order is to set the \type {order}
+%D variable when placing a list. The \type {command} option only
+%D pushes commands into the right order, and \type {all} orders all
+%D entries (which might be too much). In this case no specific
+%D location is needed with the inbetween method. Maybe additional
+%D mechanisms show up some day. See \type {inbetween-001.tex} for an
+%D example.
+
+% command : location=none
+% userdata : location=none
+% simple : location=here
+
+\unexpanded\def\structurelistinject
+ {\dotripleempty\strc_lists_inject}
+
+\def\strc_lists_inject[#tag]%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \doifelse{\listparameter\c!state}\v!start\strc_lists_inject_yes\strc_lists_inject_nop}
+
+\def\strc_lists_inject_nop[#dummya][#dummyb]%
+ {\endgroup}
+
+\def\strc_lists_inject_yes[#settings][#userdata]%
+ {\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped
+ \edef\p_location{\listparameter\c!location}%
+ \setnextinternalreference
+ \edef\currentlistnumber{\ctxcommand{addtolist{
+ references = {
+ internal = \nextinternalreference,
+ block = "\currentsectionblock", % handy for lists, like bibl
+ section = structures.sections.currentid(),
+ % location = "\p_location",
+ },
+ metadata = {
+ kind = "\listparameter\c!type",
+ name = "\currentlist",
+ level = structures.sections.currentlevel(),
+ catcodes = \the\catcodetable,
+ },
+ userdata = \!!bs\detokenize{#userdata}\!!es % will be converted to table at the lua end
+ }}}%
+ \ifx\p_location\v!here
+ % this branch injects nodes !
+ \expanded{\ctxlatecommand{enhancelist(\currentlistnumber)}}%
+ \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}% will change
+ \xdef\currentstructurelistattribute{\number\lastdestinationattribute}%
+ \dontleavehmode\hbox attr \destinationattribute \lastdestinationattribute{}% todo
+ \else
+ % and this one doesn't
+ \ctxcommand{enhancelist(\currentlistnumber)}%
+ \fi
+ \endgroup}
+
+\unexpanded\def\writebetweenlist{\dodoubleempty \strc_lists_write_between}
+\unexpanded\def\writedatatolist {\dotripleargument\strc_lists_write_data_to}
+\unexpanded\def\writetolist {\dodoubleempty \strc_lists_write_to}
+
+\def\strc_lists_write_between[#tag][#settings]#command% we can overload location
+ {\doif{\namedlistparameter{#tag}\c!state}\v!start
+ {\strc_lists_inject_yes[#tag][#settings,\c!type=\s!command][\s!command={#command}]}}
+
+\def\strc_lists_write_data_to[#tag][#settings][#userdata]% we can overload location
+ {\doif{\namedlistparameter{#tag}\c!state}\v!start
+ {\ifthirdargument
+ \strc_lists_inject_yes[#tag][#settings,\c!type=\s!userdata][#userdata]%
+ \else
+ \strc_lists_inject_yes[#tag][\c!type=\s!userdata][#settings]%
+ \fi}}
+
+\def\strc_lists_write_to[#tag][#settings]#first#second% we can overload location
+ {\doif{\namedlistparameter{#tag}\c!state}\v!start
+ {\strc_lists_inject_yes[#tag][\c!location=\v!here,#settings,\c!type=\s!simple][\s!first={#first},\s!second={#second}]}}
+
+%D When placing a list either one or a set can be giving. This makes
+%D it possible to flush for instance an nested (or merged) table of
+%D contents. Keep in mind that placing a list is what we do most (think
+%D of tables of contents, figures, etc.\ but other usag eis also possible
+%D in which case low level commands have to be used.
+
+\newtoks\everystructurelist
+
+\unexpanded\def\placelist
+ {\dodoubleempty\strc_lists_place}
+
+\unexpanded\def\placerawlist
+ {\dodoubleempty\strc_lists_place_raw}
+
+\def\strc_lists_place[#taglist][#settings]%
+ {\begingroup
+ \startpacked[\v!blank]%
+ \edef\m_list {#taglist}%
+ \edef\m_first{\firststructureelementinlist{#taglist}}%
+ \ifx\m_list\m_first
+ % use settings of first
+ \else
+ % use settings of root
+ \let\m_first\empty
+ \fi
+ \strc_lists_place_indeed\m_first\m_list{#settings}%
+ \stoppacked
+ \endgroup}
+
+\def\strc_lists_place_raw[#tag][#settings]% just one list
+ {\strc_lists_place_indeed\empty{#tag}{#settings}}
+
+\def\strc_lists_place_indeed#tag#list#settings%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \setupcurrentlist[#settings]%
+ \the\everystructurelist
+ % \doif{\listparameter\c!coupling}\v!on{\startlistreferences{#tag}}%
+ \doplacestructurelist % maybe inline
+ {#list}%
+ {\listparameter\c!criterium}%
+ {\listparameter\c!number}%
+ {\listparameter\c!extras}%
+ {\listparameter\c!order}%
+ % \stoplistreferences
+ \endgroup
+ \strc_lists_set_mode}
+
+\def\strc_lists_set_mode
+ {\ifcase\structurelistsize\relax
+ \resetsystemmode\v!list
+ \else
+ \setsystemmode \v!list
+ \fi}
+
+%D Complete lists are just lists but with a title. They were
+%D originally introduced to minimize the number for commands in
+%D a document source but nowadays that is less an issue in the
+%D sense that the extra few lines are neglectable to the rest.
+
+\unexpanded\def\systemsuppliedchapter {\getvalue{\v!chapter}} % obsolete
+\unexpanded\def\systemsuppliedtitle {\getvalue{\v!title}} % obsolete
+
+\unexpanded\def\completelist
+ {\dodoubleempty\strc_lists_complete}
+
+\def\strc_lists_complete[#tag][#settings]%
+ {\strc_lists_complete_indeed[#tag][#tag][#settings]}
+
+\def\strc_lists_complete_indeed[#singular][#plural][#settings]%
+ {\normalexpanded{\startnamedsection[\v!title][\c!title=\headtext{#plural},\c!reference=#singular]}%
+ \strc_lists_place[#singular][#settings]%
+ \stopnamedsection}
+
+%D Combined list provide a nice level of abstraction.
+%D
+%D \starttyping
+%D \definecombinedlist[whatever][a,b,c][settings]
+%D \stoptyping
+
+\unexpanded\def\definecombinedlist
+ {\dotripleempty\strc_lists_combined_define}
+
+\def\strc_lists_combined_define[#tag][#list][#settings]%
+ {\definelist[#tag][\c!criterium=\v!local,\c!number=0,\c!list={#list},#settings]% inherits from root
+ \setvalue{\e!setup #tag\e!endsetup}{\dodoubleempty\strc_lists_combined_setup [#tag]}%
+ \setvalue{\e!place #tag}{\dodoubleempty\strc_lists_combined_place [#tag]}%
+ \setvalue{\e!complete #tag}{\dodoubleempty\strc_lists_combined_complete[#tag]}}
+
+\unexpanded\def\setupcombinedlist
+ {\dodoubleargument\strc_lists_combined_setup}
+
+\def\strc_lists_combined_setup[#tag][#settings]%
+ {\ifsecondargument
+ \setuplist[#tag][#settings]% we don't want to mess up the parent
+ \fi}
+
+\unexpanded\def\placecombinedlist
+ {\dodoubleempty\strc_lists_combined_place}
+
+\def\strc_lists_combined_place[#tag][#settings]% i.e. no list set in settings
+ {\begingroup
+ \strc_lists_place_indeed{#tag}{\listparameter\c!list}{#settings}%
+ \endgroup}
+
+\def\strc_lists_combined_complete[#tag][#settings]%
+ {\normalexpanded{\startnamedsection[\v!title][\c!title={\headtext{#tag}},\c!reference=#tag]}%
+ \strc_lists_combined_place[#tag][#settings]%
+ \stopnamedsection}
+
+%D Given that some variables are set, we can ask for some properties of
+%D an entry.
+
+\def\currentstructurelistnumber{0} % injection
+\def\currentlistmethod {entry} % typesetting
+\def\currentlistindex {0} % typesetting
+
+\def\structurelistlocation
+ {\ctxcommand{listlocation(\currentlistindex)}}
+
+\def\structurelistrealpagenumber
+ {\ctxcommand{listrealpage("\currentlist",\currentlistindex)}}
+
+\unexpanded\def\structurelistpagenumber
+ {\dostarttagged\t!listpage\empty
+ \ctxcommand{listprefixedpage(
+ "\currentlist",
+ \currentlistindex,
+ {
+ separatorset = "\listparameter\c!pageprefixseparatorset",
+ conversionset = "\listparameter\c!pageprefixconversionset",
+ set = "\listparameter\c!pageprefixset",
+ segments = "\listparameter\c!pageprefixsegments",
+ connector = \!!bs\listparameter\c!pageprefixconnector\!!es,
+ },
+ {
+ prefix = "\listparameter\c!pageprefix",
+ conversionset = "\listparameter\c!pageconversionset",
+ starter = \!!bs\listparameter\c!pagestarter\!!es,
+ stopper = \!!bs\listparameter\c!pagestopper\!!es,
+ }
+ )}%
+ \dostoptagged}
+
+\unexpanded\def\structurelistuservariable#name%
+ {\dostarttagged\t!listdata{#name}%
+ \ctxcommand{listuserdata("\currentlist",\currentlistindex,"#name")}%
+ \dostoptagged}
+
+\unexpanded\def\structurelistfirst {\structurelistuservariable\s!first } % s!
+\unexpanded\def\structurelistsecond{\structurelistuservariable\s!second} % s!
+
+\unexpanded\def\doifstructurelisthaspageelse
+ {\ctxcommand{doiflisthaspageelse("\currentlist",\currentlistindex)}}
+
+\unexpanded\def\doifstructurelisthasnumberelse
+ {\ctxcommand{doiflisthasnumberelse("\currentlist",\currentlistindex)}}
+
+\unexpanded\def\structurelistgenerictitle
+ {\dostarttagged\t!listcontent\empty
+ \ctxcommand{listtitle("\currentlist",\currentlistindex)}%
+ \dostoptagged}
+
+\unexpanded\def\structurelistgenericnumber % tricky, we need to delay tagging as we have nested lua calls
+ {\dostarttagged\t!listtag\empty
+ \ctxcommand{listprefixednumber("\currentlist",\currentlistindex, {
+ prefix = "\listparameter\c!prefix",
+ separatorset = "\listparameter\c!prefixseparatorset",
+ conversionset = "\listparameter\c!prefixconversionset",
+ starter = \!!bs\listparameter\c!prefixstarter\!!es,
+ stopper = \!!bs\listparameter\c!prefixstopper\!!es,
+ set = "\listparameter\c!prefixset",
+ segments = "\listparameter\c!prefixsegments",
+ connector = \!!bs\listparameter\c!prefixconnector\!!es,
+ },
+ {
+ separatorset = "\listparameter\c!numberseparatorset",
+ conversionset = "\listparameter\c!numberconversionset",
+ starter = \!!bs\listparameter\c!numberstarter\!!es,
+ stopper = \!!bs\listparameter\c!numberstopper\!!es,
+ segments = "\listparameter\c!numbersegments",
+ } )}%
+ \dostoptagged}
+
+% TODO: pass extra tag name (contents, figures, bibliography ...)
+
+\unexpanded\def\doplacestructurelist#list#criterium#number#extras#order% beware, not a user command
+ {\dostarttagged\t!list\empty
+ \ctxcommand{processlist{
+ names = "#list",
+ criterium = "#criterium",
+ number = "\number#number",
+ extras = "#extras",
+ order = "#order"
+ }}%
+ \dostoptagged}
+
+\unexpanded\def\doanalyzestructurelist#list#criterium#number%
+ {\ctxcommand{analyzelist{
+ names = "#list",
+ criterium = "#criterium",
+ number = "\number#number"
+ }}}
+
+\def\firststructureelementinlist#list%
+ {\ctxcommand{firstinset("#list")}}
+
+\def\structurelistsize
+ {\ctxcommand{listsize()}}
+
+%D Depending on what kind of list we have (e.g.\ a section related one)
+%D processors can be defined.
+
+% push pop test:
+%
+% \starttext
+% \placelist[chapter] [after={\placelist[section][criterium=local]}]
+% \chapter{One} \section{Alpha} \section{Beta}
+% \chapter{Two} \section{First} \section{Second}
+% \stoptext
+
+\installcorenamespace{structurelistprocessor} % the topmost list handler
+\installcorenamespace{listextra} % control of that handler
+
+\installcommandhandler \??listextra {listextra} \??listextra
+
+\definelistextra % example
+ [\v!page]
+ [\c!before={\showmessage\m!system{14}{\currentlist/\currentlistindex}\page}]
+
+\unexpanded\def\installstructurelistprocessor#tag#meaning%
+ {\expandafter\normaldef\csname\??structurelistprocessor#tag\endcsname{#meaning}}
+
+\def\usestructurelistprocessor#tag%
+ {\csname\??structurelistprocessor#tag\endcsname}
+
+\unexpanded\def\strclistsentryprocess#tag#method#index#extra% This one is called at the lua end!
+ {\ctxcommand{pushlist(#index)}%
+ \edef\currentlist {#tag}%
+ \edef\currentlistmethod{#method}%
+ \edef\currentlistindex {#index}%
+ \edef\currentlistextra {#extra}%
+ \listextraparameter\c!before
+ \dostarttagged\t!listitem\currentlist
+ \csname\??structurelistprocessor
+ \ifcsname\??structurelistprocessor\currentlist:\currentlistmethod\endcsname\currentlist:\currentlistmethod\else
+ \ifcsname\??structurelistprocessor\currentlistmethod \endcsname\currentlistmethod \else
+ \ifcsname\??structurelistprocessor\currentlist \endcsname\currentlist \else
+ \s!default \fi\fi\fi
+ \endcsname
+ \dostoptagged
+ \listextraparameter\c!after
+ \ctxcommand{poplist()}}
+
+% lists that have a number/title are kind of generic and can share code
+
+\installstructurelistprocessor\s!default
+ {no list method}
+
+\installstructurelistprocessor\s!simple
+ {\let\currentlistentrynumber \structurelistfirst
+ \let\currentlistentrytitle \structurelistsecond
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+\installstructurelistprocessor\s!command
+ {\ctxcommand{listuserdata("\currentlist",\currentlistindex,"\s!command")}}
+
+\installstructurelistprocessor{section}
+ {\let\currentlistentrynumber \structurelistgenericnumber
+ \let\currentlistentrytitle \structurelistgenerictitle
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+\installstructurelistprocessor{number+title}
+ {\let\currentlistentrynumber \structurelistgenericnumber
+ \let\currentlistentrytitle \structurelistgenerictitle
+ \let\currentlistentrypagenumber\structurelistpagenumber
+ \strc_lists_apply_renderingsetup}
+
+% example of usage elsewhere:
+%
+% \installstructcurelistprocessor{pubs:userdata}
+% {\ctxcommand{listuserdata("\currentlist",\currentlistindex,"bibref")}}
+
+%D List symbols are used in interactive documents where no numbers
+%D are used but nevertheless structure is present. Beware, the list
+%D symbol macro gets an argument passed, i.e. when this argument is
+%D not picked up, the symbol becomes a kind of prefix. It's not really
+%D a user command (and might even get protected).
+
+\unexpanded\def\listsymbol[#tag]#number%
+ {\begingroup
+ \edef\currentlist{#tag}%
+ \def\currentlistentrynumber{#number}% no edef else tag problems
+ \currentlistsymbol
+ \endgroup}
+
+% For historical reasons we're stuck to symbols, so in order to generalize,
+% we have to hook it into the symbol handle. One way to deal with this is
+% to use a different key and as it makes sense to use setups instead of
+% def's we use a new key 'renderingsetup' which is the name of a setup.
+
+\def\strc_lists_assign_dimen#dimension#key#default%
+ {\edef\m_strc_list_dimen{\listparameter#key}%
+ \doifinsetelse\m_strc_list_dimen{\v!fit,\v!broad}{#dimension#default}{#dimension\m_strc_list_dimen}\relax}
+
+\definesymbol[\v!list][\v!none ][\strc_lists_symbol_none]
+\definesymbol[\v!list][\v!one ][\strc_lists_symbol_one]
+\definesymbol[\v!list][\v!two ][\strc_lists_symbol_two]
+\definesymbol[\v!list][\v!three ][\strc_lists_symbol_three]
+\definesymbol[\v!list][\s!default][\strc_lists_symbol_default]
+\definesymbol[\v!list][\s!unknown][\strc_lists_symbol_unknown]
+
+\unexpanded\def\currentlistsymbol
+ {\edef\p_symbol{\listparameter\c!symbol}%
+ \doifinsymbolsetelse\v!list\p_symbol
+ {\directsymbol\v!list\p_symbol}
+ {\directsymbol\v!list\s!default}}
+
+\unexpanded\def\strc_lists_symbol_none
+ {\strc_lists_assign_dimen\scratchwidth\c!width{1.5\emwidth}%
+ \hbox to \scratchwidth{}}
+
+\unexpanded\def\strc_lists_symbol_one
+ {\strut\symbol[bullet]}
+
+\unexpanded\def\strc_lists_symbol_two
+ {\vrule\!!width\emwidth\!!height\exheight\!!depth\zeropoint}
+
+\unexpanded\def\strc_lists_symbol_three
+ {\begingroup
+ \strc_lists_assign_dimen\scratchwidth \c!width {1.5\emwidth}%
+ \strc_lists_assign_dimen\scratchheight\c!height\exheight
+ \strc_lists_assign_dimen\scratchdepth \c!depth \zeropoint
+ \vrule\!!width\scratchwidth\!!height\scratchheight\!!depth\scratchdepth
+ \endgroup}
+
+\unexpanded\def\strc_lists_symbol_unknown
+ {\listparameter\c!symbol}
+
+\installcorenamespace{listsymbollabels}
+
+\unexpanded\def\strc_lists_symbol_default
+ {\dontleavehmode
+ \strut
+ \begingroup
+ \edef\currentlistlabel{\listparameter\c!label}% can be used in label
+ \csname\??listsymbollabels
+ \ifcsname\??listsymbollabels\currentlistlabel\endcsname\currentlistlabel\else\s!unknown\fi
+ \endcsname
+ \endgroup}
+
+\setvalue{\??listsymbollabels\s!unknown}% use whatever is set
+ {\leftlabeltext\currentlistlabel
+ \listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper
+ \rightlabeltext\currentlistlabel}
+
+\setvalue{\??listsymbollabels}% default (empty)
+ {\listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper}
+
+\setvalue{\??listsymbollabels\v!no}% also default
+ {\listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper}
+
+\setvalue{\??listsymbollabels\v!none}% real minimal (as suggested by WS)
+ {\currentlistentrynumber}
+
+\setvalue{\??listsymbollabels\v!yes}% auto (use value stored in tuc file)
+ {\edef\currentlistlabel{\ctxcommand{listlabel(\currentlistindex,"\currentlistlabel")}}%
+ \leftlabeltext\currentlistlabel
+ \listparameter\c!starter
+ \currentlistentrynumber
+ \listparameter\c!stopper
+ \rightlabeltext\currentlistlabel}
+
+% a : nr - tit - pag
+% b : nr - tit - fill - pag
+% c : nr - tit - dots - pag
+% d : inline
+% e : interaction
+% f : interaction
+% g : interaction
+
+\installcorenamespace{listalternative} % specific ways of rendering a list
+
+\installcommandhandler \??listalternative {listalternative} \??listalternative
+
+% Commands are bound to specific list instances as often these are
+% quite special and don't apply to multiple. So, being strict saves
+% us resets.
+
+\setuplistalternative
+ [\c!command=\strictlistparameter\c!command]
+
+\definelistalternative
+ [a]
+ [\c!distance=0pt,
+ \c!width=2em,
+ \c!stretch=10em,
+ \c!filler=\hskip.25em\relax,
+ \c!renderingsetup=\??listrenderings:abc]
+
+\definelistalternative
+ [b]
+ [\c!distance=5em,
+ \c!width=2em,
+ \c!stretch=10em,
+ \c!filler=\hfill,
+ \c!renderingsetup=\??listrenderings:abc]
+
+\definelistalternative
+ [c]
+ [\c!distance=5em,
+ \c!width=0pt,
+ \c!stretch=10em,
+ \c!filler=\hskip.5em\gleaders\hbox to .5em{\hss.\hss}\hfill\hskip.5em\relax,
+ \c!renderingsetup=\??listrenderings:abc]
+
+\definelistalternative
+ [d]
+ [\c!renderingsetup=\??listrenderings:d]
+
+\definelistalternative
+ [e]
+ [\c!renderingsetup=\??listrenderings:e]
+
+\definelistalternative
+ [f]
+ [\c!renderingsetup=\??listrenderings:f]
+
+\definelistalternative
+ [g]
+ [\c!renderingsetup=\??listrenderings:g]
+
+\definelistalternative
+ [\v!command]
+ [\c!renderingsetup=\??listrenderings:command]
+
+\definelistalternative
+ [\v!none]
+ [\c!renderingsetup=\??listrenderings:none]
+
+\definelistalternative
+ [\v!vertical]
+ [\c!before=\ifvmode\nointerlineskip\fi,
+ \c!after=\ifvmode\nointerlineskip\fi\endgraf\allowbreak,
+ \c!renderingsetup=\??listrenderings:generic]
+
+\definelistalternative
+ [\v!horizontal]
+ [\c!before=\noindent,
+ \c!after=,
+ \c!renderingsetup=\??listrenderings:generic]
+
+% \setuplist
+% [section]
+% [alternative=MyListItem,
+% after=\blank,
+% before=\blank]
+%
+% \definelistplacement[MyListItem][command]#1#2#3{(#1) (#2) (#3)}
+% \definelistplacement[MyListItem][command]{\whatever}
+%
+% this is a compatibility command, best use the regular
+% defined with command= either set in the alternative or
+% in the list
+
+\installcorenamespace{listelementcommand} % the old plugin model
+
+\unexpanded\def\definelistplacement
+ {\dodoubleempty\strc_lists_define_placement}
+
+\def\strc_lists_define_placement[#tag][#method]%
+ {\edef\p_method{#method}%
+ \ifx\p_method\empty
+ \let\p_method\v!command
+ \fi
+ \normalexpanded{\definelistalternative[#tag][\p_method]}[\c!command=\strc_lists_placement_command]%
+ \doifnextbgroupelse
+ {\strc_lists_define_placement_yes{#tag}}
+ {\strc_lists_define_placement_nop{#tag}}}
+
+% indirect definition: <three ignore arguments>: {\bla}
+
+\def\strc_lists_define_placement_yes#tag%
+ {\unexpanded\expandafter\normaldef\csname\??listelementcommand#tag\endcsname##1##2##3}
+
+% direct definition: <three arguments>{\bla}
+
+\def\strc_lists_define_placement_nop#tag%
+ {\unexpanded\expandafter\normaldef\csname\??listelementcommand#tag\endcsname}
+
+\def\strc_lists_placement_command
+ {\csname\??listelementcommand\currentlistalternative\endcsname}
+
+%D The rendering macros.
+
+\newbox \b_strc_lists_number
+\newbox \b_strc_lists_text
+\newbox \b_strc_lists_page
+
+\newtoks \t_lists_every_renderingsetup
+\newtoks \t_lists_every_renderingtext
+\newtoks \t_lists_every_renderingcleanup
+
+\newconditional\c_lists_has_number
+\newconditional\c_lists_has_page
+
+\let\currentlistentrylocation \empty % watch the 'entry' in the name
+\let\currentlistentrynumber \empty % watch the 'entry' in the name
+\let\currentlistentrytitle \empty % watch the 'entry' in the name
+\let\currentlistentrypagenumber\empty % watch the 'entry' in the name
+
+\appendtoks
+ \dontcomplain
+ \letinteractionparameter\c!width\zeropoint % a weird one
+\to \t_lists_every_renderingsetup
+
+\appendtoks
+ % better is to use a special list entry but we keep this for compatibility
+ \let\\=\space
+ % so expanding this token register has to come *after* the font switch
+ \dontconvertfont
+\to \t_lists_every_renderingtext
+
+\appendtoks
+ % because we want to avoid redundant lua calls we expand the
+ % location beforehand
+ \ifx\currentlistentrylocation\empty
+ \edef\currentlistentrylocation{\structurelistlocation}%
+ \fi
+ % because these tests happen often and because we're dealing with
+ % rather complex composed data we have special conditionals; keep
+ % in mind that testing for empty fails do to tagging being applied
+ \doifstructurelisthaspageelse \settrue\setfalse\c_lists_has_page
+ \doifstructurelisthasnumberelse\settrue\setfalse\c_lists_has_number
+\to \t_lists_every_renderingsetup
+
+\appendtoks
+ \strc_lists_interaction_check
+\to \t_lists_every_renderingsetup
+
+\appendtoks
+ % as we don't want any interference we clear some variables
+ % afterwards
+ \let\currentlistentrylocation \empty
+ \let\currentlistentrynumber \empty
+ \let\currentlistentrytitle \empty
+ \let\currentlistentrypagenumber\empty
+ \setfalse\c_lists_has_page
+ \setfalse\c_lists_has_number
+\to \t_lists_every_renderingcleanup
+
+\unexpanded\def\strc_lists_apply_renderingsetup
+ {\the\t_lists_every_renderingsetup
+ \edef\currentlistalternative{\listparameter\c!alternative}%
+ \directsetup{\listalternativeparameter\c!renderingsetup}\relax
+ \the\t_lists_every_renderingsetup}
+
+% todo: provide packager via attributes
+
+\installcorenamespace{listalternativemethods} % the general wrapper of a rendering
+\installcorenamespace{listrenderings} % a namespace for setups (rather local)
+
+\startsetups[\??listrenderings:\v!none]
+ % nothing, nb we use the [] syntax here because we end with a \cs
+\stopsetups
+
+\startsetups[\??listrenderings:\v!command]
+ \edef\p_command{\listalternativeparameter\c!command}%
+ \ifx\p_command\empty
+ [\currentlist: \currentlistentrynumber\space -- \currentlistentrytitle\space -- \currentlistentrypagenumber]%
+ \else
+ \p_command\currentlistentrynumber\currentlistentrytitle\currentlistentrypagenumber
+ \fi
+\stopsetups
+
+% \startsetups[\??listrenderings:\v!vertical]
+% \directsetup{\??listrenderings:generic}
+% \stopsetups
+
+% \startsetups[\??listrenderings:\v!horizontal]
+% \directsetup{\??listrenderings:generic}
+% \stopsetups
+
+\startsetups[\??listrenderings:generic]
+ \listparameter\c!before % can be \hskip
+ \edef\p_command{\listalternativeparameter\c!command}
+ \ifx\p_command\empty
+ \listalternativeparameter\c!before
+ \vbox {
+ \forgetall
+ \hbox \strc_lists_get_reference_attribute\v!all {
+ \edef\p_headnumber{\listparameter\c!headnumber}
+ \ifx\p_headnumber\v!yes
+ % \ifconditional\c_lists_has_page
+ \hbox \strc_lists_get_reference_attribute\v!number {
+ \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
+ \listparameter\c!numbercommand\currentlistsymbol
+ }
+ % \fi
+ \fi
+ \hbox \strc_lists_get_reference_attribute\v!text {
+ \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
+ \the\t_lists_every_renderingtext
+ \listparameter\c!textcommand\currentlistentrytitle
+ }
+ \edef\p_pagenumber{\listparameter\c!pagenumber}
+ \ifx\p_pagenumber\v!yes
+ \ifconditional\c_lists_has_page
+ \hbox \strc_lists_get_reference_attribute\v!pagenumber {
+ \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
+ \listparameter\c!pagecommand\currentlistentrypagenumber
+ }
+ \fi
+ \fi
+ }
+ }
+ \listalternativeparameter\c!after
+ \else
+ \hbox \strc_lists_get_reference_attribute\v!all {
+ \p_command\currentlistentrynumber\currentlistentrytitle\currentlistentrypagenumber
+ }
+ \fi
+ \listparameter\c!after
+\stopsetups
+
+% to be documented: align, hang
+
+\startsetups[\??listrenderings:abc]
+ \endgraf % are we grouped?
+ \leftskip\listparameter\c!margin % after \endgraf !
+ \listparameter\c!before
+ \endgraf
+ \edef\p_width{\listparameter\c!width}
+ \scratchdistance\listparameter\c!distance
+ \ifx\p_width\v!fit
+ \scratchwidth\zeropoint
+ \else\ifconditional\c_lists_has_number
+ \scratchwidth\p_width
+ \else
+ \edef\p_aligntitle{\listparameter\c!aligntitle}
+ \ifx\p_aligntitle\v!yes
+ \scratchwidth\zeropoint
+ \scratchdistance\zeropoint
+ \else
+ \scratchwidth\p_width
+ \fi
+ \fi\fi
+ \noindent
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \setlocalhsize
+ \hsize\localhsize
+ \hbox to \hsize {
+ \forgetall
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \scratchhsize\hsize
+ \edef\p_headnumber{\listparameter\c!headnumber}
+ \ifconditional\c_lists_has_number
+ \ifx\p_headnumber\v!yes
+ \setbox\b_strc_lists_number\hbox \strc_lists_get_reference_attribute\v!number \ifdim\scratchwidth>\zeropoint to \scratchwidth \fi {
+ \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
+ \listparameter\c!numbercommand\currentlistsymbol
+ \hfill
+ }
+ \else
+ \setbox\b_strc_lists_number\emptyhbox
+ \fi
+ \else
+ \scratchwidth\zeropoint
+ \scratchdistance\zeropoint
+ \setbox\b_strc_lists_number\emptyhbox
+ \fi
+ \ifconditional\c_lists_has_page
+ \edef\p_pagenumber{\listparameter\c!pagenumber}
+ \ifx\p_pagenumber\v!yes
+ \setbox\b_strc_lists_page\hbox {
+ \scratchdimen\listalternativeparameter\c!width
+ \hbox \strc_lists_get_reference_attribute\v!pagenumber \ifdim\scratchdimen>\zeropoint to \scratchdimen\fi {
+ \hfill
+ \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
+ \strut
+ \listparameter\c!pagecommand\currentlistentrypagenumber
+ }
+ }
+ \else
+ \setbox\b_strc_lists_page\emptyhbox
+ \fi
+ \else
+ \setbox\b_strc_lists_page\emptyhbox
+ \fi
+ \vbox {
+ \hsize\scratchhsize
+ \usealignparameter\listparameter
+ \ifdim\scratchwidth<\hsize
+ \edef\p_hang{\listparameter\c!hang}
+ \hangindent\dimexpr\wd\b_strc_lists_number+\scratchdistance\relax
+ \hangafter\ifx\p_hang\v!no\zerocount\else\plusone\fi
+ \scratchdimen\listalternativeparameter\c!distance
+ \ifdim\wd\b_strc_lists_page=\zeropoint \else\ifdim\scratchdimen>\zeropoint\relax
+ \rightskip\scratchdimen\!!plus\listalternativeparameter\c!stretch\relax
+ \parfillskip-\rightskip
+ \fi \fi
+ \else
+ \scratchdistance\zeropoint
+ \fi
+ \parindent\zeropoint
+ \dontleavehmode
+ % % topaligned
+ %
+ % \scratchdimen\wd\b_strc_lists_number
+ % \setbox\b_strc_lists_number\hbox to \hsize{\box\b_strc_lists_number\hss\box\b_strc_lists_page}%
+ % \wd\b_strc_lists_number\scratchdimen
+ %
+ \box\b_strc_lists_number
+ \hskip\scratchdistance\relax
+ \begingroup
+ \strc_lists_set_reference_attribute\v!text
+ \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
+ \the\t_lists_every_renderingtext
+ \setstrut % needs checking, new here
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ \endgroup
+ \ifdim\wd\b_strc_lists_page=\zeropoint\else
+ \nobreak
+ \listalternativeparameter\c!filler
+ \box\b_strc_lists_page
+ \fi
+ }
+ \hss
+ }
+ }% new
+ \endgraf % new, else problems with nointerlinespace and prevdepth
+ \nointerlineskip % anders verkeerde spatiering bij multi-line
+ \endgraf
+ \allowbreak
+ \listparameter\c!after
+\stopsetups
+
+% % example from the context list
+%
+% \setuphead [part] [page=right,placehead=yes]
+% \setuplist [chapter] [alternative=d,before=\blank,after=\blank]
+% \setuplist [part] [before=\blank,after=\blank]
+%
+% \starttext
+% \startnarrower[2*right] \placecontent \stopnarrower
+% \blank[4*big]
+% \startsetups chapter
+% \blank \startnarrower[3*middle] \placecontent[criterium=local] \stopnarrower
+% \stopsetups
+% \placelist[part][criterium=text,after=\setups{chapter}]
+%
+% \part{First part} \chapter{Chapter one} \chapter{Chapter two}
+% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
+% \part{Second part} \chapter{Chapter one} \chapter{Chapter two}
+% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
+% \part{Third part} \chapter{Chapter one} \chapter{Chapter two}
+% \chapter{Chapter three} \chapter{Chapter four} \chapter{Chapter five}
+% \stoptext
+
+% overrulen interactie kan sneller, bv door hulpconstanten
+% te gebruiken en die te letten
+
+\startsetups[\??listrenderings:d]
+ \ifvmode
+ \advance\leftskip\listparameter\c!margin
+ \fi
+ \begingroup
+ \ifvmode
+ \noindent
+ \fi
+ \begingroup
+ \strc_lists_set_reference_attribute\v!all
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \strc_lists_get_destination_attribute
+ \begingroup
+ \edef\p_headnumber{\listparameter\c!headnumber}
+ \ifx\p_headnumber\v!yes
+ \donetrue
+ \ifconditional\c_lists_has_number \else
+ \edef\p_symbol{\listparameter\c!symbol}
+ \ifx\p_symbol\empty
+ \donefalse
+ \fi
+ \fi
+ \ifdone
+ \begingroup
+ \strc_lists_set_reference_attribute\v!number
+ \strc_lists_set_style_color\c!numberstyle\c!numbercolor\v!number
+ \listparameter\c!left
+ \listparameter\c!numbercommand\currentlistsymbol
+ \listparameter\c!right
+ \endgroup
+ \kern.5em
+ \nobreak
+ \fi
+ \fi
+ \endgroup
+ \begingroup
+ \strc_lists_set_reference_attribute\v!text
+ \strc_lists_set_style_color\c!textstyle\c!textcolor\v!text
+ \the\t_lists_every_renderingtext
+ \setstrut % needs checking, new here
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ \endgroup
+ \begingroup
+ \ifconditional\c_lists_has_page
+ \edef\p_pagenumber{\listparameter\c!pagenumber}
+ \ifx\p_pagenumber\v!yes
+ \nobreak
+ \hskip.75em\relax
+ \nobreak
+ \strc_lists_set_reference_attribute\v!pagenumber
+ \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber
+ \strut
+ \listparameter\c!pagecommand\currentlistentrypagenumber
+ \fi
+ \fi
+ \endgroup
+ \scratchdistance\listparameter\c!distance\relax
+ \ifdim\scratchdistance<\emwidth
+ \hskip\emwidth\!!plus\emwidth\!!minus.25\emwidth\relax
+ \else
+ \hskip\scratchdistance\!!plus.5\scratchdistance\!!minus.25\scratchdistance\relax
+ \fi
+ \endgroup
+ \endgroup
+\stopsetups
+
+\startsetups[\??listrenderings:e]
+ \noindent
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \letlistparameter\c!depth\zeropoint
+ \letlistparameter\c!color\empty
+ \inheritedlistframed {
+ \letinteractionparameter\c!strut\v!no % still needed?
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \the\t_lists_every_renderingtext
+ \setstrut
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ }
+ }
+ \par
+ \listparameter\c!inbetween
+\stopsetups
+
+\startsetups[\??listrenderings:f]
+ \noindent
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \dosetraggedhbox{\listparameter\c!align}%
+ \raggedbox {
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \the\t_lists_every_renderingtext
+ \setstrut
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ }
+ }
+ \par
+ \listparameter\c!inbetween
+\stopsetups
+
+\startsetups[\??listrenderings:g]
+ \noindent
+ \hbox \strc_lists_get_reference_attribute\v!all \strc_lists_get_destination_attribute {
+ \midaligned {
+ \strc_lists_set_style_color\c!style\c!color\v!all
+ \the\t_lists_every_renderingtext
+ \setstrut
+ \begstrut
+ \strc_lists_limitated_text\currentlistentrytitle
+ \endstrut
+ }
+ }
+ \par
+ \listparameter\c!inbetween
+\stopsetups
+
+%D List elements are packaged in such a way that we can click on them
+%D in an interactive document. Here are a few helpers.
+
+\newconstant\a_strc_lists_reference
+\newconstant\a_strc_lists_destination
+
+\installcorenamespace{listinteractions}
+
+\letvalue{\??listinteractions\v!number }\v!number
+\letvalue{\??listinteractions\v!sectionnumber}\v!number
+\letvalue{\??listinteractions\v!text }\v!text
+\letvalue{\??listinteractions\v!title }\v!text
+\letvalue{\??listinteractions\v!page }\v!pagenumber
+\letvalue{\??listinteractions\v!pagenumber }\v!pagenumber
+\letvalue{\??listinteractions\v!all }\v!all
+\letvalue{\??listinteractions\v!yes }\v!all
+
+\unexpanded\def\strc_lists_interaction_check
+ {\iflocation
+ \strc_lists_interaction_check_yes
+ \else
+ \strc_lists_interaction_check_nop
+ \fi}
+
+\def\strc_lists_interaction_check_yes
+ {\edef\p_interaction_forward{\listparameter\c!interaction}%
+ \ifcsname\??listinteractions\p_interaction_forward\endcsname
+ \expandafter\let\expandafter\p_interaction_forward\csname\??listinteractions\p_interaction_forward\endcsname
+ \dogetsimplepagereference{internal(\currentlistentrylocation)}%
+ \a_strc_lists_reference\currentreferenceattribute
+ \else
+ \a_strc_lists_reference\attributeunsetvalue
+ \fi
+ \ifnum\a_strc_lists_reference=\attributeunsetvalue
+ \let\strc_lists_get_reference_attribute\gobbleoneargument
+ \let\strc_lists_set_reference_attribute\gobbleoneargument
+ \let\strc_lists_set_style_color \strc_lists_set_style_color_normal
+ \else
+ \let\strc_lists_get_reference_attribute\strc_lists_get_reference_attribute_indeed
+ \let\strc_lists_set_reference_attribute\strc_lists_set_reference_attribute_indeed
+ \let\strc_lists_set_style_color \strc_lists_set_style_color_special
+ \fi
+ \edef\p_interaction_backward{\namedheadparameter\currentlist\c!interaction}% \namedheadparameter !
+ \ifx\p_interaction_backward\v!list
+ \dosetsimplepagereference{bck:\currentlistentrylocation}%
+ \a_strc_lists_destination\currentdestinationattribute
+ \else
+ \a_strc_lists_destination\attributeunsetvalue
+ \fi
+ \ifnum\a_strc_lists_destination=\attributeunsetvalue
+ \let\strc_lists_get_destination_attribute\empty
+ \let\strc_lists_set_destination_attribute\empty
+ \else
+ \let\strc_lists_get_destination_attribute\strc_lists_get_destination_attribute_indeed
+ \let\strc_lists_set_destination_attribute\strc_lists_set_destination_attribute_indeed
+ \fi}
+
+\def\strc_lists_interaction_check_nop
+ {\let\strc_lists_get_reference_attribute \gobbleoneargument
+ \let\strc_lists_set_reference_attribute \gobbleoneargument
+ \let\strc_lists_get_destination_attribute\empty
+ \let\strc_lists_set_destination_attribute\empty
+ \let\strc_lists_set_style_color \strc_lists_set_style_color_normal}
+
+\def\strc_lists_get_reference_attribute_indeed#element%
+ {\ifx#element\p_interaction_forward
+ attr \referenceattribute\a_strc_lists_reference
+ \fi}
+
+\def\strc_lists_set_reference_attribute_indeed#element%
+ {\ifx#element\p_interaction_forward
+ \attribute\referenceattribute\a_strc_lists_reference
+ \fi}
+
+\def\strc_lists_get_destination_attribute_indeed
+ {attr \destinationattribute\number\a_strc_lists_destination}
+
+\def\strc_lists_set_destination_attribute_indeed
+ {\attribute\destinationattribute\a_strc_lists_destination}
+
+\unexpanded\def\strc_lists_set_style_color_normal#style#color#element%
+ {\useliststyleandcolor#style#color}
+
+\unexpanded\def\strc_lists_set_style_color_special#style#color#element%
+ {\useliststyleandcolor#style#color%
+ \ifx\currentcolorparameter\empty
+ \ifx#element\p_interaction_forward
+ \setlocationcolor
+ \fi
+ % \else
+ % \resetinteractionparameter\c!color
+ % \resetinteractionparameter\c!contrastcolor
+ \fi}
+
+%D A helper:
+
+\def\strc_lists_limitated_text#text%
+ {\edef\p_maxwidth{\listparameter\c!maxwidth}%
+ \ifx\p_maxwidth\empty
+ \listparameter\c!textcommand{#text}%
+ \else
+ \listparameter\c!textcommand{\limitatetext{#text}\p_maxwidth{\splitsymbol{\listparameter\c!limittext}}}%
+ \fi}
+
+% todo:
+
+\def\utilitylistlength{\listlength} % old name ... uses in styles
+
+\let\listlength\!!zerocount % better use listmode
+
+\unexpanded\def\determinelistcharacteristics
+ {\dodoubleempty\strc_lists_determine_characteristics}
+
+\def\strc_lists_determine_characteristics[#list][#settings]%
+ {\begingroup
+ \edef\currentlist{\firststructureelementinlist{#list}}%
+ \ifx\currentlist\empty
+ \endgroup
+ \let\listlength\!!zerocount
+ \else
+ \setupcurrentlist[#settings]%
+ \doanalyzestructurelist{#list}{\listparameter\c!criterium}{\listparameter\c!number}%
+ \normalexpanded{\endgroup\noexpand\edef\noexpand\listlength{\structurelistsize}}%
+ \fi
+ \strc_lists_set_mode}
+
+\protect \endinput