diff options
Diffstat (limited to 'tex/context/base/typo-mar.mkiv')
-rw-r--r-- | tex/context/base/typo-mar.mkiv | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/tex/context/base/typo-mar.mkiv b/tex/context/base/typo-mar.mkiv new file mode 100644 index 000000000..4d122204e --- /dev/null +++ b/tex/context/base/typo-mar.mkiv @@ -0,0 +1,351 @@ +% macros=mkvi + +%D \module +%D [ file=typo-mar, +%D version=2010.02.15, % was experimental code +%D title=\CONTEXT\ Typesetting Macros, +%D subtitle=Margindata, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright=\PRAGMA] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +% todo: tags + +\writestatus{loading}{ConTeXt Typesetting Macros / Margindata} + +\unprotect + +%D This module has been on the agenda for a while. Actually, it is +%D one of the things that I really need myself, for instance when +%D rendering rather unpredictable (educational) tests encoded in +%D XML. This module permits anchoring for instance item numbers and +%D also overload them when they have subnumbers. In the future it +%D might replace the current maginal note mechanism (that then +%D will be just an instance). +%D +%D In spite of what might be expected, the more advanced \LUA\ based +%D variant is upto twice as fast on simple entries. Also, we no longer +%D need an extra pass to get inner and outer alignments in sync with +%D the pagebuilder. + +\registerctxluafile{typo-mar}{1.001} + +%definesystemattribute[margindata] % only at the lua end + +%D In \MKII\ we have three categories and their historically meaning +%D is as follows: +%D +%D marginlines: These are flushed relative to the start of a line and +%D need to be invoked there. +%D +%D marginwords: These can be issued in the text flow and will migrate +%D sidewards; in spite of the name, it can be a paragraph of text as +%D well, but normally it's words. +%D +%D margintexts: These can be set beforehand and are flushed at the +%D next paragraph of text (of header). +%D +%D In \MKIV\ we have further integrated the mechanism and we now have: +%D +%D margindata: This can be anything that needs to go into the margin. +%D It can be anchored in the text or given beforehand in which case +%D it gets flushed at the first occasion. +%D +%D margintext: This runs on top of margindata and the only difference +%D is that it uses the framed mechanism for packaging. +%D +%D Stacking is done differently as is inner and outer alignment (in +%D most cases more efficient). The functionality is mostly the same +%D as in \MKII, but there are a few additions, like names entries, +%D where later ones overload preceding not yet flushed ones. Data can +%D get catagorized and is then treated as a group (e.g. when stacking +%D is needed). +%D +%D The amount of \TEX\ code is less than in \MKII\ because we do all +%D trickery in at the \LUA\ end. At the end of this file we define +%D several commands, like \type {\inleftmargin} and \type {\inleft}. +%D You can configure them individually or as a group. There is an +%D inheritance model in place. +%D +%D The following notes will be stacked: +%D +%D \starttyping +%D \ininner[line=2]{IM A} +%D \ininner[stack=yes]{IM B} +%D \ininner[stack=yes]{IM C} +%D \stoptyping +%D +%D The distance between them is determined by \type {dy}: +%D +%D \starttyping +%D \ininner[stack=yes,dy=2ex][frame=on] {IM A} +%D \ininner[stack=yes,dy=2ex][frame=on] {IM B} +%D \stoptyping +%D +%D There are several methods of vertical alignment. +%D +%D \starttyping +%D \inmargin [method=first] [frame=on] {first\\second} \input ward \par +%D \inmargin [method=first] [frame=on,offset=3pt] {first\\second} \input ward \par +%D \inmargin [method=first,voffset=-3pt][frame=on,offset=3pt,rulethickness=3pt] {first\\second} \input ward \par +%D \inmargin [method=first,voffset=-6pt][frame=on,offset=3pt,rulethickness=3pt] {first\\second} \input ward \par +%D \stoptyping +%D +%D You sometimes need to combine \type {voffset} with \type {offset}. The first +%D argument concerns the data, the second the framed. Not sharing the setup is +%D on purpose: location, offset, alignment and other parameters might clash. + +\def\??mc{@@mc} % margincategory +\def\??mf{@@mf} % marginframed + +\installcommandhandler\??mc{margindata}\??mc +\installcommandhandler\??mf{marginframed}\??mf + +\setupmargindata + [\c!location=\v!left, + % \c!align=, + % \c!method=, + \c!style=\v!bold, + \c!color=, % maybe textcolor + % \c!name=, + % \c!category=, + \c!threshold=.25ex, + \c!margin=\v!normal, + \c!scope=\v!global, + \c!width=, + % \c!stack=, + \c!line=0, + \c!dy=\zeropoint, + \c!distance=\zeropoint, + \c!hoffset=\zeropoint, + \c!voffset=\zeropoint] + +\setupmarginframed % so, align should be set with the data command + [\c!strut=\v!yes, + \c!offset=\v!overlay, + \c!fr!analyze=\v!yes, + \c!frame=\v!off, + \c!width=\margindataparameter\c!width, + \c!align=\margindataparameter\c!align] + +\appendtoks + \setuevalue\currentmargindata{\margindata[\currentmargindata]}% +\to \everydefinemargindata + +\newconditional\inhibitmargindata % This one is used at the Lua end! +\newtoks \everymargindatacontent % Later on we will set this one. + +\unexpanded\def\margindata[#name]% + {\setfalse\inhibitmargindata % flushing afterwards + \begingroup + %\settrue\inhibitmargindata % no flushing in here + \def\currentmargindata{#name}% + \dodoubleempty\domargindata} + +\appendtoks + \settrue\inhibitmargindata +\to \everyforgetall + +% option test -> ruled + +\appendtoks + \forgetall + \tf + \deactivatecolor +\to \everymargindatacontent + +\unexpanded\def\domargindata[#dataparameters][#textparameters]#content% + {\iffirstargument + \setupmargindata[\currentmargindata][#dataparameters]% + \fi + \edef\currentmargindatastrut{\margindataparameter\c!strut}% + \the\everymargindatacontent + \dostarttagged\t!margintext\currentmargindata + \ifcsname\??mf\currentmargindata\s!parent\endcsname + \setbox\nextbox\hbox\bgroup + \the\everymargindatacontent + \dosetmargindataattributes\c!style\c!color + \localframedwithsettings[\??mf\currentmargindata][\c!location=\v!normal,#textparameters]\bgroup + \ifx\currentmargindatastrut\empty \else + \dosetupstrut[\currentmargindatastrut]% + \fi + \begstrut\margindataparameter\c!command{#content}\endstrut + \egroup + \egroup + \edef\currentmarginfirstheight{\number\dimexpr\framedfirstheight}% + \else + \edef\currentmargindatawidth{\margindataparameter\c!width}% + \ifx\currentmargindatawidth\empty + \setbox\nextbox\hbox\bgroup + \the\everymargindatacontent + \dosetmargindataattributes\c!style\c!color + \ifx\currentmargindatastrut\empty \else + \dosetupstrut[\currentmargindatastrut]% + \fi + \begstrut\margindataparameter\c!command{#content}\endstrut + \egroup + \let\currentmarginfirstheight\empty + \else + \dosetraggedcommand{\margindataparameter\c!align}% + \setbox\nextbox\hbox \bgroup\vtop \bgroup % hbox is needed + \the\everymargindatacontent + \dosetmargindataattributes\c!style\c!color + \hsize\currentmargindatawidth + \raggedcommand + \ifx\currentmargindatastrut\empty \else + \dosetupstrut[\currentmargindatastrut]% + \fi + \begstrut\margindataparameter\c!command{#content}\endstrut + \egroup \egroup + \edef\currentmarginfirstheight{true}% + \fi + \fi + \dostoptagged + \ctxlua{typesetters.margins.save{ + \c!location = "\margindataparameter\c!location", + \c!method = "\margindataparameter\c!method", + \c!category = "\margindataparameter\c!category", + \c!name = "\margindataparameter\c!name", + \c!margin = "\margindataparameter\c!margin", % local normal margin edge + \c!distance = \number\dimexpr\margindataparameter\c!distance, + \c!hoffset = \number\dimexpr\margindataparameter\c!hoffset, + \c!voffset = \number\dimexpr\margindataparameter\c!voffset, + \c!dy = \number\dimexpr\margindataparameter\c!dy, + \ifx\currentmarginfirstheight\empty \else + baseline = \currentmarginfirstheight, + \fi + threshold = \number\dimexpr\margindataparameter\c!threshold, % will change + \ifhmode + inline = true, + \fi + \c!scope = "\margindataparameter\c!scope", + \c!align = "\margindataparameter\c!align", + \c!line = "\margindataparameter\c!line", + \c!stack = "\margindataparameter\c!stack", + \c!number = \number\nextbox + }}% + \endgroup} + +%D Downward compatible hack: + +\unexpanded\def\spaceorpar + {\endgraf\ifhmode\space\fi} + +\appendtoks + \let\\\spaceorpar +\to \everymargindatacontent + +%D Another one: + +% \letvalue{\??mc->\v!left }\v!right +% \letvalue{\??mc->\v!right }\v!left +% \letvalue{\??mc->\v!inner }\v!outer +% \letvalue{\??mc->\v!outer }\v!inner +% \letvalue{\??mc->\v!normal}\v!normal +% +% \def\oppositemargin#1% +% {\csname\??mc->\ifcsname\??mc->#1\endcsname#1\else\v!normal\fi\endcsname} + +%D Definitions: + +% common to lines and text + +\setupmargindata [\v!left ] [\c!method=\v!first,\c!location=\v!left ,\c!margin=\v!margin,\c!align=\v!flushright,\s!parent=\??mc] % we could autoparent when no define yet +\setupmargindata [\v!right] [\c!method=\v!first,\c!location=\v!right,\c!margin=\v!margin,\c!align=\v!flushleft, \s!parent=\??mc] +\setupmargindata [\v!outer] [\c!method=\v!first,\c!location=\v!outer,\c!margin=\v!margin,\c!align=\v!inner, \s!parent=\??mc] +\setupmargindata [\v!inner] [\c!method=\v!first,\c!location=\v!inner,\c!margin=\v!margin,\c!align=\v!outer, \s!parent=\??mc] + +% lines + +\definemargindata [inleftmargin] [\v!left ] [\c!margin=\v!margin,\c!width=\leftmarginwidth ,\c!style=,\c!color=] +\definemargindata [inrightmargin] [\v!right] [\c!margin=\v!margin,\c!width=\rightmarginwidth,\c!style=,\c!color=] +\definemargindata [inoutermargin] [\v!outer] [\c!margin=\v!margin,\c!width=\outermarginwidth,\c!style=,\c!color=] +\definemargindata [ininnermargin] [\v!inner] [\c!margin=\v!margin,\c!width=\innermarginwidth,\c!style=,\c!color=] + +\definemargindata [inleftedge] [\v!left ] [\c!margin=\v!edge ,\c!width=\leftedgewidth ,\c!style=,\c!color=,\c!category=\v!edge] +\definemargindata [inrightedge] [\v!right] [\c!margin=\v!edge ,\c!width=\rightedgewidth ,\c!style=,\c!color=,\c!category=\v!edge] +\definemargindata [inouteredge] [\v!outer] [\c!margin=\v!edge ,\c!width=\outeredgewidth ,\c!style=,\c!color=,\c!category=\v!edge] +\definemargindata [ininneredge] [\v!inner] [\c!margin=\v!edge ,\c!width=\inneredgewidth ,\c!style=,\c!color=,\c!category=\v!edge] + +\definemargindata [atleftmargin] [\v!left ] [\c!margin=\v!normal,\c!width=\leftmarginwidth ,\c!style=,\c!color=] +\definemargindata [atrightmargin] [\v!right] [\c!margin=\v!normal,\c!width=\rightmarginwidth,\c!style=,\c!color=] + +% text + +\definemargindata [inleft] [\v!left ] [\c!margin=\c!margin,\c!width=\leftmarginwidth ,\c!align=\v!flushright] +\definemargindata [inright] [\v!right] [\c!margin=\c!margin,\c!width=\rightmarginwidth,\c!align=\v!flushleft] +\definemargindata [inouter] [\v!outer] [\c!margin=\c!margin,\c!width=\outermarginwidth,\c!align=\v!inner] +\definemargindata [ininner] [\v!inner] [\c!margin=\c!margin,\c!width=\innermarginwidth,\c!align=\v!outer] + +% no longer auto auto-other + +\definemargindata [inmargin] [\v!left] [\c!margin=\c!margin,\c!width=\leftmarginwidth, \c!align=\v!flushright] +\definemargindata [inother] [\v!right] [\c!margin=\c!margin,\c!width=\rightmarginwidth,\c!align=\v!flushleft] + +\definemargindata [margintext] [\v!left] % keep it a bit separated from inleft and inmargin + +\setupmarginframed [\v!left ] [\c!method=\v!first,\c!align=\v!flushright,\s!parent=\??mf] % we could autoparent when no define yet +\setupmarginframed [\v!right] [\c!method=\v!first,\c!align=\v!flushleft, \s!parent=\??mf] +\setupmarginframed [\v!outer] [\c!method=\v!first,\c!align=\v!inner, \s!parent=\??mf] +\setupmarginframed [\v!inner] [\c!method=\v!first,\c!align=\v!outer, \s!parent=\??mf] + +\definemarginframed [inleft] [\v!left ] +\definemarginframed [inright] [\v!right] +\definemarginframed [inouter] [\v!outer] +\definemarginframed [ininner] [\v!inner] +\definemarginframed [inmargin] [\v!inleft] +\definemarginframed [inother] [\v!inright] + +\let\marginword \margintext +\let\margintitle\margintext + +%definemargindata [inouterextra] [\v!outer] [\c!margin=\c!edge,\c!location=\v!outer,\c!width=\outeredgewidth,\c!align=\v!outer,\c!category=\v!edge] +%definemargindata [ininnerextra] [\v!inner] [\c!margin=\c!edge,\c!location=\v!inner,\c!width=\inneredgewidth,\c!align=\v!inner,\c!category=\v!edge] +% +%definemarginframed [inouterextra] [\v!outer] +%definemarginframed [ininnerextra] [\v!inner] + +%D As we have more control we are not backward compatible although in +%D practice it won't hurt that much. +%D So, from now on use: +%D +%D \starttyping +%D \setupmargindata +%D \setupmargintext +%D \stoptyping + +% The following sort of works okay: +% +% \let\definemarginline\definemargindata +% +% \unexpanded\def\defineinmargin +% {\doquadrupleempty\dodefineinmargin} +% +% \def\dodefineinmargin[#name][#location][#align][#settings]% not completely compatible +% {\definemargindata[#name][\c!location=#location,\c!align=#align,#settings]% +% \definemarginframed[#name][#location][\c!align=#align,#settings]} +% +% \let\setupinmargin\setupmargindata +% +% The following is too dangerous: +% +% \unexpanded\def\setupinmargin +% {\dodoubleempty\dosetupinmargin} +% +% \def\dosetupinmargin[#1][#2]% +% {\ifsecondargument +% \processcommalist[#1]{\dodosetupinmargin[#2]}% +% \else +% \setupmargindata [#1]% beware, here we can have clashes, so +% \setupmarginframed[#1]% don't use setupinmargin any more +% \fi} +% +% \def\dodosetupinmargin[#1]#2% [settings]{class} +% {\setupmargindata[#2][#1]% +% \setupmargintext[#2][#1]} + +\protect \endinput |