summaryrefslogtreecommitdiff
path: root/tex/context/base/core-env.mkiv
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/core-env.mkiv')
-rw-r--r--tex/context/base/core-env.mkiv253
1 files changed, 206 insertions, 47 deletions
diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv
index 1c92a371c..bebc1bef0 100644
--- a/tex/context/base/core-env.mkiv
+++ b/tex/context/base/core-env.mkiv
@@ -46,8 +46,6 @@
\installcorenamespace{modestack}
-% todo: check prevent mode, also at the lua end
-
\setnewconstant\disabledmode \zerocount
\setnewconstant\enabledmode \plusone
\setnewconstant\preventedmode\plustwo
@@ -59,7 +57,7 @@
\def\syst_modes_new#1%
{\expandafter\newcount\csname\??mode#1\endcsname}
-\unexpanded\def\newmode#1%
+\unexpanded\def\newmode#1% so, no change of already set modes !
{\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi}
\unexpanded\def\setmode#1%
@@ -113,8 +111,6 @@
\unexpanded\def\globalenablemode {\let\syst_mode_prefix\global\unprotect\syst_modes_enable }
\unexpanded\def\globaldisablemode{\let\syst_mode_prefix\global\unprotect\syst_modes_disable}
-\let\definemode\disablemode % nicer
-
\def\syst_modes_prevent[#1]{\protect\rawprocesscommacommand[#1]\syst_modes_prevent_indeed\let\syst_mode_prefix\relax}
\def\syst_modes_enable [#1]{\protect\rawprocesscommacommand[#1]\syst_modes_enable_indeed \let\syst_mode_prefix\relax}
\def\syst_modes_disable[#1]{\protect\rawprocesscommacommand[#1]\syst_modes_disable_indeed\let\syst_mode_prefix\relax}
@@ -135,10 +131,47 @@
\syst_mode_prefix\csname\??mode#1\endcsname\disabledmode
\fi}
+%D If you do a lot of mode testing, it makes sense to define modes (or disable them
+%D explicitly if unset. This makes testing twice as fast. Often one enables modes
+%D beforehand, in which case \type {\definemode} would reset the mode. The optional
+%D second argument \type {keep} will prevent changing the already set mode but defines
+%D it when undefined.
+
+\unexpanded\def\definemode
+ {\unprotect
+ \dodoubleempty\syst_modes_define}
+
+\def\syst_modes_define[#1][#2]%
+ {\protect
+ \edef\m_modes_asked{#2}%
+ \rawprocesscommacommand[#1]\syst_modes_define_indeed}
+
+\def\syst_modes_define_indeed#1%
+ {\ifcsname\??mode#1\endcsname
+ % already set
+ \else
+ \syst_modes_new{#1}
+ \fi
+ \ifx\m_modes_asked\v!keep
+ % not changes, disabled when undefined
+ \else
+ \csname\??mode#1\endcsname\ifx\m_modes_asked\v!yes\enabledmode\else\disabledmode\fi
+ \fi}
+
% handy for mp
\def\booleanmodevalue#1%
- {\ifcsname\??mode#1\endcsname\ifcase\csname\??mode#1\endcsname\s!false\else\s!true\fi\else\s!false\fi}
+ {\ifcsname\??mode#1\endcsname
+ \ifcase\csname\??mode#1\endcsname
+ \s!false
+ \or
+ \s!true
+ \else
+ \s!false
+ \fi
+ \else
+ \s!false
+ \fi}
% check macros
@@ -148,6 +181,27 @@
\newconditional\c_checked_mode
+% one
+
+% \def\syst_modes_check_indeed#1%
+% {\ifcsname\??mode#1\endcsname
+% \ifcase\csname\??mode#1\endcsname\else
+% \let\syst_modes_check_step\gobbleoneargument
+% \fi
+% \fi}
+%
+% \def\syst_modes_check#1#2#3%
+% {\let\syst_modes_check_step\syst_modes_check_indeed
+% \rawprocesscommacommand[#3]\syst_modes_check_step
+% \ifx\syst_modes_check_step\gobbleoneargument
+% \expandafter#1%
+% \else
+% \expandafter#2%
+% \fi}
+
+% modes .. twice as fast on defined modes .. we could use definers and make it even faster
+% if needed
+
\def\syst_modes_check_indeed#1%
{\ifcsname\??mode#1\endcsname
\ifcase\csname\??mode#1\endcsname\else
@@ -155,7 +209,7 @@
\fi
\fi}
-\def\syst_modes_check#1#2#3%
+\def\syst_modes_check_nop#1#2#3%
{\let\syst_modes_check_step\syst_modes_check_indeed
\rawprocesscommacommand[#3]\syst_modes_check_step
\ifx\syst_modes_check_step\gobbleoneargument
@@ -164,10 +218,32 @@
\expandafter#2%
\fi}
+\def\syst_modes_check_yes#1#2#3%
+ {\ifcase\csname\??mode#3\endcsname
+ \expandafter#2%
+ \or
+ \expandafter#1%
+ \else
+ \expandafter#2%
+ \fi}
+
+\def\syst_modes_check#1#2#3%
+ {\ifcsname\??mode#3\endcsname
+ \expandafter\syst_modes_check_yes
+ \else
+ \expandafter\syst_modes_check_nop
+ \fi#1#2{#3}}
+
+% all
+
\def\syst_modes_check_all_indeed#1%
{\ifcsname\??mode#1\endcsname
\ifcase\csname\??mode#1\endcsname
\let\syst_modes_check_all_step\gobbleoneargument
+ \or
+ % enabled
+ \else
+ \let\syst_modes_check_all_step\gobbleoneargument
\fi
\else
\let\syst_modes_check_all_step\gobbleoneargument
@@ -182,17 +258,20 @@
\expandafter#1%
\fi}
-\unexpanded\def\doifmodeelse {\syst_modes_check\firstoftwoarguments\secondoftwoarguments}
+\unexpanded\def\doifelsemode {\syst_modes_check\firstoftwoarguments\secondoftwoarguments}
\unexpanded\def\doifmode {\syst_modes_check\firstofoneargument\gobbleoneargument}
\unexpanded\def\doifnotmode {\syst_modes_check\gobbleoneargument\firstofoneargument}
\unexpanded\def\startmode [#1]{\syst_modes_check\donothing\syst_modes_stop_yes{#1}}
\unexpanded\def\startnotmode [#1]{\syst_modes_check\syst_modes_stop_nop\donothing{#1}}
-\unexpanded\def\doifallmodeselse {\syst_modes_check_all\firstoftwoarguments\secondoftwoarguments}
+\unexpanded\def\doifelseallmodes {\syst_modes_check_all\firstoftwoarguments\secondoftwoarguments}
\unexpanded\def\doifallmodes {\syst_modes_check_all\firstofoneargument\gobbleoneargument}
\unexpanded\def\doifnotallmodes {\syst_modes_check_all\gobbleoneargument\firstofoneargument}
\unexpanded\def\startallmodes [#1]{\syst_modes_check_all\donothing\syst_modes_stop_all_yes{#1}}
\unexpanded\def\startnotallmodes[#1]{\syst_modes_check_all\syst_modes_stop_all_nop\donothing{#1}}
+\let\doifmodeelse \doifelsemode
+\let\doifallmodeselse \doifelseallmodes
+
\unexpanded\def\stopmode {} % no relax
\unexpanded\def\stopnotmode {} % no relax
\unexpanded\def\stopallmodes {} % no relax
@@ -232,21 +311,21 @@
%D \starttyping
%D \enablemode[two]
%D
-%D \startmodes
+%D \startmodeset
%D [one] {1}
%D [two] {2}
%D [two] {2}
%D [three] {3}
%D [default] {?}
-%D \stopmodes
+%D \stopmodeset
%D
-%D \startmodes
+%D \startmodeset
%D [one] {1}
%D [three] {3}
%D [default] {?}
-%D \stopmodes
+%D \stopmodeset
%D
-%D \startmodes
+%D \startmodeset
%D [one] {
%D \input tufte
%D }
@@ -265,15 +344,15 @@
%D [default] {
%D \input ward
%D }
-%D \stopmodes
+%D \stopmodeset
%D \stoptyping
\newconditional\c_syst_modes_set_done % conditionals can be pushed/popped
\unexpanded\def\startmodeset
{\pushmacro\c_syst_modes_set_done
- \setfalse\conditionalfalse
- \doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit}
+ \setfalse\c_syst_modes_set_done
+ \doifelsenextoptionalcs\syst_modes_set_start\syst_modes_set_quit}
\def\syst_modes_set_start[#1]%
{\edef\m_mode_case{#1}%
@@ -293,10 +372,10 @@
\def\syst_modes_set_yes#1%
{\settrue\c_syst_modes_set_done
#1%
- \doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit}
+ \doifelsenextoptionalcs\syst_modes_set_start\syst_modes_set_quit}
\def\syst_modes_set_nop#1%
- {\doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit}
+ {\doifelsenextoptionalcs\syst_modes_set_start\syst_modes_set_quit}
\def\syst_modes_set_quit#1\stopmodeset
{\popmacro\c_syst_modes_set_done}
@@ -314,16 +393,16 @@
\unexpanded\def\startsetups{} % to please dep checker
\unexpanded\def\stopsetups {} % to please dep checker
-\expanded % will become obsolete
- {\def\expandafter\noexpand\csname\e!start\v!setups\endcsname
- {\begingroup\noexpand\doifnextoptionalelse
- {\noexpand\dostartsetupsA\expandafter\noexpand\csname\e!stop\v!setups\endcsname}
- {\noexpand\dostartsetupsB\expandafter\noexpand\csname\e!stop\v!setups\endcsname}}}
-
-\letvalue{\e!stop\v!setups}\relax
+% \expanded % will become obsolete
+% {\def\expandafter\noexpand\csname\e!start\v!setups\endcsname
+% {\begingroup\noexpand\doifnextoptionalcselse
+% {\noexpand\dostartsetupsA\expandafter\noexpand\csname\e!stop\v!setups\endcsname}
+% {\noexpand\dostartsetupsB\expandafter\noexpand\csname\e!stop\v!setups\endcsname}}}
+%
+% \letvalue{\e!stop\v!setups}\relax
-\unexpanded\def\setups{\doifnextbgroupelse\syst_setups_a\syst_setups_b} % {..} or [..]
-\unexpanded\def\setup {\doifnextbgroupelse\syst_setups \syst_setups_c} % {..} or [..]
+\unexpanded\def\setups{\doifelsenextbgroup\syst_setups_a\syst_setups_b} % {..} or [..]
+\unexpanded\def\setup {\doifelsenextbgroup\syst_setups \syst_setups_c} % {..} or [..]
\def\syst_setups_a #1{\processcommacommand[#1]\syst_setups} % {..}
\def\syst_setups_b[#1]{\processcommacommand[#1]\syst_setups} % [..]
@@ -331,15 +410,57 @@
\letvalue{\??setup:\letterpercent}\gobbleoneargument
+% \def\syst_setups#1% the grid option will be extended to other main modes
+% {\csname\??setup
+% \ifgridsnapping
+% \ifcsname\??setup\v!grid:#1\endcsname\v!grid:#1\else\ifcsname\??setup:#1\endcsname:#1\else:\letterpercent\fi\fi
+% \else
+% \ifcsname\??setup:#1\endcsname:#1\else:\letterpercent\fi
+% \fi
+% \endcsname\empty} % takes one argument
+
\def\syst_setups#1% the grid option will be extended to other main modes
{\csname\??setup
\ifgridsnapping
- \ifcsname\??setup\v!grid:#1\endcsname\v!grid:#1\else\ifcsname\??setup:#1\endcsname:#1\else:\letterpercent\fi\fi
+ \ifcsname\??setup\v!grid:#1\endcsname\v!grid:#1\else:\ifcsname\??setup:#1\endcsname#1\else\letterpercent\fi\fi
\else
- \ifcsname\??setup:#1\endcsname:#1\else:\letterpercent\fi
+ :\ifcsname\??setup:#1\endcsname#1\else\letterpercent\fi
\fi
\endcsname\empty} % takes one argument
+% not faster but less tracing sometimes:
+%
+% \def\syst_setups% the grid option will be extended to other main modes
+% {\csname\??setup\ifgridsnapping\expandafter\syst_setups_grid\else\expandafter\syst_setups_normal\fi}
+%
+% \def\syst_setups_grid#1%
+% {\ifcsname\??setup\v!grid:#1\endcsname\v!grid:#1\else\ifcsname\??setup:#1\endcsname:#1\else:\letterpercent\fi\fi\endcsname\empty} % takes one argument
+%
+% \def\syst_setups_normal#1%
+% {:\ifcsname\??setup:#1\endcsname#1\else\letterpercent\fi\endcsname\empty} % takes one argument
+%
+% only makes sense with many setups
+%
+% \def\syst_setups% the grid option will be extended to other main modes
+% {\ifgridsnapping
+% \expandafter\syst_setups_grid
+% \else
+% \expandafter\syst_setups_normal
+% \fi}
+%
+% \def\syst_setups_normal#1% the grid option will be extended to other main modes
+% {\csname\??setup
+% :\ifcsname\??setup:#1\endcsname#1\else\letterpercent\fi
+% \endcsname\empty} % takes one argument
+%
+% \def\syst_setups_grid#1% the grid option will be extended to other main modes
+% {\csname\??setup
+% \ifcsname\??setup\v!grid:#1\endcsname\v!grid:#1\else:\ifcsname\??setup:#1\endcsname#1\else\letterpercent\fi\fi
+% \endcsname\empty} % takes one argument
+%
+% \let\directsetup\syst_setups
+% \let\texsetup \syst_setups % nicer than \directsetup and more en par with xmlsetup and luasetup
+
% We can consider:
%
% \setvalue{\??setup->\v!auto}#1{\ctxcommand{autosetup("#1")}}
@@ -349,6 +470,12 @@
% but it won't work out well with multiple setups (intercepted at the
% lua end) that then get only one argument.
+% no checking and we assume it being defined:
+
+\def\fastsetup #1{\csname\??setup:#1\endcsname\empty}
+\def\fastsetupwithargument #1#2{\csname\??setup:#2\endcsname{#1}}
+\def\fastsetupwithargumentswapped #1{\csname\??setup:#1\endcsname}
+
% the next one is meant for \c!setups situations, hence the check for
% a shortcut
@@ -375,11 +502,11 @@
% setups={S1,lua(S2),xml(test{123}),S3}
\def\syst_setups_process_local
- {\ctxcommand{autosetups("\m_syst_setups_asked")}%
+ {\clf_autosetups{\m_syst_setups_asked}%
\relax} % let's prevent lookahead
\def\autosetups#1%
- {\ctxcommand{autosetups("#1")}}
+ {\clf_autosetups{#1}}
\edef\setupwithargument#1% saves a few expansions
{\noexpand\csname\??setup:\noexpand\ifcsname\??setup:#1\endcsname#1\noexpand\else\letterpercent\noexpand\fi\endcsname}
@@ -390,13 +517,15 @@
\let\directsetup\syst_setups
\let\texsetup \syst_setups % nicer than \directsetup and more en par with xmlsetup and luasetup
-\unexpanded\def\doifsetupselse#1% to be done: grid
+\unexpanded\def\doifelsesetups#1% to be done: grid
{\ifcsname\??setup:#1\endcsname
\expandafter\firstoftwoarguments
\else
\expandafter\secondoftwoarguments
\fi}
+\let\doifsetupselse\doifelsesetups
+
\unexpanded\def\doifsetups#1% to be done: grid
{\ifcsname\??setup:#1\endcsname
\expandafter\firstofoneargument
@@ -467,17 +596,11 @@
% Is doglobal still relevant? Maybe always global? Or never? Anyway, it will become obsolete.
-\unexpanded\def\startluasetups {\begingroup\doifnextoptionalelse\syst_setups_start_lua_a\syst_setups_start_lua_b}
-\unexpanded\def\startxmlsetups {\begingroup\doifnextoptionalelse\syst_setups_start_xml_a\syst_setups_start_xml_b}
-\unexpanded\def\startrawsetups {\begingroup\doifnextoptionalelse\syst_setups_start_raw_a\syst_setups_start_raw_b}
-\unexpanded\def\startlocalsetups{\begingroup\doifnextoptionalelse\syst_setups_start_loc_a\syst_setups_start_loc_b}
-\unexpanded\def\startsetups {\begingroup\doifnextoptionalelse\syst_setups_start_tex_a\syst_setups_start_tex_b}
-
-\let\stopluasetups \relax
-\let\stopxmlsetups \relax
-\let\stoprawsetups \relax
-\let\stoplocalsetups \relax
-\let\stopsetups \relax
+\unexpanded\def\startluasetups {\begingroup\doifelsenextoptionalcs\syst_setups_start_lua_a\syst_setups_start_lua_b} \let\stopluasetups \relax
+\unexpanded\def\startxmlsetups {\begingroup\doifelsenextoptionalcs\syst_setups_start_xml_a\syst_setups_start_xml_b} \let\stopxmlsetups \relax
+\unexpanded\def\startrawsetups {\begingroup\doifelsenextoptionalcs\syst_setups_start_raw_a\syst_setups_start_raw_b} \let\stoprawsetups \relax
+\unexpanded\def\startlocalsetups{\begingroup\doifelsenextoptionalcs\syst_setups_start_loc_a\syst_setups_start_loc_b} \let\stoplocalsetups \relax
+\unexpanded\def\startsetups {\begingroup\doifelsenextoptionalcs\syst_setups_start_tex_a\syst_setups_start_tex_b} \let\stopsetups \relax
\def\syst_setups_start_lua_indeed#1#2#3\stopluasetups {\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
\def\syst_setups_start_xml_indeed#1#2#3\stopxmlsetups {\endgroup\dodoglobal\expandafter\def\csname\??setup#1:#2\expandafter\endcsname\expandafter##\expandafter1\expandafter{#3}}
@@ -525,14 +648,14 @@
\def\systemsetups#1{\syst_setups{\systemsetupsprefix#1}}
-\def\resetsetups[#1]% see x-fo for usage
+\unexpanded\def\resetsetups[#1]% see x-fo for usage
{\ifcsname\??setup\ifgridsnapping\v!grid\fi:#1\endcsname
\dodoglobal\letbeundefined{\??setup\ifgridsnapping\v!grid\fi:#1}%
\else
\dodoglobal\letbeundefined{\??setup:#1}%
\fi}
-\def\showsetupsdefinition[#1]%
+\unexpanded\def\showsetupsdefinition[#1]%
{\showvalue{\??setup:#1}} % temp hack for debugging
%D \macros
@@ -619,6 +742,8 @@
\expandafter\secondoftwoarguments
\fi}
+\let\doifvariableelse\doifelsevariable
+
\unexpanded\def\doifvariable#1#2%
{\ifcsname\??variables#1:#2\endcsname
\expandafter\firstofoneargument
@@ -633,18 +758,52 @@
\expandafter\firstofoneargument
\fi}
+%D A few more (we could use a public test variable so that we only need
+%D to expand once, assuming expandable variables):
+
+\letvalue{\??variables:}\empty
+
+\unexpanded\def\doifelseemptyvariable#1#2%
+ {\edef\m_syst_string_one{\csname\??variables\ifcsname\??variables#1:#2\endcsname#1:#2\else:\fi\endcsname}%
+ \ifx\m_syst_string_one\empty
+ \expandafter\firstoffourarguments
+ \else
+ \expandafter\secondoftwoarguments
+ \fi}
+
+\let\doifemptyvariableelse\doifelseemptyvariable
+
+\unexpanded\def\doifemptyvariable#1#2%
+ {\edef\m_syst_string_one{\csname\??variables\ifcsname\??variables#1:#2\endcsname#1:#2\else:\fi\endcsname}%
+ \ifx\m_syst_string_one\empty
+ \expandafter\firstofoneargument
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
+\unexpanded\def\doifnotemptyvariable#1#2%
+ {\edef\m_syst_string_one{\csname\??variables\ifcsname\??variables#1:#2\endcsname#1:#2\else:\fi\endcsname}%
+ \ifx\m_syst_string_one\empty
+ \expandafter\gobbleoneargument
+ \else
+ \expandafter\firstofoneargument
+ \fi}
+
+
\def\getvariabledefault#1#2% #3% can be command, so no ifcsname here
{\executeifdefined{\??variables#1:#2}}% {#3}
\unexpanded\def\setupenv
{\dotripleargument\syst_variables_set[\getrawparameters][\s!environment]}
-\unexpanded\def\doifenvelse{\doifelsevariable \s!environment}
+\unexpanded\def\doifelseenv{\doifelsevariable \s!environment}
\unexpanded\def\doifenv {\doifvariable \s!environment}
\unexpanded\def\doifnotenv {\doifnotvariable \s!environment}
\def\env {\getvariable \s!environment}
\def\envvar {\getvariabledefault\s!environment}
+\let\doifenvelse\doifelseenv
+
%D \macros
%D {defineselector,setupselector,select,directselect}
%D