%D \module %D [ file=core-env, % was core-new %D version=1995.01.01, % wrong %D title=\CONTEXT\ Core Macros, %D subtitle=New ones, %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 Core Macros / Environments} \unprotect % Clean labels: \bgroup % some day this will go away / we could use detokenize as well % actually we should handle all discretionaries here \catcode`:=\@@active \gdef\cleanuplabel#1% {\begingroup \let:\lettercolon \xdef\cleanlabel{#1}% \endgroup} \gdef\cleanupprefixedlabel#1#2% {\begingroup \let:\lettercolon \xdef\cleanprefix{#1}% \xdef\cleanlabel {#2}% \endgroup} \gdef\protectlabels {\let:\lettercolon} \global\def\blabelgroup {\begingroup \let:\lettercolon} \global\let\elabelgroup \endgroup \gdef\labelcsname {\begingroup\let:\lettercolon \expandafter\endgroup\csname} \gdef\labelvalue#1% {\labelcsname#1\endcsname} \egroup %D Modes: %D %D \starttyping %D \enablemode[screen,paper,bound] %D %D \doifmodeelse {paper} {this} {that} %D \doifmode {paper,screen} {this} %D \doifnotmode {paper,bound} {that} %D %D \startmode [list] %D \stopmode %D %D \startnotmode [list] %D \stopnotmode %D \stoptyping %D %D system modes have a * as prefix %D %D Sometimes, we want to prevent a mode for being set. Think %D of situations where a style enables a mode, but an outer %D level style does not want that. Preventing can be %D considered a permanent disabling on forehand. \def\@mode@{@md@} \def\systemmodeprefix{*} \def\disabledmode {0} \def\enabledmode {1} \def\preventedmode {2} % fast internal ones \def\setmode #1{\@EA\let\csname\@mode@#1\endcsname\enabledmode } \def\resetmode#1{\@EA\let\csname\@mode@#1\endcsname\disabledmode} \def\setsystemmode #1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\enabledmode } \def\resetsystemmode#1{\@EA\let\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode} % user ones \def\preventmode{\unprotect\dopreventmode} \def\enablemode {\unprotect\doenablemode } \def\disablemode{\unprotect\dodisablemode} \def\dopreventmode[#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dodopreventmode} \def\doenablemode [#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dodoenablemode } \def\dodisablemode[#1]{\protect\cleanuplabel{#1}\rawprocesscommalist[\cleanlabel]\dododisablemode} \def\dodopreventmode#1% {\@EA\let\csname\@mode@#1\endcsname\preventedmode} \def\dodoenablemode#1% mode can be relax {\ifcase0\csname\@mode@#1\endcsname\relax \@EA\let\csname\@mode@#1\endcsname\enabledmode \fi} \def\dododisablemode#1% {\ifcase0\csname\@mode@#1\endcsname\or \@EA\let\csname\@mode@#1\endcsname\disabledmode \fi} % handy for mp \def\booleanmodevalue#1% can be \relax {\expandafter\ifx\csname\@mode@#1\endcsname\relax fals% \else\ifnum0\csname\@mode@#1\endcsname=0 fals% \else tru% \fi\fi e} % check macros \newif\ifcheckedmode \def\dodocheckformode#1% {\ifcase0\csname\@mode@#1\endcsname\or\checkedmodetrue\fi} \def\docheckformode#1#2#3% will be sped up with a quit {\cleanuplabel{#3}% \protect\checkedmodefalse\rawprocesscommacommand[\cleanlabel]\dodocheckformode \ifcheckedmode\@EA#1\else\@EA#2\fi} \def\dodocheckforallmodes#1% {\ifcase0\csname\@mode@#1\endcsname\relax\checkedmodefalse\or\or\checkedmodefalse\fi} \def\docheckforallmodes#1#2#3% will be sped up with a quit {\cleanuplabel{#3}% \protect\checkedmodetrue\rawprocesscommacommand[\cleanlabel]\dodocheckforallmodes \ifcheckedmode\@EA#1\else\@EA#2\fi} % simple ones \def\doifmodeelse{\unprotect\dodoifmodeelse} \def\doifmode {\unprotect\dodoifmode} \def\doifnotmode {\unprotect\dodoifnotmode} \def\startmode {\unprotect\dostartmode} \def\startnotmode{\unprotect\dostartnotmode} \def\dodoifmodeelse {\docheckformode\firstoftwoarguments\secondoftwoarguments} \def\dodoifmode {\docheckformode\firstofoneargument\gobbleoneargument} \def\dodoifnotmode {\docheckformode\gobbleoneargument\firstofoneargument} \long\def\dostartmode[#1]% {\docheckformode\donothing\dostopmode{#1}} \long\def\dostartnotmode[#1]% {\docheckformode\dostopnotmode\donothing{#1}} \let\stopmode \donothing \let\stopnotmode\donothing \long\def\dostopmode #1\stopmode {} \long\def\dostopnotmode#1\stopnotmode{} \def\doifallmodeselse{\unprotect\dodoifallmodeselse} \def\doifallmodes {\unprotect\dodoifallmodes} \def\doifnotallmodes {\unprotect\dodoifnotallmodes} \def\startallmodes {\unprotect\dostartallmodes} \def\startnotallmodes{\unprotect\dostartnotallmodes} \def\dodoifallmodeselse {\docheckforallmodes\firstoftwoarguments\secondoftwoarguments} \def\dodoifallmodes {\docheckforallmodes\firstofoneargument\gobbleoneargument} \def\dodoifnotallmodes {\docheckforallmodes\gobbleoneargument\firstofoneargument} \long\def\dostartallmodes[#1]% {\docheckforallmodes\donothing\dostopallmodes{#1}} \long\def\dostartnotallmodes[#1]% {\docheckforallmodes\dostopnotallmodes\donothing{#1}} \let\stopallmodes \donothing \let\stopnotallmodes\donothing \long\def\dostopallmodes #1\stopallmodes {} \long\def\dostopnotallmodes#1\stopnotallmodes{} % Setups \let\startsetups\relax % to please dep checker \let\stopsetups \relax % to please dep checker \expanded {\long\def\@EA\noexpand\csname\e!start\v!setups\endcsname {\begingroup\noexpand\doifnextoptionalelse {\noexpand\startsetupsA\@EA\noexpand\csname\e!stop\v!setups\endcsname} {\noexpand\startsetupsB\@EA\noexpand\csname\e!stop\v!setups\endcsname}}} \letvalue{\e!stop\v!setups}\relax \unexpanded \def\setups{\doifnextbgroupelse\dosetupsA\dosetupsB} % {..} or [..] \unexpanded \def\setup {\doifnextbgroupelse\dosetups \dosetupsC} % {..} or [..] \def\dosetupsA #1{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % {..} \def\dosetupsB[#1]{\cleanuplabel{#1}\processcommacommand[\cleanlabel]\dosetups} % [..] \def\dosetupsC[#1]{\cleanuplabel{#1}\dosetups\cleanlabel} % [..] % \def\dosetups#1% the grid option will be extended to other main modes % {\executeifdefined{\??su\ifgridsnapping\v!grid\fi:#1} % {\executeifdefined{\??su :#1}\gobbleoneargument}\empty} % takes one argument % % \def\setupwithargument#1% the grid option will be extended to other main modes % {\executeifdefined{\??su:#1}\gobbleoneargument} % better: % \def\dosetups#1% the grid option will be extended to other main modes % {\executeifdefined{\??su\ifgridsnapping\v!grid\fi:#1} % {\executeifdefined{\??su :#1}\gobbleoneargument}\empty} % takes one argument % % \def\setupwithargument#1% the grid option will be extended to other main modes % {\executeifdefined{\??su:#1}\gobbleoneargument} % faster: \letvalue{\??su:\letterpercent}\gobbleoneargument \def\dosetups#1% the grid option will be extended to other main modes {\csname\??su \ifgridsnapping \ifcsname\??su\v!grid:#1\endcsname\v!grid:#1\else\ifcsname\??su:#1\endcsname:#1\else:\letterpercent\fi\fi \else \ifcsname\??su:#1\endcsname:#1\else:\letterpercent\fi \fi \endcsname\empty} % takes one argument \def\setupwithargument#1% the grid option will be extended to other main modes {\csname\??su:\ifcsname\??su:#1\endcsname#1\else\letterpercent\fi\endcsname} \let\directsetup\dosetups % somehow fails ... % % \letvalue{\??su:..}\gobbleoneargument % % \def\dosetups#1% the grid option will be extended to other main modes % {\csname \??su % \ifcsname\??su\ifgridsnapping\v!grid\fi:#1\endcsname\v!grid:#1\else % \ifcsname\??su :#1\endcsname :#1\else % :..\fi\fi % \endcsname\empty} % takes one argument % % \def\setupwithargument#1% the grid option will be extended to other main modes % {\csname\??su:\ifcsname\??su:#1\endcsname#1\else..\fi\endcsname} \let\directsetup\dosetups \def\doifsetupselse#1% to be done: grid {\doifdefinedelse{\??su:#1}} \chardef\setupseolmode\plusone \def\startsetups {\xxstartsetups\plusone \stopsetups } \let\stopsetups \relax \def\startlocalsetups{\xxstartsetups\plusone \stoplocalsetups} \let\stoplocalsetups\relax \def\startrawsetups {\xxstartsetups\zerocount\stoprawsetups } \let\stoprawsetups \relax \def\startxmlsetups {\xxstartsetups\plustwo \stopxmlsetups } \let\stopxmlsetups \relax \def\xxstartsetups#1#2% {\begingroup\chardef\setupseolmode#1\doifnextoptionalelse{\startsetupsA#2}{\startsetupsB#2}} \def\startsetupsA#1% [ ] delimited {\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi \dotripleempty\dostartsetups[#1]} \def\startsetupsB#1#2 % space delimited {\ifcase\setupseolmode\or\catcode`\^^M\@@ignore\or\catcode`\^^M\@@ignore\catcode`\|\@@other\fi \dodostartsetups#1\empty{#2}} \def\startsetupsC[#1][#2][#3]{\dodostartsetups#1{#2}{#3}} % [..] [..] \def\startsetupsD[#1][#2][#3]{\dodostartsetups#1\empty{#2}} % [..] \def\dostartsetups {\ifthirdargument\@EA\startsetupsC\else\@EA\startsetupsD\fi} % \long\def\dodostartsetups#1#2#3% watch out: not \grabuntil % {\dograbuntil#1{\endgroup\dodoglobal\long\setvalue{\??su#2:#3}}} % \doglobal % % better: % \long\def\dodostartsetups#1#2#3% watch out: not \grabuntil % {\cleanuplabel{\??su#2:#3}\dograbuntil#1{\endgroup\dodoglobal\long\setvalue\cleanlabel}} % \doglobal % \long\def\dodostartsetups#1#2#3% % {\cleanuplabel{\??su#2:#3}% % \long\def\dododostartsetups##1#1{\endgroup\dodoglobal\long\setvalue\cleanlabel####1{##1}}\dododostartsetups} \long\def\dodostartsetups#1#2#3% {\cleanuplabel{\??su#2:#3}% \long\def\dododostartsetups##1#1% {\endgroup \dodoglobal % bah \long\expandafter\setvalue\expandafter\cleanlabel\expandafter####\expandafter1\expandafter{##1}}% \dododostartsetups\empty} % the empty trick prevents the { } in {arg} from being eaten up \def\systemsetupsprefix{*} \def\systemsetups#1{\dosetups{\systemsetupsprefix#1}} \def\resetsetups[#1]% see x-fo for usage {\ifundefined{\??su\ifgridsnapping\v!grid\fi:#1}% \dodoglobal\letbeundefined{\??su:#1}% \else \dodoglobal\letbeundefined{\??su\ifgridsnapping\v!grid\fi:#1}% \fi} % or % % \def\resetsetups[#1]% % {\letbeundefined % {\??su:% % \ifundefined{\??su\ifgridsnapping\v!grid\fi:#1}#1\else\ifgridsnapping\v!grid\fi% % #1}} %D new and beta and will become a module instead \def\defineshortcut {\dotripleargument\dodefineshortcut} \def\dodefineshortcut[#1][#2][#3]% {\ifthirdargument \doifelsenothing{#1} {\dododefineshortcut[<>][#2][#3]} {\dododefineshortcut[#1][#2][#3]}% \else\ifsecondargument \dododefineshortcut[<>][#1][#2]% \else \dododefineshortcut[<>][][#1]% \fi\fi} \def\dododefineshortcut[#1#2][#3][#4]% #1 is the trigger, #2 the delimiter/tag {\doifundefined{\??te\??te\string#2}{\letvalue{\??te\??te\string#2}=#1}% \defineactivecharacter #1 {\@EA\doshortcut\string#2} % \getparameters [\??te\string#2#3] [\c!commands=,\c!command=,\c!style=,\c!color=,#4]} \def\doshortcut#1% {\ifmmode \getvalue{\??te\??te#1}% \else \bgroup \catcode`#1=\@@other \def\dodoshortcut##1#1% {\def\shorttag{\??te#1}% \def\shortcut{##1}% \dododoshortcut##1:\end}% \@EA\dodoshortcut \fi} \def\dododoshortcut#1:#2\end {\doifelsenothing{#2} {\doifundefinedelse{\shorttag\c!commands} {\shortcut} {\@EA\dodododoshortcut\@EA\shorttag\@EA:\shortcut:\end}} {\doifundefinedelse{\shorttag#1\c!commands} {\shortcut} {\dodododoshortcut\shorttag#1:#2\end}}% \egroup} \def\dodododoshortcut#1:#2:\end {\getvalue{#1\c!commands}% \doattributes{#1}\c!style\c!color{\getvalue{#1\c!command}{#2}}} %D \defineshortcut [style=type] %D \defineshortcut [b] [style=bold] %D \defineshortcut [e] [style=\em] %D \defineshortcut [t] [style=type] %D \defineshortcut [c] [style=cap] %D \defineshortcut [k] [style=cap] %D \defineshortcut [u] [style=type,command=\hyphenatedurl] %D %D \startlines %D test test %D test test %D test test %D test test %D zus<>zo zus<:>zo zus<::>zo %D test test dat (ziezo) %D test test dat (:ziezo) %D test test dat (ziezo:) %D test test dat (zi:ezo:) %D well, looks fuzzy %D $10<20$ %D \stoplines %D %D \defineshortcut [<>] [i] [style=\it] %D \defineshortcut [()] [b] [style=\bf] %D \defineshortcut [++] [s] [style=\sl] %D \defineshortcut [//] [u] [style=\underbars] %D \defineshortcut [--] [a] [style=\overstrike] %D %D \startlines %D it seems well %D it seems (b:to work) well %D it seems +s:to work+ well %D it seems /u:to work/ well %D it seems -a:to work- well %D \stoplines %D \macros %D {setvariables,getvariable,getvariabledefault} %D %D \starttyping %D \setvariables[xx][title=] %D \setvariables[xx][title=test test] %D \setvariables[xx][title=test $x=1$ test] % fatal error reported %D \setvariables[xx][title=test {$x=1$} test] %D \setvariables[xx][title] % fatal error reported %D \setvariables[xx][titletitel=e] %D \stoptyping \def\??vars{@@vars} \def\setvariables {\dotripleargument\dosetvariables[\getrawparameters ]} \def\setevariables{\dotripleargument\dosetvariables[\getraweparameters]} \def\setgvariables{\dotripleargument\dosetvariables[\getrawgparameters]} \def\setxvariables{\dotripleargument\dosetvariables[\getrawxparameters]} \def\globalsetvariables % obsolete {\dotripleargument\dosetvariables[\globalgetrawparameters]} \long\def\dosetvariables[#1][#2][#3]% tricky, test on s-pre-60 {\errorisfataltrue \doifelse{#2}\currentvariableclass {#1[\??vars:#2:][#3]}% {\pushmacro\currentvariableclass \def\currentvariableclass{#2}% \getvariable{#2}\s!reset #1[\??vars:#2:][#3]% \getvariable{#2}\s!set \popmacro\currentvariableclass}% \errorisfatalfalse} \long\def\setvariable #1#2#3{\long\setvalue {\??vars:#1:#2}{#3}} \long\def\setevariable#1#2#3{\long\setevalue{\??vars:#1:#2}{#3}} \long\def\setgvariable#1#2#3{\long\setgvalue{\??vars:#1:#2}{#3}} \long\def\setxvariable#1#2#3{\long\setxvalue{\??vars:#1:#2}{#3}} \def\getvariable#1#2% to be sped up {\csname \ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi \endcsname} \def\showvariable#1#2% {\showvalue{\ifcsname\??vars:#1:#2\endcsname\??vars:#1:#2\else\s!empty\fi}} \let\currentvariableclass\empty %D \macros %D {doifelsevariable,doifvariable,doifnotvariable} %D %D A few trivial macros: \def\doifelsevariable#1#2% {\ifcsname\??vars:#1:#2\endcsname \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} \def\doifvariable#1#2% {\ifcsname\??vars:#1:#2\endcsname \expandafter\firstofoneargument \else \expandafter\gobbleoneargument \fi} \def\doifnotvariable#1#2% {\ifcsname\??vars:#1:#2\endcsname \expandafter\gobbleoneargument \else \expandafter\firstofoneargument \fi} \def\getvariabledefault#1#2% #3% can be command, so no ifcsname here {\executeifdefined{\??vars:#1:#2}}% {#3} %D \macros %D {checkvariables} %D %D I'll probably forget that this on exists. \def\checkvariables {\dodoubleargument\docheckvariables} \def\docheckvariables {\dogetparameters\docheckrawvalue} \def\docheckrawvalue#1#2#3% {\doifundefined {\??vars:#1:#2}{\setvalue{\??vars:#1:#2}{#3}} {\doifvaluenothing{\??vars:#1:#2}{\setvalue{\??vars:#1:#2}{#3}}}} % \def\setupenv{\dodoubleargument\rawgetparameters[\??en]} % % \def\doifenvelse#1{\doifdefinedelse{\??en#1}} % speed up % \def\doifenv #1{\doifdefined {\??en#1}} % speed up % \def\doifnotenv #1{\doifundefined {\??en#1}} % speed up % % \def\env#1{\csname\??en#1\endcsname} % % \def\envvar#1#2% % {\ifcsname\??en#1\endcsname % \csname\??en#1\endcsname\else#2% % \fi} % low level change, now also accessible as \getvariable{environment}{...}; the % next macros will become obsolete some day in favor of normal variables \def\s!environment{environment} \def\setupenv {\dotripleargument\dosetvariables[\getrawparameters][\s!environment]} \def\doifenvelse{\doifelsevariable \s!environment} \def\doifenv {\doifvariable \s!environment} \def\doifnotenv {\doifnotvariable \s!environment} \def\env {\getvariable \s!environment} \def\envvar {\getvariabledefault\s!environment} \protect \endinput