%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 / Hans Hagen \& Ton Otten}] %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} \registerctxluafile{core-env}{1.001} \unprotect %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\@mode@{mode} \def\systemmodeprefix{*} % todo: check prevent mode, also at the lua end \setnewconstant\disabledmode \zerocount \setnewconstant\enabledmode \plusone \setnewconstant\preventedmode\plustwo % fast internal ones \def\donewmode#1% {\@EA\newcount\csname\@mode@#1\endcsname} \def\newmode#1% {\ifcsname\@mode@#1\endcsname\else\donewmode{#1}\fi} \def\setmode#1% {\ifcsname\@mode@#1\endcsname\else\donewmode{#1}\fi \csname\@mode@#1\endcsname\enabledmode} \def\resetmode#1% {\ifcsname\@mode@#1\endcsname\else\donewmode{#1}\fi \csname\@mode@#1\endcsname\disabledmode} \def\newsystemmode#1% {\ifcsname\@mode@\systemmodeprefix#1\endcsname\else\donewmode{\systemmodeprefix#1}\fi} \def\setsystemmode#1% {\ifcsname\@mode@\systemmodeprefix#1\endcsname\else\donewmode{\systemmodeprefix#1}\fi \csname\@mode@\systemmodeprefix#1\endcsname\enabledmode} \def\resetsystemmode#1% {\ifcsname\@mode@\systemmodeprefix#1\endcsname\else\donewmode{\systemmodeprefix#1}\fi \csname\@mode@\systemmodeprefix#1\endcsname\disabledmode} % \def\dosetsystemmode#1% % {\csname\@mode@\systemmodeprefix#1\endcsname\enabledmode} % % \def\doresetsystemmode#1% % {\csname\@mode@\systemmodeprefix#1\endcsname\disabledmode} % demo: trialtypesetting is a systemmode as well as an if \newsystemmode{trialtypesetting} \expandafter\let\expandafter\@@trialtypesetting\csname\@mode@\systemmodeprefix trialtypesetting\endcsname % private ! \appendtoks \@@trialtypesetting\enabledmode \to \everysettrialtypesetting \appendtoks \@@trialtypesetting\disabledmode \to \everyresettrialtypesetting % user ones \unexpanded\def\preventmode{\unprotect\dopreventmode} \unexpanded\def\enablemode {\unprotect\doenablemode } \unexpanded\def\disablemode{\unprotect\dodisablemode} \let\definemode\disablemode % nicer \def\dopreventmode[#1]{\protect\rawprocesscommacommand[#1]\dodopreventmode} \def\doenablemode [#1]{\protect\rawprocesscommacommand[#1]\dodoenablemode } \def\dodisablemode[#1]{\protect\rawprocesscommacommand[#1]\dododisablemode} \def\dodopreventmode#1% {\ifcsname\@mode@#1\endcsname\else\donewmode{#1}\fi \csname\@mode@#1\endcsname\preventedmode} \def\dodoenablemode#1% we can speed it up by moving the new outside {\ifcsname\@mode@#1\endcsname\else\donewmode{#1}\fi \ifnum\csname\@mode@#1\endcsname=\preventedmode \else \csname\@mode@#1\endcsname\enabledmode \fi} \def\dododisablemode#1% {\ifcsname\@mode@#1\endcsname\else\donewmode{#1}\fi \ifnum\csname\@mode@#1\endcsname=\preventedmode \else \csname\@mode@#1\endcsname\disabledmode \fi} % handy for mp \def\booleanmodevalue#1% {\ifcsname\@mode@#1\endcsname\ifcase\csname\@mode@#1\endcsname fals\else tru\fi\else fals\fi e} % check macros \newif\ifcheckedmode \def\dodocheckformode#1% {\ifcsname\@mode@#1\endcsname\ifcase\csname\@mode@#1\endcsname\else\checkedmodetrue\fi\fi} \def\docheckformode#1#2#3% will be sped up with a quit {\protect\checkedmodefalse\rawprocesscommacommand[#3]\dodocheckformode \ifcheckedmode\@EA#1\else\@EA#2\fi} \def\dodocheckforallmodes#1% {\ifcsname\@mode@#1\endcsname\ifcase\csname\@mode@#1\endcsname\checkedmodefalse\fi\else\checkedmodefalse\fi} \def\docheckforallmodes#1#2#3% will be sped up with a quit {\protect\checkedmodetrue\rawprocesscommacommand[#3]\dodocheckforallmodes \ifcheckedmode\@EA#1\else\@EA#2\fi} % simple ones \unexpanded\def\doifmodeelse{\unprotect\dodoifmodeelse} \unexpanded\def\doifmode {\unprotect\dodoifmode} \unexpanded\def\doifnotmode {\unprotect\dodoifnotmode} \unexpanded\def\startmode {\unprotect\dostartmode} \unexpanded\def\startnotmode{\unprotect\dostartnotmode} \def\dodoifmodeelse {\docheckformode\firstoftwoarguments\secondoftwoarguments} \def\dodoifmode {\docheckformode\firstofoneargument\gobbleoneargument} \def\dodoifnotmode {\docheckformode\gobbleoneargument\firstofoneargument} \long\unexpanded\def\dostartmode[#1]% {\docheckformode\donothing\dostopmode{#1}} \long\def\dostartnotmode[#1]% {\docheckformode\dostopnotmode\donothing{#1}} \unexpanded\def\stopmode {} % no relax \unexpanded\def\stopnotmode{} % no relax \long\def\dostopmode #1\stopmode {} \long\def\dostopnotmode#1\stopnotmode{} \unexpanded\def\doifallmodeselse{\unprotect\dodoifallmodeselse} \unexpanded\def\doifallmodes {\unprotect\dodoifallmodes} \unexpanded\def\doifnotallmodes {\unprotect\dodoifnotallmodes} \unexpanded\def\startallmodes {\unprotect\dostartallmodes} \unexpanded\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}} \unexpanded\def\stopallmodes {} % no relax \unexpanded\def\stopnotallmodes{} % no relax \long\def\dostopallmodes #1\stopallmodes {} \long\def\dostopnotallmodes#1\stopnotallmodes{} %D Lets now set a mode: \enablemode[mkiv] \newsystemmode{mkiv} \setsystemmode{mkiv} %D Setups: \unexpanded\def\startsetups{} % to please dep checker \unexpanded\def\stopsetups {} % to please dep checker \expanded % will become obsolete {\long\def\@EA\noexpand\csname\e!start\v!setups\endcsname {\begingroup\noexpand\doifnextoptionalelse {\noexpand\dostartsetupsA\@EA\noexpand\csname\e!stop\v!setups\endcsname} {\noexpand\dostartsetupsB\@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{\processcommacommand[#1]\dosetups} % {..} \def\dosetupsB[#1]{\processcommacommand[#1]\dosetups} % [..] \def\dosetupsC[#1]{\dosetups{#1}} % [..] \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 % We can consider: % % \setvalue{\??su->\v!auto}#1{\ctxcommand{autosetup("#1")}} % % ":\letterpercent" => "->\v!auto" with "\endcsname{#1}" % % but it won't work out well with multiple setups (intercepted at the % lua end) that then get only one argument. % the next one is meant for \c!setups situations, hence the check for % a shortcut \def\doprocesslocalsetups#1% {\edef\tobeprocessedsetups{#1}% \ifx\tobeprocessedsetups\empty\else \dodoprocesslocalsetups \fi} % \def\dodoprocesslocalsetups % {\@EA\processcommalist\@EA[\tobeprocessedsetups]\dosetups} % setups=S1 % setups=lua(S2) % setups=S3 % setups={S1,lua(S2),xml(test{123}),S3} \def\dodoprocesslocalsetups {\ctxcommand{autosetups("\tobeprocessedsetups")}} \def\autosetups#1% {\ctxcommand{autosetups("#1")}} \edef\setupwithargument#1% saves a few expansions {\noexpand\csname\??su:\noexpand\ifcsname\??su:#1\endcsname#1\noexpand\else\letterpercent\noexpand\fi\endcsname} \let\directsetup\dosetups \let\texsetup \dosetups % nicer than \directsetup and more en par with xmlsetup and luasetup \def\doifsetupselse#1% to be done: grid {\doifdefinedelse{\??su:#1}} % doto: ifcsname % \startluasetups oeps % tex.print("DONE") % a = 1 % b = 1 % \stopluasetups % % \luasetup{oeps} % % \startsetups xxx % ziezo % \stopsetups % % \directsetup{xxx} % % \startxmlsetups zzz % [[#1]] % \stopxmlsetups % % \xmlsetup{123}{zzz} % % \startbuffer[what] % tex.print("DONE") % \stopbuffer % % \startbuffer % tex.print("MORE") % \stopbuffer % % \ctxluabuffer[what] % % \ctxluabuffer \newtoks\everydefinesetups \appendtoks \catcode\endoflineasciicode \ignorecatcode \to \everydefinesetups \newtoks\everydefinelocalsetups \appendtoks \catcode\endoflineasciicode \ignorecatcode \to \everydefinelocalsetups \newtoks\everydefinerawsetups \appendtoks % nothing \to \everydefinerawsetups \newtoks\everydefinexmlsetups \appendtoks \catcode\endoflineasciicode\ignorecatcode \catcode\barasciicode \othercatcode \to \everydefinexmlsetups \newtoks\everydefineluasetups \appendtoks \obeylualines \obeyluatokens \to \everydefineluasetups \unexpanded\def\startluasetups {\begingroup\doifnextoptionalelse\dostartluasetupsA \dostartluasetupsB } \unexpanded\def\startxmlsetups {\begingroup\doifnextoptionalelse\dostartxmlsetupsA \dostartxmlsetupsB } \unexpanded\def\startrawsetups {\begingroup\doifnextoptionalelse\dostartrawsetupsA \dostartrawsetupsB } \unexpanded\def\startlocalsetups{\begingroup\doifnextoptionalelse\dostartlocalsetupsA\dostartlocalsetupsB} \unexpanded\def\startsetups {\begingroup\doifnextoptionalelse\dostartsetupsA \dostartsetupsB } \let\stopluasetups \relax \let\stopxmlsetups \relax \let\stoprawsetups \relax \let\stoplocalsetups \relax \let\stopsetups \relax \def\dodostartluasetups #1#2#3\stopluasetups {\endgroup\dodoglobal\long\@EA\def\csname\??su#1:#2\@EA\endcsname\@EA##\@EA1\@EA{#3}} \def\dodostartxmlsetups #1#2#3\stopxmlsetups {\endgroup\dodoglobal\long\@EA\def\csname\??su#1:#2\@EA\endcsname\@EA##\@EA1\@EA{#3}} \def\dodostartrawsetups #1#2#3\stoprawsetups {\endgroup\dodoglobal\long\@EA\def\csname\??su#1:#2\@EA\endcsname\@EA##\@EA1\@EA{#3}} \def\dodostartlocalsetups #1#2#3\stoplocalsetups{\endgroup\dodoglobal\long\@EA\def\csname\??su#1:#2\@EA\endcsname\@EA##\@EA1\@EA{#3}} \def\dodostartsetups #1#2#3\stopsetups {\endgroup\dodoglobal\long\@EA\def\csname\??su#1:#2\@EA\endcsname\@EA##\@EA1\@EA{#3}} \def\dostartluasetups {\ifsecondargument\@EA\dostartluasetupsC \else\@EA\dostartluasetupsD \fi} \def\dostartxmlsetups {\ifsecondargument\@EA\dostartxmlsetupsC \else\@EA\dostartxmlsetupsD \fi} \def\dostartrawsetups {\ifsecondargument\@EA\dostartrawsetupsC \else\@EA\dostartrawsetupsD \fi} \def\dostartlocalsetups {\ifsecondargument\@EA\dostartlocalsetupsC\else\@EA\dostartlocalsetupsD\fi} \def\dostartsetups {\ifsecondargument\@EA\dostartsetupsC \else\@EA\dostartsetupsD \fi} \def\dostartluasetupsA {\the\everydefineluasetups \dodoubleempty\dostartluasetups} % [ ] delimited \def\dostartxmlsetupsA {\the\everydefinexmlsetups \dodoubleempty\dostartxmlsetups} % [ ] delimited \def\dostartrawsetupsA {\the\everydefinerawsetups \dodoubleempty\dostartrawsetups} % [ ] delimited \def\dostartlocalsetupsA {\the\everydefinelocalsetups\dodoubleempty\dostartlocalsetups} % [ ] delimited \def\dostartsetupsA {\the\everydefinesetups \dodoubleempty\dostartsetups} % [ ] delimited % empty preserves inner {} (is removed by the \@EA{#3}) \def\dostartluasetupsB #1 {\the\everydefineluasetups \dodostartluasetups \empty{#1}\empty} % space delimited \def\dostartxmlsetupsB #1 {\the\everydefinexmlsetups \dodostartxmlsetups \empty{#1}\empty} % space delimited \def\dostartrawsetupsB #1 {\the\everydefinerawsetups \dodostartrawsetups \empty{#1}\empty} % space delimited \def\dostartlocalsetupsB #1 {\the\everydefinelocalsetups\dodostartlocalsetups\empty{#1}\empty} % space delimited \def\dostartsetupsB #1 {\the\everydefinesetups \dodostartsetups \empty{#1}\empty} % space delimited \def\dostartluasetupsC [#1][#2]{\the\everydefineluasetups \dodostartluasetups {#1}{#2}\empty} % [..] [..] \def\dostartxmlsetupsC [#1][#2]{\the\everydefinexmlsetups \dodostartxmlsetups {#1}{#2}\empty} % [..] [..] \def\dostartrawsetupsC [#1][#2]{\the\everydefinerawsetups \dodostartrawsetups {#1}{#2}\empty} % [..] [..] \def\dostartlocalsetupsC[#1][#2]{\the\everydefinelocalsetups\dodostartlocalsetups{#1}{#2}\empty} % [..] [..] \def\dostartsetupsC [#1][#2]{\the\everydefinesetups \dodostartsetups {#1}{#2}\empty} % [..] [..] \def\dostartluasetupsD [#1][#2]{\the\everydefineluasetups \dodostartluasetups \empty{#1}\empty} % [..] \def\dostartxmlsetupsD [#1][#2]{\the\everydefinexmlsetups \dodostartxmlsetups \empty{#1}\empty} % [..] \def\dostartrawsetupsD [#1][#2]{\the\everydefinerawsetups \dodostartrawsetups \empty{#1}\empty} % [..] \def\dostartlocalsetupsD[#1][#2]{\the\everydefinelocalsetups\dodostartlocalsetups\empty{#1}\empty} % [..] \def\dostartsetupsD [#1][#2]{\the\everydefinesetups \dodostartsetups \empty{#1}\empty} % [..] \def\luasetup#1{\ctxlua{\dosetups{#1}}} % % % % \def\systemsetupsprefix{*} \def\systemsetups#1{\dosetups{\systemsetupsprefix#1}} \def\resetsetups[#1]% see x-fo for usage {\ifcsname\??su\ifgridsnapping\v!grid\fi:#1\endcsname \dodoglobal\letbeundefined{\??su\ifgridsnapping\v!grid\fi:#1}% \else \dodoglobal\letbeundefined{\??su:#1}% \fi} %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\expandafter\def \csname\??vars:#1:#2\endcsname{#3}} \long\def\setevariable#1#2#3{\long\expandafter\edef\csname\??vars:#1:#2\endcsname{#3}} \long\def\setgvariable#1#2#3{\long\expandafter\gdef\csname\??vars:#1:#2\endcsname{#3}} \long\def\setxvariable#1#2#3{\long\expandafter\xdef\csname\??vars:#1:#2\endcsname{#3}} \def\getvariable#1#2% {\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 {checkvariables} %D %D I'll probably forget that this on exists. \def\checkvariables {\dodoubleargument\docheckvariables} \def\docheckvariables {\dogetparameters\docheckrawvalue} \long\def\docheckrawvalue#1#2#3% {\ifcsname\??vars:#1:#2\endcsname \edef\checkedrawvalue{\csname\??vars:#1:#2\endcsname}% \ifx\checkedrawvalue\empty \long\expandafter\def\csname\??vars:#1:#2\endcsname{#3}% \fi \else \long\expandafter\def\csname\??vars:#1:#2\endcsname{#3}% \fi} %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} % \unexpanded\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 in the environment % namespace \def\s!environment{environment} \unexpanded\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