summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/unicode-math-input/unicode-math-input.sty
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/unicode-math-input/unicode-math-input.sty')
-rw-r--r--macros/latex/contrib/unicode-math-input/unicode-math-input.sty731
1 files changed, 731 insertions, 0 deletions
diff --git a/macros/latex/contrib/unicode-math-input/unicode-math-input.sty b/macros/latex/contrib/unicode-math-input/unicode-math-input.sty
new file mode 100644
index 0000000000..dcb72f6a30
--- /dev/null
+++ b/macros/latex/contrib/unicode-math-input/unicode-math-input.sty
@@ -0,0 +1,731 @@
+% File: unicode-math-input.sty
+% Copyright 2022-2023 user202729
+%
+% This work may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this license or
+% (at your option) any later version. The latest version of this license is in
+% the file:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is user202729.
+
+\RequirePackage{expl3}
+\RequirePackage{iftex}
+\ProvidesExplPackage{unicode-math-input}{2023-05-12}{0.0.0}{Allow entering Unicode symbols in math formulas}
+
+\makeatletter
+\AtBeginDocument{
+ \@ifpackageloaded{unicode-math}{
+ \msg_new:nnn {unicode-math-input} {unicode-math-clash} {
+ You~don't~need~this~package~if~you~use~unicode-math~package!
+ }
+ \msg_error:nn {unicode-math-input} {unicode-math-clash}
+ }{}
+}
+\makeatother
+
+\RequirePackage{l3keys2e}
+\keys_define:nn{unicode-math-input}{
+ ignore-refresh-delimiter-list .bool_set:N=\__umi_ignore_refresh_delimiter_list,
+ ignore-patch-delimiter-commands .bool_set:N=\__umi_ignore_patch_delimiter_commands,
+ ignore-patch-prime .bool_set:N=\__umi_ignore_patch_prime,
+}
+\ProcessKeysOptions{unicode-math-input}
+
+\cs_new_protected:Npn \umiMathbf {\__umi_check_math_alphabet \mathbf \umiMathbf }
+\cs_new_protected:Npn \umiMathit {\__umi_check_math_alphabet \mathit \umiMathit }
+\cs_new_protected:Npn \umiMathbfit {\__umi_check_math_alphabet \bm \umiMathbfit }
+\cs_new_protected:Npn \umiMathscr {\__umi_check_math_alphabet \mathscr \umiMathscr }
+\cs_new_protected:Npn \umiMathbfscr {\__umi_check_math_alphabet \mathbfscr \umiMathbfscr }
+\cs_new_protected:Npn \umiMathfrak {\__umi_check_math_alphabet \mathfrak \umiMathfrak }
+\cs_new_protected:Npn \umiMathbb {\__umi_check_math_alphabet \mathbb \umiMathbb }
+\cs_new_protected:Npn \umiMathbbit {\__umi_check_math_alphabet \mathbbit \umiMathbbit }
+\cs_new_protected:Npn \umiMathbffrak{\__umi_check_math_alphabet \mathbffrak \umiMathbffrak }
+\cs_new_protected:Npn \umiMathsf {\__umi_check_math_alphabet \mathsf \umiMathsf }
+\cs_new_protected:Npn \umiMathsfbf {\__umi_check_math_alphabet \mathsfbf \umiMathsfbf }
+\cs_new_protected:Npn \umiMathsfit {\__umi_check_math_alphabet \mathsfit \umiMathsfit }
+\cs_new_protected:Npn \umiMathsfbfit{\__umi_check_math_alphabet \mathsfbfit \umiMathsfbfit }
+\cs_new_protected:Npn \umiMathtt {\__umi_check_math_alphabet \mathtt \umiMathtt }
+
+\msg_new:nnn {unicode-math-input} {define-math-alphabet} {
+ Please~load~a~package~that~defines~#1,~or~manually~define~#2.
+}
+\cs_new_protected:Npn \__umi_check_math_alphabet#1#2{
+ \ifdefined#1
+ \expandafter#1
+ \else
+ \msg_error:nnnn {unicode-math-input} {define-math-alphabet} #1 #2
+ \fi
+}
+
+\msg_new:nnn {unicode-math-input} {internal-error} {
+ Internal~error!
+}
+\cs_new_protected:Npn \__umi_internal_error {
+ \msg_error:nn {unicode-math-input} {internal-error}
+}
+
+\msg_new:nnn {unicode-math-input} {undefined-cs} {
+ Please~load~a~package~that~defines~any~of~#1~to~use~this~Unicode~symbol.
+}
+% take 2 control sequences, return the first one that is defined. They must not peek ahead
+\cs_new_protected:Npn \__umi_alternatives #1 #2 {
+ \ifdefined #1
+ #1
+ \else
+ \ifdefined #2
+ #2
+ \else
+ \msg_error:nnn {unicode-math-input} {undefined-cs} {#1#2}
+ \fi
+ \fi
+}
+
+% #1 is control sequence, #2 is anything (must not peek ahead!)
+\cs_new_protected:Npn \__umi_alternatives_iisafe #1 #2 {
+ \ifdefined #1
+ \expandafter#1
+ \else
+ #2
+ \fi
+}
+
+% e.g. '\__umi_alternatives_not \nexists \exists' → \nexists or \not\exists
+% both must be control sequences
+\cs_new_protected:Npn \__umi_alternatives_not #1 #2 {
+ \ifdefined #1
+ #1
+ \else
+ \ifdefined #2
+ \not#2
+ \else
+ \msg_error:nnn {unicode-math-input} {undefined-cs} {#1#2}
+ \fi
+ \fi
+}
+
+% ======== \__umi_require_math
+\msg_new:nnn {unicode-math-input} {not-math-mode} {
+ This~symbol~can~only~be~used~in~math~mode!
+}
+\cs_new_protected:Npn \__umi_require_math {
+ \ifmmode\else \msg_error:nn {unicode-math-input} {not-math-mode} \fi
+}
+
+% ======== \__umi_define_char
+
+\msg_new:nnn {unicode-math-input} {not-single-character} {
+ Argument~must~be~a~single~character.
+}
+
+\msg_new:nnn {unicode-math-input} {not-correct-catcode} {
+ Redefining~this~special~character~in~math~mode~is~not~supported.
+}
+
+\cs_new_protected:Npn \__umi_check_before_define_char_single #1 {
+ \ifnum \str_count:n{#1}=\c_one_int
+ \int_case:nnF{\catcode `#1}{
+ {11}{} % letter
+ {12}{} % other
+ {13}{} % active
+ }{
+ % otherwise the character won't be active in math mode...
+ \msg_error:nn {unicode-math-input} {not-correct-catcode}
+ }
+ \else
+ \msg_error:nn {unicode-math-input} {not-single-character}
+ \fi
+}
+
+\int_const:Nn \__umi_active_mathcode_input {"8000} % equal to \__umi_active_mathcode unless on lualatex where the former is "1000000
+
+\cs_gset_protected:Npn \__umi_gtmp #1 {
+ \cs_new_protected:Npn \__umi_define_char_single ##1 ##2{ % this function is \__umi_define_char if simply redefining the character and setting the mathcode to "8000 suffices
+ \__umi_check_before_define_char_single{##1}
+ \global\mathcode `##1=\__umi_active_mathcode_input
+ \begingroup \lccode 0=`##1 \lowercase{\endgroup \cs_gset_protected:Npx #1} {\unexpanded{##2}} % #1 = ⟨active character with code 0⟩
+ % the code above executes '\cs_gset_protected:Npn ⟨active character with charcode ##1⟩ {##2}'
+ }
+}
+\expandafter \expandafter \expandafter \__umi_gtmp \char_generate:nn {0} {13}
+
+\ifTUTeX
+ \cs_new_eq:NN \__umi_if_engine_unicode \use_i:nn
+\else
+ \cs_new_eq:NN \__umi_if_engine_unicode \use_ii:nn
+\fi
+
+\cs_generate_variant:Nn \str_if_eq:nnTF {x}
+
+\__umi_if_engine_unicode {
+ \cs_new_eq:NN \__umi_define_char \__umi_define_char_single
+
+ % as documented in the documentation, for Unicode engines we need to handle the delimiters specially.
+ \cs_new_protected:Npn \__umi_define_char_maybe_delimiter #1 #2 {
+ \ifnum \tl_count:n {#2}=1 \else \__umi_internal_error \fi
+ \tl_if_head_is_N_type:nF {#2} {\__umi_internal_error}
+
+ \__umi_define_char #1 #2
+ \tl_build_put_right:Nn \__umi_delimiter_list {\__umi_check_delimiter #1 #2}
+ }
+
+ \msg_new:nnn {unicode-math-input} {not-delimiter} {
+ The~Unicode~character~#1~is~mapped~to~#2,~but~the~latter~is~not~determined~to~be~a~delimiter.
+ }
+
+ \cs_generate_variant:Nn \str_range:nnn {V}
+ \cs_generate_variant:Nn \cs_replacement_spec:N {c}
+
+ % e.g. \__umi_check_delimiter_aux ⟨ \langle
+ % #2 must be a single token
+ % on successful, just set (globally)
+ % on unsuccessful (if #2 is undefined) call \__umi_check_delimiter_undefined #1 #2
+ % on unsuccessful (if #2 is defined but not a delimiter) call \__umi_check_delimiter_defined_not_delimiter #1 #2
+ % caller of this function should set these 2 functions in advance
+ \cs_new_protected:Npn \__umi_check_delimiter_aux #1 #2 {
+ \begingroup
+ \escapechar=`\/~
+
+ \str_gset:Nx \g_tmpb_str {\cs_replacement_spec:N #2}
+
+ % some introspection is needed to determine what it is...
+ % e.g. 'macro:->/protect /langle ' → 'macro:->/delimiter "426830A ' (for old LaTeX versions)
+ \str_if_eq:VnT \g_tmpb_str {/protect~#2~} {
+ \str_gset:Nx \g_tmpb_str {\cs_replacement_spec:c {\cs_to_str:N #2 ~}}
+ }
+ \endgroup
+
+ \str_if_eq:VnTF \g_tmpb_str {/scan_stop:~} {
+ \__umi_check_delimiter_undefined #1 #2
+ } {
+ % e.g. '/delimiter "426830A '
+ \str_if_eq:xnTF {\str_range:Vnn \g_tmpb_str {1} {11}} {/delimiter~} {
+ %\typeout{setting delcode #1 to \int_to_hex:n {\int_mod:nn {\str_range:Vnn \g_tmpb_str {12} {-1}} {"1000000}} }
+ \global\delcode `#1 = \int_mod:nn {\str_range:Vnn \g_tmpb_str {12} {-1}} {"1000000} \relax
+ } {
+ %\typeout{>> |\g_tmpb_str|}
+ \__umi_check_delimiter_defined_not_delimiter #1 #2
+ }
+ }
+ }
+
+
+ \cs_new_eq:NN \umiDefineMathChar \__umi_define_char_single
+ \cs_new_protected:Npn \umiDefineMathDelimiter #1 #2 {
+ \cs_new_protected:Npn \__umi_check_delimiter_defined_not_delimiter ##1 ##2 {
+ \msg_error:nnnn {unicode-math-input} {not-delimiter} {##1} {##2}
+ }
+ \cs_new_eq:NN \__umi_check_delimiter_undefined \__umi_check_delimiter_defined_not_delimiter
+ \ifnum \str_count:n{#1}=1 \else \__umi_internal_error \fi
+ \ifnum \tl_count:n {#2}=1 \else \__umi_internal_error \fi
+ \tl_if_head_is_N_type:nF {#2} {\__umi_internal_error}
+ \__umi_define_char #1 #2
+ \__umi_check_delimiter_aux #1 #2
+ }
+
+} {
+ \cs_new:Npn \__umi_take_IeC \IeC #1 \__umi_delimiter { \unexpanded{#1} }
+
+ % internal procedure
+ % e.g.
+ % \str_set:Nn \l_tmpa_str {u8:×} \__umi_define_char_math_only {\times}
+ % the character #1 is already defined in LaTeX, check if it's LaTeX default definition (\IeC{\texttimes})
+ % if it is then change it to do a switch-case on text/math mode, otherwise raise an error
+ \cs_new_protected:Npn \__umi_define_char_math_only #1 {
+ \begingroup
+ \escapechar=`\/~
+ \str_gset:Nx \g_tmpb_str { \expandafter\meaning\csname \l_tmpa_str\endcsname }
+ \endgroup
+ \str_if_eq:xnTF { \str_range:Nnn \g_tmpb_str {1} {13} } {macro:->/IeC~} {
+ % it probably is, tack on the math definition
+ \cs_gset_protected:cpx {\l_tmpa_str} {
+ \noexpand\mode_if_math:TF {
+ \unexpanded{#1}
+ } {
+ \expandafter\expandafter\expandafter \__umi_take_IeC \csname \l_tmpa_str\endcsname \__umi_delimiter
+ }
+ } % this is already protected, no need protected@empty
+
+ % in summary if the existing definition is
+ % \u8:×:
+ % macro:->\IeC {\texttimes }
+ % then the new definition is
+ % \protected macro:->\mode_if_math:TF {\times} {\texttimes}
+ % as expected.
+ % we use \mode_if_math:TF just in case the thing inside peeks ahead.
+ } {
+ % ... cannot redefine...?
+ \__umi_internal_error
+ }
+ }
+
+ \cs_new_protected:Npn \__umi_define_char #1 #2{
+ \ifnum \str_count:n{#1}=1
+ \__umi_define_char_single #1 {#2}
+ \else
+ \str_set:Nn \l_tmpa_str{u8:#1}
+ \ifcsname \l_tmpa_str\endcsname
+ \__umi_define_char_math_only {#2}
+ \else
+ % the character is not defined, just define it
+ \cs_gset_protected:cpx {\l_tmpa_str} {\unexpanded{\__umi_require_math #2}}
+ \fi
+ \fi
+ }
+
+ \cs_new_eq:NN \__umi_define_char_maybe_delimiter \__umi_define_char
+
+ \cs_new_protected:Npn \umiDefineMathChar #1 #2{
+ \ifnum \str_count:n{#1}=1
+ \__umi_define_char_single #1 {#2}
+ \else
+ \cs_gset_protected:cpx {u8:\detokenize{#1}} {\unexpanded{\__umi_require_math #2}}
+ \fi
+ }
+ \cs_new_eq:NN \umiDefineMathDelimiter \umiDefineMathChar
+}
+
+\__umi_if_engine_unicode {
+ \tl_build_begin:N \__umi_delimiter_list
+} {}
+% we temporarily turn off the check for extra performance.
+\cs_gset_eq:NN \__umi_check_before_define_char_single_backup \__umi_check_before_define_char_single
+\cs_gset_eq:NN \__umi_check_before_define_char_single \use_none:n
+\input unicode-math-input-table.tex
+\cs_gset_eq:NN \__umi_check_before_define_char_single \__umi_check_before_define_char_single_backup
+\__umi_if_engine_unicode {
+ \tl_build_end:N \__umi_delimiter_list
+ \cs_new_protected:Npn \umiRefreshDelimiterList{
+ \cs_new_eq:NN \__umi_check_delimiter_undefined \use_none:nn
+ \cs_new_protected:Npn \__umi_check_delimiter_defined_not_delimiter ##1 ##2 {
+ \msg_warning:nnnn {unicode-math-input} {not-delimiter} {##1} {##2}
+ }
+ \cs_new_eq:NN \__umi_check_delimiter \__umi_check_delimiter_aux
+ \__umi_delimiter_list
+ }
+ \bool_if:NF\__umi_ignore_refresh_delimiter_list{
+ \AtBeginDocument{\umiRefreshDelimiterList}
+ }
+} {
+ \cs_new_eq:NN \umiRefreshDelimiterList \relax
+}
+
+\cs_new_eq:NN \__umi_special_handle \__umi_define_char
+
+\cs_new_eq:NN \umiFrac \frac
+
+% ======== after the superscript collection, \umiPrime\umiPrime... should be replaced with \dprime etc. smartly
+\cs_new_protected:Npn \umiPrime{ \__umi_prime } % indirection layer for fast meaning-equality checking
+\cs_new_eq:NN \umiPrimeNormalDefinition \umiPrime
+\cs_new_protected:Npn \__umi_prime {
+ \peek_meaning_collect_inline:Nn \umiPrime {
+ % note that ##1 misses one \prime as expands to this current function
+ \int_case:nnF { \tl_count:n {##1} } {
+ 1 {\__umi_alternatives_iisafe \dprime {\prime\prime}}
+ 2 {\__umi_alternatives_iisafe \trprime{\prime\prime\prime}}
+ 3 {\__umi_alternatives_iisafe \qprime {\prime\prime\prime\prime}}
+ } {
+ % complicated way to repeat '\prime' <count #1> times
+ \cs_gset_eq:NN \umiPrime \prime
+ \prime ##1
+ \cs_gset_eq:NN \umiPrime \umiPrimeNormalDefinition
+ }
+ }
+}
+
+% similar for backprime
+\cs_new_protected:Npn \umiBackprime{ \__umi_backprime }
+\cs_new_eq:NN \umiBackprimeNormalDefinition \umiBackprime
+\cs_new_protected:Npn \__umi_backprime {
+ \peek_meaning_collect_inline:Nn \umiBackprime {
+ \int_case:nnF { \tl_count:n {##1} } {
+ 1 {\__umi_alternatives_iisafe \backdprime {\backprime\backprime}}
+ 2 {\__umi_alternatives_iisafe \backtrprime {\backprime\backprime\backprime}}
+ } {
+ \cs_gset_eq:NN \umiBackprime \backprime
+ \backprime ##1
+ \cs_gset_eq:NN \umiBackprime \umiBackprimeNormalDefinition
+ }
+ }
+}
+
+\__umi_special_handle{ı}{\imath}
+\__umi_special_handle{ȷ}{\jmath}
+
+\__umi_special_handle{↉}{\umiFrac{0}{3} }
+\__umi_special_handle{⅒}{\umiFrac{1}{10}}
+\__umi_special_handle{⅑}{\umiFrac{1}{9} }
+\__umi_special_handle{⅛}{\umiFrac{1}{8} }
+\__umi_special_handle{⅐}{\umiFrac{1}{7} }
+\__umi_special_handle{⅙}{\umiFrac{1}{6} }
+\__umi_special_handle{⅕}{\umiFrac{1}{5} }
+\__umi_special_handle{¼}{\umiFrac{1}{4} }
+\__umi_special_handle{⅓}{\umiFrac{1}{3} }
+\__umi_special_handle{⅜}{\umiFrac{3}{8} }
+\__umi_special_handle{⅖}{\umiFrac{2}{5} }
+\__umi_special_handle{½}{\umiFrac{1}{2} }
+\__umi_special_handle{⅗}{\umiFrac{3}{5} }
+\__umi_special_handle{⅝}{\umiFrac{5}{8} }
+\__umi_special_handle{⅔}{\umiFrac{2}{3} }
+\__umi_special_handle{¾}{\umiFrac{3}{4} }
+\__umi_special_handle{⅘}{\umiFrac{4}{5} }
+\__umi_special_handle{⅚}{\umiFrac{5}{6} }
+\__umi_special_handle{⅞}{\umiFrac{7}{8} }
+\__umi_special_handle{√}{\sqrt}
+\__umi_special_handle{∛}{\sqrt[3]}
+\__umi_special_handle{∜}{\sqrt[4]}
+
+
+% ======== the following routine handles both superscript and subscript collection.
+
+% like this:
+% \__umi_superscript {12} ≡ ^{12}
+% \__umi_superscript {12}^{34} ≡ ^{1234}
+% \__umi_superscript {12}^{34}^{56} ≡ ^{123456} (unintended but okay no problem)
+% \__umi_superscript {12}' ≡ ^{12\prime} (something like this)
+% \__umi_superscript {12} \__umi_superscript {34} ≡ ^{1234}
+% \__umi_superscript {12} \__umi_superscript {34} ^{56} ≡ ^{123456}
+% we will not deal with ^\bgroup...\egroup
+
+\cs_new_protected:Npn \__umi_superscript {
+ \cs_gset_eq:NN \__umi_superscript ^
+ \cs_gset_eq:NN \__umi_script_cat ^
+ \cs_gset:Npn \__umi_script_collect_done {\cs_gset_eq:NN \__umi_superscript \__umi_superscript_normal}
+ \__umi_script
+}
+\cs_new_protected:Npn \__umi_subscript {
+ \cs_gset_eq:NN \__umi_subscript \sb
+ \cs_gset_eq:NN \__umi_script_cat \sb
+ \cs_gset:Npn \__umi_script_collect_done {\cs_gset_eq:NN \__umi_subscript \__umi_subscript_normal}
+ \__umi_script
+}
+\cs_new_eq:NN \__umi_superscript_normal \__umi_superscript
+\cs_new_eq:NN \__umi_subscript_normal \__umi_subscript
+
+% in order to use the function below the caller should (do as what \__umi_superscript does above...)
+
+\cs_new_protected:Npn \__umi_script #1 {
+ % * store the argument
+ \tl_set:Nn \l_tmpa_tl {#1}
+ % * f-expand following stuff exclude the \__umi_*script token itself which has been set to ^ or _
+ % by the code above
+ \expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
+}
+
+\cs_new_protected:Npn \__umi_continue_script_aux {
+ \peek_catcode_remove:NTF \__umi_script_cat {
+ % * in this case following is either \__umi_script token or ^{something} as usual, we handle both the same way
+ \__umi_continue_script_auxii
+ } {
+ % * following may be some other-catcode token
+ \peek_catcode:NTF ? {
+ \__umi_replace_other_active
+ } {
+ \__umi_script_collect_done
+ \__umi_script_cat{\l_tmpa_tl}
+ }
+ }
+}
+
+\cs_new_protected:Npn \__umi_continue_script_auxii #1 {
+ \tl_put_right:Nn \l_tmpa_tl {#1}
+ \expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
+}
+
+% the active mathcode value.
+\int_const:Nn \__umi_active_mathcode {\mathcode `'}
+
+\use:x{
+ \cs_new:Npn \noexpand\__umi_gobble_the_character \detokenize{the~character~} {`}
+}
+% effectively the result will be that
+% \int_eval:n {\__umi_gobble_the_character 'the character a'} = 65
+
+\cs_new_protected:Npn \__umi_replace_other_active #1 {
+ % * if following is some other-catcode and the mathcode is active, replace it with the active token and retry
+ % (we ignore the case of letter-catcode)
+ \int_compare:nNnTF {\mathcode \expandafter \__umi_gobble_the_character \meaning #1} = {\__umi_active_mathcode} {
+ \expandafter \__umi_continue_script_aux \exp:w\exp_end_continue_f:w
+ \char_generate:nn {\expandafter \__umi_gobble_the_character \meaning #1} {13}
+ } {
+ \cs_gset_eq:NN \__umi_script \__umi_put_script_normal
+ ^{\l_tmpa_tl} #1
+ }
+}
+
+% ======== patch \big etc.
+
+
+\__umi_if_engine_unicode {
+ \cs_new_eq:NN \umiPatchCmdUnicodeArg \use_none:n
+ \cs_new_eq:NN \umiPatchCmdUnicodeArgExtraGroup \use_none:n
+ \cs_new_eq:NN \umiPatchCmdUnicodeTwoArgs \use_none:n
+ \cs_new_eq:NN \umiUnpatchCmdUnicodeArg \use_none:n
+} {
+
+ % usage:
+ % \umiBraceNext {abc...} xyz... ≡ abc... xyz...
+ % \umiBraceNext {abc...} αyz... ≡ abc... {α}yz...
+ \cs_new_protected:Npn \umiBraceNext #1 {
+ \tl_set:Nn \l_tmpa_tl {#1}
+ \peek_N_type:TF {
+ \__umi_brace_next_aux
+ } {
+ \l_tmpa_tl
+ }
+ }
+
+ \cs_new_protected:Npn \__umi_brace_next_aux #1 {
+ \begingroup
+ \escapechar=`\\~ % just in case there's \⟨single byte⟩ ...
+ \int_compare:nNnTF {\str_count:n {#1}} = {1} {
+ \endgroup
+ \csname __umi_brace_handle_\string#1 \endcsname
+ } {
+ \endgroup
+ \l_tmpa_tl
+ }
+ #1
+ }
+
+ \def \__umi_brace_error {\__umi_internal_error \l_tmpa_tl}
+ \def \__umi_brace_two #1 #2 {\l_tmpa_tl {#1 #2}}
+ \def \__umi_brace_three #1 #2 #3 {\l_tmpa_tl {#1 #2 #3}}
+ \def \__umi_brace_four #1 #2 #3 #4 {\l_tmpa_tl {#1 #2 #3 #4}}
+
+ \int_step_inline:nnn {"00} {"7F} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \relax
+ }
+ \int_step_inline:nnn {"80} {"BF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_error
+ }
+ \int_step_inline:nnn {"C0} {"DF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_two
+ }
+ \int_step_inline:nnn {"E0} {"EF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_three
+ }
+ \int_step_inline:nnn {"F0} {"F7} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_four
+ }
+ \int_step_inline:nnn {"F8} {"FF} {
+ \expandafter\let\csname __umi_brace_handle_ \char_generate:nn {#1} {12} \endcsname \__umi_brace_error
+ }
+
+ \cs_new_protected:Npn \umiPatchCmdUnicodeArg #1 { % #1 = \big
+ \exp_args:NNc \__umi_patch_cmd_aux #1 {umi-before-patch~\cs_to_str:N #1}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_aux #1 #2 { % #1 = \big, #2 = \umi-before-patch␣big
+ \cs_new_eq:NN #2 #1 % error if #2 already defined i.e. already patched
+ \cs_gset_protected:Npn #1 {\umiBraceNext #2}
+ }
+
+ % the situation for \big / \bigl is a bit complicated -- \bigl = \mathopen \big,
+ % and \mathopen expect implicit {...} right after it without any assignment
+ % while it's possible to patch the source code of \big in a more sophisticated way to keep the implicit group
+ % it's simpler to just pile on another implicit group...
+ % consequently, \Bigl etc. does not need patching
+ \cs_new_protected:Npn \umiPatchCmdUnicodeArgExtraGroup #1 { % #1 = \big
+ \exp_args:NNc \__umi_patch_cmd_extra_group_aux #1 {umi-before-patch~\cs_to_str:N #1}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_extra_group_aux #1 #2 { % #1 = \big, #2 = \umi-before-patch␣big
+ \cs_new_eq:NN #2 #1 % error if #2 already defined i.e. already patched
+ \cs_gset_protected:Npn #1 {\bgroup \umiBraceNext {\__umi_patch_cmd_extra_group_auxii #2}}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_extra_group_auxii #1 #2 { #1 {#2} \egroup }
+
+ \cs_new_protected:Npn \umiPatchCmdUnicodeTwoArgs #1 {
+ \exp_args:NNc \__umi_patch_cmd_two_aux #1 {umi-before-patch~\cs_to_str:N #1}
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_two_aux #1 #2 { % #1 = \frac, #2 = \umi-before-patch␣frac
+ \cs_new_eq:NN #2 #1
+ \cs_gset_protected:Npn #1 {
+ \umiBraceNext {\__umi_patch_cmd_two_auxii #2}
+ }
+ }
+ \cs_new_protected:Npn \__umi_patch_cmd_two_auxii #1 #2 { % #1 = \umi-before-patch␣frac, #2 = {α}
+ \umiBraceNext {
+ #1 {#2}
+ }
+ }
+
+ \msg_new:nnn {unicode-math-input} {unpatch-without-patch} {
+ #1 was~not~patched!
+ }
+ \cs_new_protected:Npn \umiUnpatchCmdUnicodeArg #1 {
+ \bgroup \exp_args:NNc \egroup \__umi_unpatch_cmd {umi-before-patch~\cs_to_str:N #1} #1
+ }
+ \cs_new_protected:Npn \__umi_unpatch_cmd #1 #2 {
+ \ifdefined #1 \else \msg_error:nnn {unicode-math-input} {unpatch-without-patch} {#2} \fi
+ \cs_gset_eq:NN #2 #1
+ \cs_undefine:N #1
+ }
+
+ \bool_if:NF\__umi_ignore_patch_delimiter_commands{
+ \AtBeginDocument{
+ \umiPatchCmdUnicodeArgExtraGroup \big
+ \umiPatchCmdUnicodeArgExtraGroup \Big
+ \umiPatchCmdUnicodeArgExtraGroup \bigg
+ \umiPatchCmdUnicodeArgExtraGroup \Bigg
+ }
+ }
+
+}
+
+
+% ======== definitions.
+
+\msg_new:nnn {unicode-math-input} {prime-already-patched} {
+ The~'~symbol~is~already~patched,~call~umiUnpatchPrime~first.
+}
+\msg_new:nnn {unicode-math-input} {prime-not-patched} {
+ The~'~symbol~is~not~patched,~call~umiPatchPrime~first.
+}
+
+\cs_new_protected:Npn \umiPatchPrime {
+ \ifdefined \__umi_prime_backup
+ \msg_error:nn {unicode-math-input} {prime-already-patched}
+ \else
+ \__umi_backup_prime_definition
+ \__umi_special_handle{'}{\__umi_superscript \umiPrime}
+ \fi
+}
+
+\cs_new_protected:Npn \umiUnpatchPrime {
+ \ifdefined \__umi_prime_backup
+ \__umi_restore_prime_definition
+ \cs_undefine:N \__umi_prime_backup
+ \else
+ \msg_error:nn {unicode-math-input} {prime-not-patched}
+ \fi
+}
+
+
+\cs_gset_protected:Npn \__umi_gtmp #1 { % auxiliary to define the following commands where #1 is \cA\'
+ \cs_new_protected:Npn \__umi_backup_prime_definition {
+ \cs_gset_eq:NN \__umi_prime_backup #1
+ }
+ \cs_new_protected:Npn \__umi_restore_prime_definition {
+ \cs_gset_eq:NN #1 \__umi_prime_backup
+ }
+}
+\expandafter \expandafter \expandafter \__umi_gtmp \char_generate:nn {`'} {13}
+
+\bool_if:NF\__umi_ignore_patch_prime{
+ \AtBeginDocument{\umiPatchPrime}
+}
+
+\__umi_special_handle{′}{\__umi_superscript \umiPrime}
+\__umi_special_handle{″}{\__umi_superscript{\umiPrime\umiPrime}}
+\__umi_special_handle{‴}{\__umi_superscript{\umiPrime\umiPrime\umiPrime}}
+\__umi_special_handle{⁗}{\__umi_superscript{\umiPrime\umiPrime\umiPrime\umiPrime}}
+\__umi_special_handle{‵}{\__umi_superscript \umiBackprime}
+\__umi_special_handle{‶}{\__umi_superscript{\umiBackprime\umiBackprime}}
+\__umi_special_handle{‷}{\__umi_superscript{\umiBackprime\umiBackprime\umiBackprime}}
+
+\__umi_special_handle{⁰}{\__umi_superscript 0}
+\__umi_special_handle{¹}{\__umi_superscript 1}
+\__umi_special_handle{²}{\__umi_superscript 2}
+\__umi_special_handle{³}{\__umi_superscript 3}
+\__umi_special_handle{⁴}{\__umi_superscript 4}
+\__umi_special_handle{⁵}{\__umi_superscript 5}
+\__umi_special_handle{⁶}{\__umi_superscript 6}
+\__umi_special_handle{⁷}{\__umi_superscript 7}
+\__umi_special_handle{⁸}{\__umi_superscript 8}
+\__umi_special_handle{⁹}{\__umi_superscript 9}
+\__umi_special_handle{⁺}{\__umi_superscript +}
+\__umi_special_handle{⁻}{\__umi_superscript -}
+\__umi_special_handle{⁼}{\__umi_superscript =}
+\__umi_special_handle{⁽}{\__umi_superscript (}
+\__umi_special_handle{⁾}{\__umi_superscript )}
+\__umi_special_handle{ᴬ}{\__umi_superscript A}
+\__umi_special_handle{ᴮ}{\__umi_superscript B}
+\__umi_special_handle{ᴰ}{\__umi_superscript D}
+\__umi_special_handle{ᴱ}{\__umi_superscript E}
+\__umi_special_handle{ᴳ}{\__umi_superscript G}
+\__umi_special_handle{ᴴ}{\__umi_superscript H}
+\__umi_special_handle{ᴵ}{\__umi_superscript I}
+\__umi_special_handle{ᴶ}{\__umi_superscript J}
+\__umi_special_handle{ᴷ}{\__umi_superscript K}
+\__umi_special_handle{ᴸ}{\__umi_superscript L}
+\__umi_special_handle{ᴹ}{\__umi_superscript M}
+\__umi_special_handle{ᴺ}{\__umi_superscript N}
+\__umi_special_handle{ᴼ}{\__umi_superscript O}
+\__umi_special_handle{ᴾ}{\__umi_superscript P}
+\__umi_special_handle{ᴿ}{\__umi_superscript R}
+\__umi_special_handle{ᵀ}{\__umi_superscript T}
+\__umi_special_handle{ᵁ}{\__umi_superscript U}
+\__umi_special_handle{ⱽ}{\__umi_superscript V}
+\__umi_special_handle{ᵂ}{\__umi_superscript W}
+\__umi_special_handle{ᵃ}{\__umi_superscript a}
+\__umi_special_handle{ᵇ}{\__umi_superscript b}
+\__umi_special_handle{ᶜ}{\__umi_superscript c}
+\__umi_special_handle{ᵈ}{\__umi_superscript d}
+\__umi_special_handle{ᵉ}{\__umi_superscript e}
+\__umi_special_handle{ᶠ}{\__umi_superscript f}
+\__umi_special_handle{ᵍ}{\__umi_superscript g}
+\__umi_special_handle{ʰ}{\__umi_superscript h}
+\__umi_special_handle{ⁱ}{\__umi_superscript i}
+\__umi_special_handle{ʲ}{\__umi_superscript j}
+\__umi_special_handle{ᵏ}{\__umi_superscript k}
+\__umi_special_handle{ˡ}{\__umi_superscript l}
+\__umi_special_handle{ᵐ}{\__umi_superscript m}
+\__umi_special_handle{ⁿ}{\__umi_superscript n}
+\__umi_special_handle{ᵒ}{\__umi_superscript o}
+\__umi_special_handle{ᵖ}{\__umi_superscript p}
+\__umi_special_handle{ʳ}{\__umi_superscript r}
+\__umi_special_handle{ˢ}{\__umi_superscript s}
+\__umi_special_handle{ᵗ}{\__umi_superscript t}
+\__umi_special_handle{ᵘ}{\__umi_superscript u}
+\__umi_special_handle{ᵛ}{\__umi_superscript v}
+\__umi_special_handle{ʷ}{\__umi_superscript w}
+\__umi_special_handle{ˣ}{\__umi_superscript x}
+\__umi_special_handle{ʸ}{\__umi_superscript y}
+\__umi_special_handle{ᶻ}{\__umi_superscript z}
+\__umi_special_handle{ᵝ}{\__umi_superscript \beta}
+\__umi_special_handle{ᵞ}{\__umi_superscript \gamma}
+\__umi_special_handle{ᵟ}{\__umi_superscript \delta}
+\__umi_special_handle{ᵠ}{\__umi_superscript \phi}
+\__umi_special_handle{ᵡ}{\__umi_superscript \chi}
+\__umi_special_handle{ᶿ}{\__umi_superscript \theta}
+
+\__umi_special_handle{₀}{\__umi_subscript 0}
+\__umi_special_handle{₁}{\__umi_subscript 1}
+\__umi_special_handle{₂}{\__umi_subscript 2}
+\__umi_special_handle{₃}{\__umi_subscript 3}
+\__umi_special_handle{₄}{\__umi_subscript 4}
+\__umi_special_handle{₅}{\__umi_subscript 5}
+\__umi_special_handle{₆}{\__umi_subscript 6}
+\__umi_special_handle{₇}{\__umi_subscript 7}
+\__umi_special_handle{₈}{\__umi_subscript 8}
+\__umi_special_handle{₉}{\__umi_subscript 9}
+\__umi_special_handle{₊}{\__umi_subscript +}
+\__umi_special_handle{₋}{\__umi_subscript -}
+\__umi_special_handle{₌}{\__umi_subscript =}
+\__umi_special_handle{₍}{\__umi_subscript (}
+\__umi_special_handle{₎}{\__umi_subscript )}
+\__umi_special_handle{ₐ}{\__umi_subscript a}
+\__umi_special_handle{ₑ}{\__umi_subscript e}
+\__umi_special_handle{ₕ}{\__umi_subscript h}
+\__umi_special_handle{ᵢ}{\__umi_subscript i}
+\__umi_special_handle{ⱼ}{\__umi_subscript j}
+\__umi_special_handle{ₖ}{\__umi_subscript k}
+\__umi_special_handle{ₗ}{\__umi_subscript l}
+\__umi_special_handle{ₘ}{\__umi_subscript m}
+\__umi_special_handle{ₙ}{\__umi_subscript n}
+\__umi_special_handle{ₒ}{\__umi_subscript o}
+\__umi_special_handle{ₚ}{\__umi_subscript p}
+\__umi_special_handle{ᵣ}{\__umi_subscript r}
+\__umi_special_handle{ₛ}{\__umi_subscript s}
+\__umi_special_handle{ₜ}{\__umi_subscript t}
+\__umi_special_handle{ᵤ}{\__umi_subscript u}
+\__umi_special_handle{ᵥ}{\__umi_subscript v}
+\__umi_special_handle{ₓ}{\__umi_subscript x}
+\__umi_special_handle{ᵦ}{\__umi_subscript \beta}
+\__umi_special_handle{ᵧ}{\__umi_subscript \gamma}
+\__umi_special_handle{ᵨ}{\__umi_subscript \rho}
+\__umi_special_handle{ᵩ}{\__umi_subscript \phi}
+\__umi_special_handle{ᵪ}{\__umi_subscript \chi}