diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/unicode-math/um-code-mathmap.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/unicode-math/um-code-mathmap.dtx | 903 |
1 files changed, 372 insertions, 531 deletions
diff --git a/Master/texmf-dist/source/latex/unicode-math/um-code-mathmap.dtx b/Master/texmf-dist/source/latex/unicode-math/um-code-mathmap.dtx index 2b843fb29a4..21e0266543d 100644 --- a/Master/texmf-dist/source/latex/unicode-math/um-code-mathmap.dtx +++ b/Master/texmf-dist/source/latex/unicode-math/um-code-mathmap.dtx @@ -1,416 +1,235 @@ %%^^A%% um-code-mathmap.dtx -- part of UNICODE-MATH <wspr.io/unicode-math> +%%^^A%% Setup of symbol alphabets. -% \section{Mapping in maths alphabets} +% \section{Defining the math alphabets per style} % \label{sec:mathmap} % % \begin{macrocode} %<*package> % \end{macrocode} % -% Switching to a different style of alphabetic symbols was traditionally performed with -% commands like \cmd\mathbf, which literally changes fonts to access alternate symbols. -% This is not as simple with Unicode fonts. -% -% In traditional \TeX{} maths font setups, you simply switch between different `families' (\cmd\fam), which is analogous to changing from one font to another---a symbol such as `a' will be upright in one font, bold in another, and so on. -% In pkg{unicode-math}, a different mechanism is used to switch between styles. For every letter (start with ascii a-zA-Z and numbers to keep things simple for now), they are assigned a `mathcode' with \cmd\Umathcode\ that maps from input letter to output font glyph slot. This is done with the equivalent of -% \begin{Verbatim} -% \Umathcode`\a = 7 1 "1D44E\relax -% \Umathcode`\b = 7 1 "1D44F\relax -% \Umathcode`\c = 7 1 "1D450\relax -% ... -% \end{Verbatim} -% When switching from regular letters to, say, \cmd\mathrm, we now need to execute a new mapping: -% \begin{Verbatim} -% \Umathcode`\a = 7 1 `\a\relax -% \Umathcode`\b = 7 1 `\b\relax -% \Umathcode`\c = 7 1 `\c\relax -% ... -% \end{Verbatim} -% This is fairly straightforward to perform when we're defining our own commands such as \cmd\symbf\ and so on. However, this means that `classical' \TeX\ font setups will break, because with the original mapping still in place, the engine will be attempting to insert unicode maths glyphs from a standard font. -% -% \subsection{Hooks into \LaTeXe} -% -% To overcome this, we patch \cs{use@mathgroup}. -% (An alternative is to patch \cs{extract@alph@from@version}, which constructs the \cs{mathXYZ} commands, but this method fails if the command has been defined using \cs{DeclareSymbolFontAlphabet}.) -% As far as I can tell, this is only used inside of commands such as \cs{mathXYZ}, so this shouldn't have any major side-effects. -% -% \begin{macrocode} -\cs_set:Npn \use@mathgroup #1 #2 - { - \mode_if_math:T % <- not sure if this is really necessary since we've just checked for mmode and raised an error if not! - { - \math@bgroup - \cs_if_eq:cNF {M@\f@encoding} #1 {#1} - \@@_switchto_literal: - \mathgroup #2 \relax - \math@egroup - } - } -% \end{macrocode} -% -% In LaTeX maths, the command |\operator@font| is defined that switches to the |operator| mathgroup. The classic example is the |\sin| in |$\sin{x}$|; essentially we're using |\mathrm| to typeset the upright symbols, but the syntax is |{\operator@font sin}|. -% I thought that hooking into |\operator@font| would be hard because all other maths font selection in 2e uses |\mathrm{...}| style. -% Then reading source2e a little more I stumbled upon: -% \begin{macro}{\operator@font} -% \begin{macrocode} -\cs_set:Npn \operator@font - { - \@@_switchto_literal: - \@fontswitch {} { \g_@@_operator_mathfont_tl } - } +% \begin{macro}{\@@_setup_alphabets:} +% This function is called within \cs{setmathfont} to configure the +% mapping between characters inside math styles. Three modes: +% \begin{description} +% \item[IMPLICIT] No ranges specified, set up everything +% \item[EXPLICIT] Some ranges specified, set up what is requested only +% \item[INHERIT] Of the slots in the ranges specified, compare against +% slots in each styled alphabet and only set up those needed +% \end{description} +% The INHERIT mode saves less time than I was hoping for but is still beneficial +% in simple cases. +% \begin{macrocode} +\cs_new:Npn \@@_setup_alphabets: + { + + \bool_if:NTF \l_@@_init_bool + { + % IMPLICIT + \@@_log:n {setup-implicit} + \seq_gset_eq:NN \g_@@_mathalph_seq \g_@@_default_mathalph_seq + \bool_set_true:N \l_@@_implicit_alph_bool + \@@_maybe_init_alphabet:n {sf} + \@@_maybe_init_alphabet:n {bf} + \@@_maybe_init_alphabet:n {bfsf} + \cs_set_eq:NN \@@_set_mathalphabet_char:nnn \@@_mathmap_noparse:nnn + \cs_set_eq:NN \@@_map_char_single:nn \@@_map_char_noparse:nn + \@@_mathalph_map: + \seq_if_empty:NF \l_@@_missing_alph_seq { \@@_log:n { missing-alphabets } } + } + { + \seq_if_empty:NF \g_@@_mathalph_seq + { + % EXPLICIT + \@@_log:n {setup-explicit} + \bool_set_false:N \l_@@_implicit_alph_bool + \cs_set_eq:NN \@@_set_mathalphabet_char:nnn \@@_mathmap_noparse:nnn + \cs_set_eq:NN \@@_map_char_single:nn \@@_map_char_noparse:nn + \@@_mathalph_map: + \seq_if_empty:NF \l_@@_missing_alph_seq { \@@_log:n { missing-alphabets } } + } + + % INHERIT + \clist_if_empty:NF \l_@@_mathmap_charints_clist + { + \seq_gclear:N \g_@@_mathalph_seq + \seq_map_inline:Nn \g_@@_default_mathalph_seq + { + \tl_set:No \l_@@_style_tl { \use_i:nnn ##1 } + \clist_set:No \l_@@_alphabet_clist { \use_ii:nnn ##1 } + + \clist_map_inline:Nn \l_@@_alphabet_clist + { + \clist_map_inline:cn {g_@@_named_slots_ \l_@@_style_tl _ ####1 _clist} + { + \clist_map_inline:Nn \l_@@_mathmap_charints_clist + { + \@@_int_if_slot_in_range:nnT {################1} {########1} + { + \seq_gput_right:Nn \g_@@_mathalph_seq {##1} + \clist_map_break:n { \clist_map_break:n { \clist_map_break: } } + } + } + } + } + } + } + + \cs_set_eq:NN \@@_set_mathalphabet_char:nnn \@@_mathmap_parse:nnn + \cs_set_eq:NN \@@_map_char_single:nn \@@_map_char_parse:nn + \@@_mathalph_map: + } + } % \end{macrocode} % \end{macro} % -% -% \subsection{Setting styles} -% -% Algorithm for setting alphabet fonts. -% By default, when |range| is empty, we are in \emph{implicit} mode. -% If |range| contains the name of the math alphabet, we are in \emph{explicit} -% mode and do things slightly differently. -% -% Implicit mode: -% \begin{itemize} -% \item Try and set all of the alphabet shapes. -% \item Check for the first glyph of each alphabet to detect if the font supports each -% alphabet shape. -% \item For alphabets that do exist, overwrite whatever's already there. -% \item For alphabets that are not supported, \emph{do nothing}. -% (This includes leaving the old alphabet definition in place.) -% \end{itemize} -% -% Explicit mode: -% \begin{itemize} -% \item Only set the alphabets specified. -% \item Check for the first glyph of the alphabet to detect if the font contains -% the alphabet shape in the Unicode math plane. -% \item For Unicode math alphabets, overwrite whatever's already there. -% \item Otherwise, use the \ascii\ glyph slots instead. -% \end{itemize} -% -% -% -% \subsection{Defining the math style macros} -% -% We call the different shapes that a math alphabet can be a `math style'. -% Note that different alphabets can exist within the same math style. E.g., -% we call `bold' the math style |bf| and within it there are upper and lower -% case Greek and Roman alphabets and Arabic numerals. -% -% \begin{macro}{\@@_prepare_mathstyle:n} -% \darg{math style name (e.g., \texttt{it} or \texttt{bb})} -% Define the high level math alphabet macros (\cs{mathit}, etc.) in terms of -% unicode-math definitions. Use \cs{bgroup}/\cs{egroup} so s'scripts scan the -% whole thing. -% -% The flag \cs{l_@@_mathstyle_tl} is for other applications to query the -% current math style. -% \begin{macrocode} -\cs_new:Nn \@@_prepare_mathstyle:n - { - \seq_put_right:Nn \g_@@_mathstyles_seq {#1} - \@@_init_alphabet:n {#1} - \cs_set:cpn {_@@_sym_#1_aux:n} - { \use:c {@@_switchto_#1:} \math@egroup } - \cs_set_protected:cpx {sym#1} - { - \exp_not:n - { - \math@bgroup - \mode_if_math:F - { - \egroup\expandafter - \non@alpherr\expandafter{\csname sym#1\endcsname\space} - } - \tl_set:Nn \l_@@_mathstyle_tl {#1} - } - \exp_not:c {_@@_sym_#1_aux:n} - } - } +% \begin{macro}{\@@_mathalph_map:} +% \begin{macrocode} +\cs_set:Nn \@@_mathalph_map: + { + \seq_map_inline:Nn \g_@@_mathalph_seq + { + \tl_set:No \l_@@_style_tl { \use_i:nnn ##1 } + \clist_set:No \l_@@_alphabet_clist { \use_ii:nnn ##1 } + \tl_set:No \l_@@_remap_style_tl { \use_iii:nnn ##1 } + + % If no set of alphabets is defined: + \clist_if_empty:NT \l_@@_alphabet_clist + { + \cs_set_eq:NN \@@_maybe_init_alphabet:n \@@_init_alphabet:n + \prop_get:cnN { g_@@_named_range_ \l_@@_style_tl _prop } + { default-alpha } \l_@@_alphabet_clist + } + + \@@_check_math_alphabet: + \@@_setup_math_alphabet: + } + } % \end{macrocode} % \end{macro} % -% -% \begin{macro}{\@@_init_alphabet:n} -% \darg{math alphabet name (e.g., \texttt{it} or \texttt{bb})} -% This macro initialises the macros used to set up a math alphabet. -% First used when the math alphabet macro is first defined, but then used -% later when redefining a particular maths alphabet. +% \begin{macro}{\@@_check_math_alphabet:} +% First check that at least one of the alphabets for the font shape is defined +% (this process is fast) \dots % \begin{macrocode} -\cs_set:Nn \@@_init_alphabet:n - { - \@@_log:nx {alph-initialise} {#1} - \cs_set_eq:cN {@@_switchto_#1:} \prg_do_nothing: - } +\cs_new:Nn \@@_check_math_alphabet: + { + \clist_map_inline:Nn \l_@@_alphabet_clist + { + \tl_set:Nn \l_@@_alphabet_tl {##1} + \@@_if_alphabet_exists:nnTF \l_@@_style_tl \l_@@_alphabet_tl + { + \str_if_eq_x:nnTF {\l_@@_alphabet_tl} {misc} + { + \@@_maybe_init_alphabet:n \l_@@_style_tl + \clist_map_break: + } + { + \@@_glyph_if_exist:NnT \g_@@_curr_font_cmd_tl + { \@@_to_usv:nn {\l_@@_style_tl} {\l_@@_alphabet_tl} } + { + \@@_maybe_init_alphabet:n \l_@@_style_tl + \clist_map_break: + } + } + } + { + \msg_warning:nnx {unicode-math} {no-alphabet} + { \l_@@_style_tl / \l_@@_alphabet_tl } + } + } + } % \end{macrocode} % \end{macro} % -% \subsection{Definition of alphabets and styles} -% -% First of all, we break up unicode into `named ranges', such as |up|, |bb|, |sfup|, and so on, which refer to specific blocks of unicode that contain various symbols (usually alphabetical symbols). -% +% \begin{macro}{\@@_setup_math_alphabet:} +% \dots and then loop through them defining the individual ranges: +% (currently this process is slow) % \begin{macrocode} -\cs_new:Nn \@@_new_named_range:n - { - \prop_new:c {g_@@_named_range_#1_prop} - } -\clist_set:Nn \g_@@_named_ranges_clist - { - up, it, tt, bfup, bfit, bb , bbit, scr, bfscr, cal, bfcal, - frak, bffrak, sfup, sfit, bfsfup, bfsfit, bfsf - } -\clist_map_inline:Nn \g_@@_named_ranges_clist - { \@@_new_named_range:n {#1} } +\cs_new:Nn \@@_setup_math_alphabet: + { + \clist_map_inline:Nn \l_@@_alphabet_clist + { + \tl_set:Nx \l_@@_alphabet_tl { \tl_trim_spaces:n {##1} } + +%<debug>\typeout{_setup_math_alphabet:~\l_@@_style_tl/\l_@@_alphabet_tl} + + \@@_if_alphabet_exists:nnT {\l_@@_style_tl} {\l_@@_alphabet_tl} + { + \exp_args:No \tl_if_eq:nnTF \l_@@_alphabet_tl {misc} + { + \@@_log:nx {setup-alph} {sym \l_@@_style_tl~(\l_@@_alphabet_tl)} + \@@_alphabet_config:nnn {\l_@@_style_tl} {\l_@@_alphabet_tl} {\l_@@_remap_style_tl} + } + { + \@@_glyph_if_exist:NnTF \g_@@_curr_font_cmd_tl { \@@_to_usv:nn {\l_@@_remap_style_tl} {\l_@@_alphabet_tl} } + { + \@@_log:nx {setup-alph} {sym \l_@@_style_tl~(\l_@@_alphabet_tl)} + \@@_alphabet_config:nnn {\l_@@_style_tl} {\l_@@_alphabet_tl} {\l_@@_remap_style_tl} + } + { + \bool_if:NTF \l_@@_implicit_alph_bool + { + \seq_put_right:Nx \l_@@_missing_alph_seq + { + \@backslashchar sym \l_@@_style_tl \space + (\tl_use:c{c_@@_math_alphabet_name_ \l_@@_alphabet_tl _tl}) + } + } + { + \@@_alphabet_config:nnn {\l_@@_style_tl} {\l_@@_alphabet_tl} {up} + } + } + } + } + } + } % \end{macrocode} -% +% \end{macro} % % Each alphabet style needs to be configured. % This happens in Section~\ref{sec:setupalphabets}. % \begin{macrocode} \cs_new:Nn \@@_new_alphabet_config:nnn - { - \prop_if_exist:cF {g_@@_named_range_#1_prop} - { \@@_warning:nnn {no-named-range} {#1} {#2} } - - \prop_gput:cnn {g_@@_named_range_#1_prop} { alpha_tl } - { - \prop_item:cn {g_@@_named_range_#1_prop} { alpha_tl } - {#2} - } - % Q: do I need to bother removing duplicates? - - \cs_new:cn { @@_config_#1_#2:n } {#3} - } -% \end{macrocode} -% \begin{macrocode} -\cs_new:Nn \@@_alphabet_config:nnn - { - \use:c {@@_config_#1_#2:n} {#3} - } -% \end{macrocode} -% \begin{macrocode} -\prg_new_conditional:Nnn \@@_if_alphabet_exists:nn {T,TF} - { - \cs_if_exist:cTF {@@_config_#1_#2:n} - \prg_return_true: \prg_return_false: - } -% \end{macrocode} -% -% The linking between named ranges and symbol style commands happens here. -% It's currently not using all of the machinery we're in the process of setting up above. -% Baby steps. -% \begin{macrocode} -\cs_new:Nn \@@_default_mathalph:nnn - { - \seq_put_right:Nx \g_@@_named_ranges_seq { \tl_to_str:n {#1} } - \seq_put_right:Nn \g_@@_default_mathalph_seq {{#1}{#2}{#3}} - \prop_gput:cnn { g_@@_named_range_#1_prop } { default-alpha } {#2} - } -\@@_default_mathalph:nnn {up } {latin,Latin,greek,Greek,num,misc} {up } -\@@_default_mathalph:nnn {it } {latin,Latin,greek,Greek,misc} {it } -\@@_default_mathalph:nnn {bb } {latin,Latin,num,misc} {bb } -\@@_default_mathalph:nnn {bbit } {misc} {bbit } -\@@_default_mathalph:nnn {scr } {latin,Latin} {scr } -\@@_default_mathalph:nnn {cal } {Latin} {scr } -\@@_default_mathalph:nnn {bfcal } {Latin} {bfscr } -\@@_default_mathalph:nnn {frak } {latin,Latin} {frak } -\@@_default_mathalph:nnn {tt } {latin,Latin,num} {tt } -\@@_default_mathalph:nnn {sfup } {latin,Latin,num} {sfup } -\@@_default_mathalph:nnn {sfit } {latin,Latin} {sfit } -\@@_default_mathalph:nnn {bfup } {latin,Latin,greek,Greek,num,misc} {bfup } -\@@_default_mathalph:nnn {bfit } {latin,Latin,greek,Greek,misc} {bfit } -\@@_default_mathalph:nnn {bfscr } {latin,Latin} {bfscr } -\@@_default_mathalph:nnn {bffrak} {latin,Latin} {bffrak} -\@@_default_mathalph:nnn {bfsfup} {latin,Latin,greek,Greek,num,misc} {bfsfup} -\@@_default_mathalph:nnn {bfsfit} {latin,Latin,greek,Greek,misc} {bfsfit} -% \end{macrocode} -% -% \subsubsection{Define symbol style commands} -% Finally, all of the `symbol styles' commands are set up, which are the commands to access each of the named alphabet styles. There is not a one-to-one mapping between symbol style commands and named style ranges! -% \begin{macrocode} -\clist_map_inline:nn - { - up, it, bfup, bfit, sfup, sfit, bfsfup, bfsfit, bfsf, - tt, bb, bbit, scr, bfscr, cal, bfcal, frak, bffrak, - normal, literal, sf, bf, - } - { \@@_prepare_mathstyle:n {#1} } -% \end{macrocode} -% -% -% \subsubsection{New names for legacy textmath alphabet selection} -% In case a package option overwrites, say, \cs{mathbf} with \cs{symbf}. -% \begin{macrocode} -\clist_map_inline:nn - { rm, it, bf, sf, tt } - { \cs_set_eq:cc { mathtext #1 } { math #1 } } -% \end{macrocode} -% Perhaps these should actually be defined using a hypothetical unicode-math interface to creating new such styles. To come. -% -% -% \subsubsection{Replacing legacy pure-maths alphabets} -% The following are alphabets which do not have a math/text ambiguity. -% \begin{macrocode} -\clist_map_inline:nn - { - normal, bb , bbit, scr, bfscr, cal, bfcal, frak, bffrak, tt, - bfup, bfit, sfup, sfit, bfsfup, bfsfit, bfsf - } - { - \cs_set:cpx { math #1 } { \exp_not:c { sym #1 } } - } -% \end{macrocode} -% -% -% \subsubsection{New commands for ambiguous alphabets} -% \begin{macrocode} -\AtBeginDocument{ -\clist_map_inline:nn - { rm, it, bf, sf, tt } - { - \cs_set_protected:cpx { math #1 } - { - \exp_not:n { \bool_if:NTF } \exp_not:c { g_@@_ math #1 _text_bool} - { \exp_not:c { mathtext #1 } } - { \exp_not:c { sym #1 } } - } - }} -% \end{macrocode} -% -% \paragraph{Alias \cs{mathrm} as legacy name for \cs{mathup}} -% \begin{macrocode} -\cs_set_protected:Npn \mathup { \mathrm } -\cs_set_protected:Npn \symrm { \symup } -% \end{macrocode} -% -% -% -% -% \subsection{Defining the math alphabets per style} -% -% \begin{macro}{\@@_setup_alphabets:} -% This function is called within \cs{setmathfont} to configure the -% mapping between characters inside math styles. -% \begin{macrocode} -\cs_new:Npn \@@_setup_alphabets: - { -% \end{macrocode} -% If |range=| has been used to configure styles, those choices will be in -% |\l_@@_mathalph_seq|. If not, set up the styles implicitly: -% \begin{macrocode} - \seq_if_empty:NTF \l_@@_mathalph_seq - { - \@@_log:n {setup-implicit} - \seq_set_eq:NN \l_@@_mathalph_seq \g_@@_default_mathalph_seq - \bool_set_true:N \l_@@_implicit_alph_bool - \@@_maybe_init_alphabet:n {sf} - \@@_maybe_init_alphabet:n {bf} - \@@_maybe_init_alphabet:n {bfsf} - } -% \end{macrocode} -% If |range=| has been used then we're in explicit mode: -% \begin{macrocode} - { - \@@_log:n {setup-explicit} - \bool_set_false:N \l_@@_implicit_alph_bool - \cs_set_eq:NN \@@_set_mathalphabet_char:nnn \@@_mathmap_noparse:nnn - \cs_set_eq:NN \@@_map_char_single:nn \@@_map_char_noparse:nn - } + { + \prop_if_exist:cF {g_@@_named_range_#1_prop} + { \@@_warning:nnn {no-named-range} {#1} {#2} } - % Now perform the mapping: - \seq_map_inline:Nn \l_@@_mathalph_seq - { - \tl_set:No \l_@@_style_tl { \use_i:nnn ##1 } - \clist_set:No \l_@@_alphabet_clist { \use_ii:nnn ##1 } - \tl_set:No \l_@@_remap_style_tl { \use_iii:nnn ##1 } - % If no set of alphabets is defined: - \clist_if_empty:NT \l_@@_alphabet_clist - { - \cs_set_eq:NN \@@_maybe_init_alphabet:n \@@_init_alphabet:n - \prop_get:cnN { g_@@_named_range_ \l_@@_style_tl _prop } - { default-alpha } \l_@@_alphabet_clist - } + \prop_gput:cnn {g_@@_named_range_#1_prop} { alpha_tl } + { + \prop_item:cn {g_@@_named_range_#1_prop} { alpha_tl } {#2} + } + % Q: do I need to bother removing duplicates? - \@@_setup_math_alphabet: - } - \seq_if_empty:NF \l_@@_missing_alph_seq { \@@_log:n { missing-alphabets } } - } % \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_setup_math_alphabet:} +% Create list of all chars defined in this named range: % \begin{macrocode} -\cs_new:Nn \@@_setup_math_alphabet: - { + \cs_new:cn { @@_config_#1_#2:n } + { + \clist_gclear_new:c {g_@@_named_slots_#1_#2_clist} + \tl_set:Nn \l_@@_curr_named_slot { g_@@_named_slots_#1_#2_clist } + #3 + \clist_gremove_duplicates:c {g_@@_named_slots_#1_#2_clist} + } + + } % \end{macrocode} -% First check that at least one of the alphabets for the font shape is defined -% (this process is fast) \dots % \begin{macrocode} - \clist_map_inline:Nn \l_@@_alphabet_clist - { - \tl_set:Nn \l_@@_alphabet_tl {##1} - \@@_if_alphabet_exists:nnTF \l_@@_style_tl \l_@@_alphabet_tl - { - \str_if_eq_x:nnTF {\l_@@_alphabet_tl} {misc} - { - \@@_maybe_init_alphabet:n \l_@@_style_tl - \clist_map_break: - } - { - \@@_glyph_if_exist:NnT \l_@@_font { \@@_to_usv:nn {\l_@@_style_tl} {\l_@@_alphabet_tl} } - { - \@@_maybe_init_alphabet:n \l_@@_style_tl - \clist_map_break: - } - } - } - { \msg_warning:nnx {unicode-math} {no-alphabet} { \l_@@_style_tl / \l_@@_alphabet_tl } } - } +\cs_new:Nn \@@_alphabet_config:nnn + { + \use:c {@@_config_#1_#2:n} {#3} + } % \end{macrocode} -% \dots and then loop through them defining the individual ranges: -% (currently this process is slow) % \begin{macrocode} -%<debug> \csname TIC\endcsname - \clist_map_inline:Nn \l_@@_alphabet_clist - { - \tl_set:Nx \l_@@_alphabet_tl { \tl_trim_spaces:n {##1} } - \cs_if_exist:cT {@@_config_ \l_@@_style_tl _ \l_@@_alphabet_tl :n} - { - \exp_args:No \tl_if_eq:nnTF \l_@@_alphabet_tl {misc} - { - \@@_log:nx {setup-alph} {sym \l_@@_style_tl~(\l_@@_alphabet_tl)} - \@@_alphabet_config:nnn {\l_@@_style_tl} {\l_@@_alphabet_tl} {\l_@@_remap_style_tl} - } - { - \@@_glyph_if_exist:NnTF \l_@@_font { \@@_to_usv:nn {\l_@@_remap_style_tl} {\l_@@_alphabet_tl} } - { - \@@_log:nx {setup-alph} {sym \l_@@_style_tl~(\l_@@_alphabet_tl)} - \@@_alphabet_config:nnn {\l_@@_style_tl} {\l_@@_alphabet_tl} {\l_@@_remap_style_tl} - } - { - \bool_if:NTF \l_@@_implicit_alph_bool - { - \seq_put_right:Nx \l_@@_missing_alph_seq - { - \@backslashchar sym \l_@@_style_tl \space - (\tl_use:c{c_@@_math_alphabet_name_ \l_@@_alphabet_tl _tl}) - } - } - { - \@@_alphabet_config:nnn {\l_@@_style_tl} {\l_@@_alphabet_tl} {up} - } - } - } - } - } -%<debug> \csname TOC\endcsname - } +\prg_new_conditional:Nnn \@@_if_alphabet_exists:nn {T,TF} + { + \cs_if_exist:cTF {@@_config_#1_#2:n} + \prg_return_true: \prg_return_false: + } % \end{macrocode} -% \end{macro} -% % -% \subsection{Mapping `naked' math characters} +% \subsection{Mapping `naked’ math characters} % % Before we show the definitions of the alphabet mappings using the functions % |\@@_alphabet_config:nnn \l_@@_style_tl {##1} {...}|, we first want to define some functions @@ -426,31 +245,33 @@ % \begin{macro}{\@@_map_char_parse:nn} % \begin{macrocode} \cs_new:Nn \@@_map_char_noparse:nn - { \@@_set_mathcode:nnnn {#1}{\mathalpha}{\l_@@_symfont_label_tl}{#2} } + { + \@@_set_mathcode:nnnn {#1} {\mathalpha} {\l_@@_symfont_label_tl} {#2} + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_map_char_parse:nn - { - \@@_if_char_spec:nNNT {#1} {\@nil} {\mathalpha} - { \@@_map_char_noparse:nn {#1}{#2} } - } + { + \@@_if_char_spec:nNT {#1} {\mathalpha} + { \@@_map_char_noparse:nn {#1}{#2} } + } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\@@_map_char_single:nnn} -% \darg{char name (`dotlessi')} +% \darg{char name (`dotlessi’)} % \darg{from alphabet(s)} % \darg{to alphabet} % Logical interface to \cs{@@_map_char_single:nn}. % \begin{macrocode} \cs_new:Nn \@@_map_char_single:nnn - { - \@@_map_char_single:nn { \@@_to_usv:nn {#1}{#3} } - { \@@_to_usv:nn {#2}{#3} } - } + { + \@@_map_char_single:nn { \@@_to_usv:nn {#1} {#3} } + { \@@_to_usv:nn {#2} {#3} } + } % \end{macrocode} % \end{macro} % @@ -463,103 +284,109 @@ % First the function with numbers: % \begin{macrocode} \cs_set:Nn \@@_map_chars_range:nnn - { - \int_step_inline:nnnn {0}{1}{#1-1} - { \@@_map_char_single:nn {#2+##1}{#3+##1} } - } + { + \int_step_inline:nnnn {0} {1} {#1-1} + { \@@_map_char_single:nn {#2+##1} {#3+##1} } + + \clist_gput_right:cx { \l_@@_curr_named_slot } + { \int_eval:n { #3 } - \int_eval:n { #3 + #1-1 } } + } % \end{macrocode} % And the wrapper with names: % \begin{macrocode} \cs_new:Nn \@@_map_chars_range:nnnn - { - \@@_map_chars_range:nnn {#1} { \@@_to_usv:nn {#2}{#4} } - { \@@_to_usv:nn {#3}{#4} } - } + { + \@@_map_chars_range:nnn {#1} { \@@_to_usv:nn {#2} {#4} } + { \@@_to_usv:nn {#3} {#4} } + } % \end{macrocode} % \end{macro} % -% \subsubsection{Functions for `normal' alphabet symbols} +% \subsubsection{Functions for `normal’ alphabet symbols} % % \begin{macro}{\@@_set_normal_char:nnn} % \begin{macrocode} \cs_set:Nn \@@_set_normal_char:nnn - { - \@@_usv_if_exist:nnT {#3} {#1} { - \clist_map_inline:nn {#2} - { - \@@_set_mathalphabet_pos:nnnn {normal} {#1} {##1} {#3} - \@@_map_char_single:nnn {##1} {#3} {#1} - } + \@@_usv_if_exist:nnT {#3} {#1} + { + \clist_map_inline:nn {#2} + { + \@@_set_mathalphabet_pos:nnnn {normal} {#1} {##1} {#3} + \@@_map_char_single:nnn {##1} {#3} {#1} + + \clist_gput_right:cx {\l_@@_curr_named_slot} + { \int_eval:n { \@@_to_usv:nn {#3} {#1} } } + } + } } - } % \end{macrocode} % \end{macro} % % \begin{macrocode} \cs_new:Nn \@@_set_normal_Latin:nn - { - \clist_map_inline:nn {#1} - { - \@@_set_mathalphabet_Latin:nnn {normal} {##1} {#2} - \@@_map_chars_range:nnnn {26} {##1} {#2} {Latin} - } - } + { + \clist_map_inline:nn {#1} + { + \@@_set_mathalphabet_Latin:nnn {normal} {##1} {#2} + \@@_map_chars_range:nnnn {26} {##1} {#2} {Latin} + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_normal_latin:nn - { - \clist_map_inline:nn {#1} - { - \@@_set_mathalphabet_latin:nnn {normal} {##1} {#2} - \@@_map_chars_range:nnnn {26} {##1} {#2} {latin} - } - } + { + \clist_map_inline:nn {#1} + { + \@@_set_mathalphabet_latin:nnn {normal} {##1} {#2} + \@@_map_chars_range:nnnn {26} {##1} {#2} {latin} + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_normal_greek:nn - { - \clist_map_inline:nn {#1} - { - \@@_set_mathalphabet_greek:nnn {normal} {##1} {#2} - \@@_map_chars_range:nnnn {25} {##1} {#2} {greek} - \@@_map_char_single:nnn {##1} {#2} {epsilon} - \@@_map_char_single:nnn {##1} {#2} {vartheta} - \@@_map_char_single:nnn {##1} {#2} {varkappa} - \@@_map_char_single:nnn {##1} {#2} {phi} - \@@_map_char_single:nnn {##1} {#2} {varrho} - \@@_map_char_single:nnn {##1} {#2} {varpi} - \@@_set_mathalphabet_pos:nnnn {normal} {epsilon} {##1} {#2} - \@@_set_mathalphabet_pos:nnnn {normal} {vartheta} {##1} {#2} - \@@_set_mathalphabet_pos:nnnn {normal} {varkappa} {##1} {#2} - \@@_set_mathalphabet_pos:nnnn {normal} {phi} {##1} {#2} - \@@_set_mathalphabet_pos:nnnn {normal} {varrho} {##1} {#2} - \@@_set_mathalphabet_pos:nnnn {normal} {varpi} {##1} {#2} - } - } + { + \clist_map_inline:nn {#1} + { + \@@_set_mathalphabet_greek:nnn {normal} {##1} {#2} + \@@_map_chars_range:nnnn {25} {##1} {#2} {greek} + \@@_map_char_single:nnn {##1} {#2} {epsilon} + \@@_map_char_single:nnn {##1} {#2} {vartheta} + \@@_map_char_single:nnn {##1} {#2} {varkappa} + \@@_map_char_single:nnn {##1} {#2} {phi} + \@@_map_char_single:nnn {##1} {#2} {varrho} + \@@_map_char_single:nnn {##1} {#2} {varpi} + \@@_set_mathalphabet_pos:nnnn {normal} {epsilon} {##1} {#2} + \@@_set_mathalphabet_pos:nnnn {normal} {vartheta} {##1} {#2} + \@@_set_mathalphabet_pos:nnnn {normal} {varkappa} {##1} {#2} + \@@_set_mathalphabet_pos:nnnn {normal} {phi} {##1} {#2} + \@@_set_mathalphabet_pos:nnnn {normal} {varrho} {##1} {#2} + \@@_set_mathalphabet_pos:nnnn {normal} {varpi} {##1} {#2} + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_normal_Greek:nn - { - \clist_map_inline:nn {#1} - { - \@@_set_mathalphabet_Greek:nnn {normal} {##1} {#2} - \@@_map_chars_range:nnnn {25} {##1} {#2} {Greek} - \@@_map_char_single:nnn {##1} {#2} {varTheta} - \@@_set_mathalphabet_pos:nnnn {normal} {varTheta} {##1} {#2} - } - } + { + \clist_map_inline:nn {#1} + { + \@@_set_mathalphabet_Greek:nnn {normal} {##1} {#2} + \@@_map_chars_range:nnnn {25} {##1} {#2} {Greek} + \@@_map_char_single:nnn {##1} {#2} {varTheta} + \@@_set_mathalphabet_pos:nnnn {normal} {varTheta} {##1} {#2} + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_normal_numbers:nn - { - \@@_set_mathalphabet_numbers:nnn {normal} {#1} {#2} - \@@_map_chars_range:nnnn {10} {#1} {#2} {num} - } + { + \@@_set_mathalphabet_numbers:nnn {normal} {#1} {#2} + \@@_map_chars_range:nnnn {10} {#1} {#2} {num} + } % \end{macrocode} % % @@ -567,45 +394,45 @@ % % \subsubsection{Functions for setting up the maths alphabets} % -% \begin{macro}{\@@_set_mathalphabet_char:Nnn} +% \begin{macro}{\@@_set_mathalphabet_char:nnn} +% \darg{Maths alphabet, \eg, `bb’} +% \darg{Input slot, \eg, the slot for `A’ (comma separated)} +% \darg{Output slot, \eg, the slot for `$\mathbb{A}$’} % This is a wrapper for either |\@@_mathmap_noparse:nnn| or -% |\@@_mathmap_parse:Nnn|, depending on the context. +% |\@@_mathmap_parse:nnn|, depending on the context. % \end{macro} % % \begin{macro}{\@@_mathmap_noparse:nnn} -% \darg{Maths alphabet, \eg, `bb'} -% \darg{Input slot(s), \eg, the slot for `A' (comma separated)} -% \darg{Output slot, \eg, the slot for `$\mathbb{A}$'} -% Adds \cs{@@_set_mathcode:nnnn} declarations to the specified maths alphabet's definition. +% \darg{Maths alphabet, \eg, `bb’} +% \darg{Input slot, \eg, the slot for `A’ (comma separated)} +% \darg{Output slot, \eg, the slot for `$\mathbb{A}$’} +% Adds \cs{@@_set_mathcode:nnnn} declarations to the specified maths alphabet’s definition. % \begin{macrocode} \cs_new:Nn \@@_mathmap_noparse:nnn - { - \clist_map_inline:nn {#2} - { - \tl_put_right:cx {@@_switchto_#1:} - { - \@@_set_mathcode:nnnn {##1} {\mathalpha} {\l_@@_symfont_label_tl} {#3} - } - } - } + { + \tl_put_right:cx { @@_switchto_#1: } + { + \@@_set_mathcode:nnnn {#2} {\mathalpha} {\l_@@_symfont_label_tl} {#3} + } + } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_mathmap_parse:nnn} -% \darg{Maths alphabet, \eg, `bb'} -% \darg{Input slot(s), \eg, the slot for `A' (comma separated)} -% \darg{Output slot, \eg, the slot for `$\mathbb{A}$'} -% When \cmd\@@_if_char_spec:nNNT\ is executed, it populates the \cmd\l_@@_char_nrange_clist\ +% \darg{Maths alphabet, \eg, `bb’} +% \darg{Input slot, \eg, the slot for `A’ (comma separated)} +% \darg{Output slot, \eg, the slot for `$\mathbb{A}$’} +% When \cmd\@@_if_char_spec:nNT\ is executed, it populates the \cmd\l_@@_mathmap_charints_clist\ % macro with slot numbers corresponding to the specified range. This range is used to % conditionally add \cs{@@_set_mathcode:nnnn} declaractions to the maths alphabet definition. % \begin{macrocode} \cs_new:Nn \@@_mathmap_parse:nnn - { - \clist_if_in:NnT \l_@@_char_nrange_clist {#3} - { - \@@_mathmap_noparse:nnn {#1}{#2}{#3} - } - } + { + \exp_args:NNx \clist_if_in:NnT \l_@@_mathmap_charints_clist { \int_eval:n {#3} } + { + \@@_mathmap_noparse:nnn {#1} {#2} {#3} + } + } % \end{macrocode} % \end{macro} % @@ -616,34 +443,45 @@ % \darg{char name to map} % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_char:nnnn - { - \@@_set_mathalphabet_char:nnn {#1} { \@@_to_usv:nn {#2} {#4} } - { \@@_to_usv:nn {#3} {#4} } - } + { + \@@_set_mathalphabet_char:nnn {#1} { \@@_to_usv:nn {#2} {#4} } + { \@@_to_usv:nn {#3} {#4} } + } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_set_mathalph_range:nnnn} % \darg{Number of iterations} -% \darg{Maths alphabet} -% \darg{Starting input char (single)} +% \darg{Sym command suffix} +% \darg{Starting input char} % \darg{Starting output char} % Loops through character ranges setting \cmd\mathcode. % First the version that uses numbers: % \begin{macrocode} \cs_new:Nn \@@_set_mathalph_range:nnnn - { - \int_step_inline:nnnn {0} {1} {#1-1} - { \@@_set_mathalphabet_char:nnn {#2} { ##1 + #3 } { ##1 + #4 } } - } + { + \int_step_inline:nnnn {0} {1} {#1-1} + { \@@_set_mathalphabet_char:nnn {#2} { ##1 + #3 } { ##1 + #4 } } + } % \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_set_mathalph_range:nnnn} +% \darg{Number of iterations} +% \darg{Sym command suffix} +% \darg{input style} +% \darg{output style} +% \darg{alphabet} % Then the wrapper version that uses names: % \begin{macrocode} \cs_new:Nn \@@_set_mathalph_range:nnnnn - { - \@@_set_mathalph_range:nnnn {#1} {#2} { \@@_to_usv:nn {#3} {#5} } - { \@@_to_usv:nn {#4} {#5} } - } + { + \clist_gput_right:cx { \l_@@_curr_named_slot } + { \int_eval:n { \@@_to_usv:nn {#4} {#5} } - \int_eval:n { (#1-1)+\@@_to_usv:nn {#4} {#5} } } + + \@@_set_mathalph_range:nnnn {#1} {#2} { \@@_to_usv:nn {#3} {#5} } + { \@@_to_usv:nn {#4} {#5} } + } % \end{macrocode} % \end{macro} % @@ -651,67 +489,70 @@ % % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_pos:nnnn - { - \@@_usv_if_exist:nnT {#4} {#2} - { - \clist_map_inline:nn {#3} - { \@@_set_mathalphabet_char:nnnn {#1} {##1} {#4} {#2} } - } - } + { + \@@_usv_if_exist:nnT {#4} {#2} + { + \clist_map_inline:nn {#3} + { \@@_set_mathalphabet_char:nnnn {#1} {##1} {#4} {#2} } + + \clist_gput_right:cx {\l_@@_curr_named_slot} + { \int_eval:n { \@@_to_usv:nn {#4} {#2} } } + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_numbers:nnn - { - \clist_map_inline:nn {#2} - { \@@_set_mathalph_range:nnnnn {10} {#1} {##1} {#3} {num} } - } + { + \clist_map_inline:nn {#2} + { \@@_set_mathalph_range:nnnnn {10} {#1} {##1} {#3} {num} } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_Latin:nnn - { - \clist_map_inline:nn {#2} - { \@@_set_mathalph_range:nnnnn {26} {#1} {##1} {#3} {Latin} } - } + { + \clist_map_inline:nn {#2} + { \@@_set_mathalph_range:nnnnn {26} {#1} {##1} {#3} {Latin} } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_latin:nnn - { - \clist_map_inline:nn {#2} - { - \@@_set_mathalph_range:nnnnn {26} {#1} {##1} {#3} {latin} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {h} - } - } + { + \clist_map_inline:nn {#2} + { + \@@_set_mathalph_range:nnnnn {26} {#1} {##1} {#3} {latin} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {h} + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_Greek:nnn - { - \clist_map_inline:nn {#2} - { - \@@_set_mathalph_range:nnnnn {25} {#1} {##1} {#3} {Greek} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varTheta} - } - } + { + \clist_map_inline:nn {#2} + { + \@@_set_mathalph_range:nnnnn {25} {#1} {##1} {#3} {Greek} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varTheta} + } + } % \end{macrocode} % % \begin{macrocode} \cs_new:Nn \@@_set_mathalphabet_greek:nnn - { - \clist_map_inline:nn {#2} - { - \@@_set_mathalph_range:nnnnn {25} {#1} {##1} {#3} {greek} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {epsilon} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {vartheta} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varkappa} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {phi} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varrho} - \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varpi} - } - } + { + \clist_map_inline:nn {#2} + { + \@@_set_mathalph_range:nnnnn {25} {#1} {##1} {#3} {greek} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {epsilon} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {vartheta} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varkappa} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {phi} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varrho} + \@@_set_mathalphabet_char:nnnn {#1} {##1} {#3} {varpi} + } + } % \end{macrocode} % % \begin{macrocode} @@ -729,7 +570,7 @@ % the conditions of the LaTeX Project Public License, version 1.3c or higher % (your choice): <http://www.latex-project.org/lppl/>. % ------------------------------------------------ -% Copyright 2006-2017 Will Robertson, LPPL "maintainer" +% Copyright 2006-2018 Will Robertson, LPPL "maintainer" % Copyright 2010-2017 Philipp Stephani % Copyright 2011-2017 Joseph Wright % Copyright 2012-2015 Khaled Hosny |