summaryrefslogtreecommitdiff
path: root/tex/context/base/typo-mar.mkiv
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2011-02-25 23:40:24 +0200
committerMarius <mariausol@gmail.com>2011-02-25 23:40:24 +0200
commit2a9554684f61df8db63dec6d4e874f49b25a212b (patch)
treefcfd079187ab1f1969351bcafffdfed837b43b33 /tex/context/base/typo-mar.mkiv
parent3880c6aa8cef3b379b06777c09f9ce3e7e61f493 (diff)
downloadcontext-2a9554684f61df8db63dec6d4e874f49b25a212b.tar.gz
beta 2011.02.25 22:03
Diffstat (limited to 'tex/context/base/typo-mar.mkiv')
-rw-r--r--tex/context/base/typo-mar.mkiv351
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