% \iffalse meta-comment
%
%% Copyright (C) 2026 by Marcel Krueger
%%
%% This file may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either
%% version 1.3c of this license or (at your option) any later
%% version. The latest version of this license is in:
%%
%% http://www.latex-project.org/lppl.txt
%%
%% and version 1.3 or later is part of all distributions of
%% LaTeX version 2005/12/01 or later.
%
%<*gobble>
\expandafter\ifx\csname @currname\endcsname\empty
\csname fi\endcsname
%</gobble>
%<*driver>
\documentclass[full,a4paper]{l3doc}
\usepackage{booktabs}
\usepackage{lua-unicode-math}
\MakeShortVerb{\|}
\begin{document}
\DocInput{lua-unicode-math.dtx}
% \PrintIndex
% \PrintChanges
\end{document}
%</driver>
%<*gobble>
\fi
%</gobble>
% \fi
%
% \GetFileInfo{lua-unicode-math.sty}
% \title{The \pkg{lua-unicode-math} package\thanks{This document
%        corresponds to \pkg{lua-unicode-math}~\fileversion, dated~\filedate.}}
% \author{Marcel Kr\"uger \\ \href{mailto:tex@2krueger.de}{tex@2krueger.de} \\ \url{https://github.com/zauguin/lua-unicode-math}}
% 
% \let\fntname\texttt
% \maketitle
% \begin{documentation}
% Modern fonts are usually provided in OpenType format and are designed for Unicode
% based input. For mathematical fonts this usually means the use of fonts with an OpenType MATH table:
% Fonts containing special metadata needed to make them usable in a mathematical context.
%
% In Lua\TeX{} such fonts have traditionally been loaded with the \pkg{unicode-math} package.
% While this works, is very flexible and allows to use the same document in Xe\TeX{} and Lua\TeX{} it has performance issues and it sometimes has unexpected interactions with the use of math versions. The \pkg{lua-unicode-math} is a specific Lua\LaTeX{} specific alternative which aims for higher performance and better integration with native Lua\TeX{} features.
%
% \section{Usage instructions}
% \subsection{Font packages}
% For most Opentype the recommended way to load them with \pkg{lua-unicode-math} is to use a dedicated package.
% Currently the following packages are shipped with \pkg{lua-unicode-math}:
% \begin{tabular}{ll}
% \toprule
% Font & Package \\
% \midrule
% Latin Modern Math & lum-lmodern \\
% New Computer Modern Math & lum-newcomputermodern \\
% New Computer Modern Sans Math & lum-newcomputermodernsans \\
% STIX2 & lum-stix2 \\
% XITS & lum-xits \\
% TeX Gyre Pagella Math & lum-pagella \\
% TeX Gyre DejaVu Math & lum-dejavu \\
% TeX Gyre Bonum Math & lum-bonum \\
% TeX Gyre Schola Math & lum-schola \\
% TeX Gyre Termes Math & lum-termes \\
% Fira Math & lum-fira \\
% GFS Neohellenic Math & lum-gfsneohellenic \\
% Erewhon Math & lum-erewhon \\
% XCharter Math & lum-xcharter \\
% Concrete Math & lum-concrete \\
% Euler Math & lum-euler \\
% Arsenal Math & lum-arsenal \\
% Asana Math & lum-asana \\
% Garamond Math & lum-garamond \\
% Lete Sans Math & lum-lete-sans \\
% Luciole Math & lum-luciole \\
% Old Standard Math & lum-oldstandard \\
% IBM Plex Math & lum-plex \\
% Libertinus Math & lum-libertinus \\
% KpMath Sans & lum-kpmath-sans \\
% \bottomrule
% \end{tabular}
%
% \subsection{Loading fonts by name}
% If you want to use a custom font, you can load \pkg{fontspec} and \pkg{lua-unicode-math}
% using
% \begin{verbatim}
% \usepackage{fontspec,lua-unicode-math}
% \end{verbatim}
% This will load \fntname{Latin Modern Math} by default. Another math font can be loaded using \cs{setmathfont} using the same options as \pkg{fontspec}'s \cs{newfontfamily}.
% Be aware that this does not support additional options supported by \pkg{unicode-math}, especially \texttt{version}, \texttt{range}, \texttt{s[s]cript-features}, \texttt{s[s]cript-font}.
% For example, you can use to to configure the current math font using
% \begin{verbatim}
% \setmathfont[AutoFakeBold=1]{Latin Modern Math}
% \end{verbatim}
%
% Sometimes you might want to use different math fonts in the same document. This can be done by defining multiple math versions.
% In order to do this with a \pkg{fontspec} compatible interface use
% \begin{verbatim}
% \setmathfontversion{special-version}{XITS Math}
% \end{verbatim}
% Afterwards in the document you can switch to the new math font using
% \begin{verbatim}
% \mathversion{special-version}
% \end{verbatim}
%
% \subsection{Writing maths}
% There are two ways of entering math: You can directly input Unicode math symbols or use regular \LaTeX{} commands for symbols.
% All Unicode symbols are supported with the same commands as in \pkg{unicode-math}. For a full list see \texttt{texdoc unimath-symbols}.
%
% \subsection{Selecting math style}
% \textit{Selecting math style is considered experimental and the interface is not stable.}
%
% The \pkg{unicode-math} package allows to configure a math style through package options. It is
% used to configure which characters are upright or italic in the default math alphabet (\texttt{\symnormal}).
% To configure similar settings in \pkg{lua-unicode-math}, you can select an instance of the \texttt{lua-unicode-math-style} template.
%
% There are four supported styles:
% \begin{description}
%   \item[TeX] Attempt to be compatible with traditional \TeX{} conventions. This is the default. Everything is italic by default except for capital greek letters which are upright.
%   \item[ISO80000-2] Attempt to be compliant with ISO 80000-2 rules. Everything is italic.
%   \item[french] Latin lowercase is italic, everything else is upright.
%   \item[upright] Everything is upright.
% \end{description}
% One of the styles can be selected by running \texttt{\cs{UseInstance}\{lua-unicode-math-style\}\{\meta{style}\}} in your preamble, e.g.
% \begin{verbatim}
% \UseInstance{lua-unicode-math-style}{ISO80000-2}
% \end{verbatim}
% \end{documentation}
% \begin{implementation}
% \section{Implementation}
%    \begin{macrocode}
\ProvidesExplPackage
  {lua-unicode-math}
  {2026-09-14}
  {0.11}
  {Opentype Math support for LuaLaTeX}

%<@@=l_uni_math>
\tl_new:N \l__l_uni_math_main_family_tl
\tl_new:N \l__l_uni_math_script_family_tl
\tl_new:N \l__l_uni_math_scriptscript_family_tl

\cs_generate_variant:Nn \tl_if_eq:nnT {o}

\msg_new:nnn { lua-unicode-math } { engine-unsupported } {
  lua-unicode-math~can~only~be~used~with~LuaTeX.
}

\sys_if_engine_luatex:F {
  \msg_critical:nn { lua-unicode-math } { engine-unsupported }
}

\msg_new:nnn { lua-unicode-math } { unicode-math-suppressed } {
  You~tried~to~load~both~lua-unicode-math~and~unicode-math~
  in~the~same~document.~This~is~not~supported,~unicode-math~
  will~be~suppressed.~There~is~a~good~chance~that~this~will~
  break~your~document.~Change~your~document~to~only~use~lua-unicode-math~
  so~solve~this.
}
\msg_new:nnn { lua-unicode-math } { unicode-math-loaded } {
  You~tried~to~load~lua-unicode-math~while~unicode-math~
  was~already~loaded.~This~does~not~work.~Please~avoid~loading~
  unicode-math.~If~that~is~not~possible~and~you~are~feeling~adventurous~
  you~can~try~loading~the~lua-unicode-math~package~at~the~beginning~
  of~your~document~instead~to~suppress~unicode-math.
}
\declare@file@substitution{amssymb.sty}{lua-unicode-math--amssymb.sty}
\declare@file@substitution{amsfonts.sty}{lua-unicode-math--amsfonts.sty}
\disable@package@load{unicode-math} {
  \msg_warning:nn { lua-unicode-math } {unicode-math-suppressed }
}
\IfPackageLoadedTF {unicode-math} {
  \msg_critical:nn { lua-unicode-math } {unicode-math-loaded }
} {}


\hook_gput_code:nnn { package/fontspec/after } {.} {
  \bool_gset_false:N \g__fontspec_math_bool

  \NewDocumentCommand \setmathfont { O{} m O{} } {
    \setfontfamily
      \g__l_uni_math_font_text_font
      { #2 }
      [ #1, #3, Script = Math, Renderer = Base ]
    \tl_set_eq:NN \l__l_uni_math_main_family_tl \l_fontspec_family_tl

    \setfontfamily
      \g__l_uni_math_font_script_font
      { #2 }
      [ #1, #3, Script = Math, Renderer = Base, Style = MathScript ]
    \tl_set_eq:NN \l__l_uni_math_script_family_tl \l_fontspec_family_tl

    \setfontfamily
      \g__l_uni_math_font_scriptscript_font
      { #2 }
      [ #1, #3, Script = Math, Renderer = Base, Style = MathScriptScript ]
    \tl_set_eq:NN \l__l_uni_math_scriptscript_family_tl \l_fontspec_family_tl

    \DeclareMathScriptfontMapping {TU} {\l__l_uni_math_main_family_tl} {TU} {\l__l_uni_math_script_family_tl} {TU} {\l__l_uni_math_scriptscript_family_tl}

    \exp_args:NnnV \DeclareSymbolFont {lummain} {TU} \l__l_uni_math_main_family_tl {m} {n}
    \exp_args:NnnnV \SetSymbolFont {lummain} {bold} {TU} \l__l_uni_math_main_family_tl {b} {n}
  }

  \NewDocumentCommand \setmathfontversion { m O{} m O{} } {
    \exp_args:NNe \tl_if_in:NnF \version@list { \exp_not:c { mv@ #1 } } {
      \DeclareMathVersion { #1 }
    }

    \setfontface
      \g__l_uni_math_font_text_font
      { #3 }
      [ #2, #4, Script = Math, Renderer = Base ]
    \tl_set_eq:NN \l__l_uni_math_main_family_tl \l_fontspec_family_tl

    \setfontface
      \g__l_uni_math_font_script_font
      { #3 }
      [ #2, #4, Script = Math, Renderer = Base, Style = MathScript ]
    \tl_set_eq:NN \l__l_uni_math_script_family_tl \l_fontspec_family_tl

    \setfontface
      \g__l_uni_math_font_scriptscript_font
      { #3 }
      [ #2, #4, Script = Math, Renderer = Base, Style = MathScriptScript ]
    \tl_set_eq:NN \l__l_uni_math_scriptscript_family_tl \l_fontspec_family_tl

    \DeclareMathScriptfontMapping {TU} {\l__l_uni_math_main_family_tl} {TU} {\l__l_uni_math_script_family_tl} {TU} {\l__l_uni_math_scriptscript_family_tl}

    \exp_args:NnnnV \SetSymbolFont {lummain} {#1} {TU} \l__l_uni_math_main_family_tl {m} {n}
  }

  \cs_set:Nn \__fontspec_setmainfont_hook:nn
    {
      \tl_if_eq:onT {\g__fontspec_mathrm_tl} {\rmdefault}
        {
          \fontspec_gset_family:Nnn \g__fontspec_mathrm_tl {Renderer=Basic,#1} {#2}
          \__fontspec_setmathrm_hook:nn {#1} {#2}
        }
    }
  \cs_set:Nn \__fontspec_setsansfont_hook:nn
    {
      \tl_if_eq:onT {\g__fontspec_mathsf_tl} {\sfdefault}
        {
          \fontspec_gset_family:Nnn \g__fontspec_mathsf_tl {Renderer=Basic,#1} {#2}
          \__fontspec_setmathsf_hook:nn {#1} {#2}
        }
    }
  \cs_set:Nn \__fontspec_setmonofont_hook:nn
    {
      \tl_if_eq:onT {\g__fontspec_mathtt_tl} {\ttdefault}
        {
          \fontspec_gset_family:Nnn \g__fontspec_mathtt_tl {Renderer=Basic,#1} {#2}
          \__fontspec_setmathtt_hook:nn {#1} {#2}
        }
    }
  \cs_set:Nn \__fontspec_setmathrm_hook:nn
    {
      \SetMathAlphabet \mathrm { normal } \g_fontspec_encoding_tl \g__fontspec_mathrm_tl { \mdseries@rm } \shapedefault
      \SetMathAlphabet \mathit { normal } \g_fontspec_encoding_tl \g__fontspec_mathrm_tl { \mdseries@rm } \itdefault
      \SetMathAlphabet \mathbf { normal } \g_fontspec_encoding_tl \g__fontspec_mathrm_tl { \bfseries@rm } \shapedefault
    }
  \cs_set:Nn \__fontspec_setboldmathrm_hook:nn
    {
      \SetMathAlphabet \mathrm { bold } \g_fontspec_encoding_tl \g__fontspec_bfmathrm_tl { \mdseries@rm } \shapedefault
      \SetMathAlphabet \mathit { bold } \g_fontspec_encoding_tl \g__fontspec_bfmathrm_tl { \mdseries@rm } \itdefault
      \SetMathAlphabet \mathbf { bold } \g_fontspec_encoding_tl \g__fontspec_bfmathrm_tl { \bfseries@rm } \shapedefault
    }
  \cs_set:Nn \__fontspec_setmathsf_hook:nn
    {
      \SetMathAlphabet \mathsf { normal } \g_fontspec_encoding_tl \g__fontspec_mathsf_tl { \mdseries@rm } \shapedefault
      \SetMathAlphabet \mathsf { bold } \g_fontspec_encoding_tl \g__fontspec_mathsf_tl { \bfseries@rm } \shapedefault
    }
  \cs_set:Nn \__fontspec_setmathtt_hook:nn
    {
      \SetMathAlphabet \mathtt { normal } \g_fontspec_encoding_tl \g__fontspec_mathtt_tl { \mdseries@rm } \shapedefault
      \SetMathAlphabet \mathtt { bold } \g_fontspec_encoding_tl \g__fontspec_mathtt_tl { \bfseries@rm } \shapedefault
    }
  %
  \__fontspec_setmathrm_hook:nn {} {}
  \__fontspec_setmathsf_hook:nn {} {}
  \__fontspec_setmathtt_hook:nn {} {}
}

\cs_set_protected:Npn \operator@font {
  \@fontswitch { \font@warning{Math~mode~required~for~\string\operator@font.} } { \mathtextrm }
}

\DeclareSymbolFont {lummain} {TU} {lmm} {m} {n}
\SetSymbolFont {lummain} {bold} {TU} {lmm} {b} {n}

\newattribute \mathfamattr

\cs_if_exist:NF \slimits@ {
  \cs_set_eq:NN \slimits@ \displaylimits
}
\cs_if_exist:NF \ilimits@ {
  \cs_set_eq:NN \ilimits@ \nolimits
}
\chardef \g_l_uni_math_dots_binary_char = `⋯
\chardef \g_l_uni_math_dots_comma_char = `…
\chardef \g_l_uni_math_dots_int_char = `⋯
\chardef \g_l_uni_math_dots_other_char = `…

\cs_set_protected:Npn \DOTSB {
  \__l_uni_math_set_previous_dots_type:w \g_l_uni_math_dots_binary_char
}

\cs_set_protected:Npn \DOTSX {
  \__l_uni_math_set_previous_dots_type:w \g_l_uni_math_dots_other_char
}

\cs_set_protected:Npn \DOTSI {
  \__l_uni_math_set_previous_dots_type:w \g_l_uni_math_dots_int_char
}

\cs_set_protected:Npn \DOTSC {
  \__l_uni_math_set_previous_dots_type:w \g_l_uni_math_dots_comma_char
}

\lua_load_module:n { lua-unicode-math }

\cs_new_protected:Npn \__l_uni_math_define_mathstyle_cmd:n #1 {
    \cs_new_protected:cpx { sym #1 } ##1 {
      \group_begin:
        \mathfamattr = \use:c { c__l_uni_math_attribute_sym #1 _int }
        ##1
      \group_end:
    }
}

\int_new:N \g__l_uni_math_max_mathstyle_int
\int_gset:Nn \g__l_uni_math_max_mathstyle_int { 512 }
\cs_new:Npn \__l_uni_math_provide_mathstyle_id:n #1 {
  \cs_if_exist:cF { c__l_uni_math_attribute_sym #1 _int } {
    \int_const:cn { c__l_uni_math_attribute_sym #1 _int } { \g__l_uni_math_max_mathstyle_int }
    \int_incr:N \g__l_uni_math_max_mathstyle_int
    \__l_uni_math_define_mathstyle_cmd:n { #1 }
  }
}

% This should be 
% \tex_Umathcharnumdef:D \c__l_uni_math_attribute_unset_int = -"7FFFFFFF \scan_stop
% but LuaTeX is too buggy to save this correctly.
\tex_Umathchardef:D \c__l_uni_math_attribute_unset_int = "0 "80 "1 \scan_stop:
\tex_Umathcharnumdef:D \c__l_uni_math_attribute_symnormal_int = 1023 \scan_stop:
\cs_new_protected:Npn \symnormal #1 {
  \group_begin:
    \mathfamattr = \c__l_uni_math_attribute_unset_int
    #1
  \group_end:
}
\cs_gset:Npn \mathnormal { \symnormal }

\seq_set_from_clist:Nn \l_tmpa_seq {
  up, rm, it, tt, bf, sf
}
\seq_map_inline:Nn \l_tmpa_seq {
  \cs_new_eq:cc { mathtext #1 } { math #1 }
}
\prop_set_from_keyval:Nn \l_tmpa_prop {
  up = 0, bfup = 1, it = 2, bfit = 3,
  sfup = 4, bfsfup = 5, sfit = 6, bfsfit = 7,
  cal = 8, bfcal = 9,
  scr = 12, bfscr = 13,
  frak = 16, bffrak = 17,
  tt = 20,
  bb = 24,
}
\prop_map_inline:Nn \l_tmpa_prop {
  \int_const:cn { c__l_uni_math_attribute_sym #1 _int } { #2 }
  \__l_uni_math_define_mathstyle_cmd:n { #1 }
  \cs_set_eq:cc { math #1 } { sym #1 }
}
\cs_set_eq:NN \symrm \symup
\cs_set_eq:NN \mathtextup \mathtextrm
\cs_set_eq:NN \mathtextsf \mathsf
\cs_set:Npn \mathbfsf { \symbfsf }

\seq_map_inline:Nn \l_tmpa_seq {
  \cs_set_eq:cc { math #1 } { mathtext #1 }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathord :nn } #1 #2 {
  \cs_set:Npx #1 {
    \char_generate:nn {#2} {12}
  }
}
\tl_map_inline:nn {\mathbin \mathclose \mathpunct \mathrel} {
  \cs_new_eq:cc
    { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N #1 :nn }
    { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathord :nn }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathop :nn } #1 #2 {
  \exp_args:Nc \Umathchardef { \cs_to_str:N #1 op } 1~\symlummain #2~
  \cs_set:Npx #1 {
    \char_generate:nn {#2} {12}
  }
  \mathcode #2 = "8000~
  \cs_set:cpx { \char_generate:nn {"FFFF} {12} \char_generate:nn {#2} {12} } {
    \__l_uni_math_is_integral_cp:wTF #2 { \DOTSI } { \DOTSB }
    \use:c { \cs_to_str:N #1 op }
    \__l_uni_math_is_integral_cp:wTF #2 { \ilimits@ } { \slimits@ }
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathopen :nn } #1 #2 {
  \token_if_eq_meaning:NNTF #1 \sqrt {
    \cs_set:Npx \sqrtsign {
      \Uradical \symlummain #2~
    }
    \cs_set:Npx \root ##1 \of {
      \Uroot \symlummain #2~ { ##1 }
    }
  }{
    \cs_set:Npx #1 {
      \char_generate:nn {#2} {12}
    }
  }
}

% For a \mathalpha command starting with \mup like \mupalpha this will be called as
% \__l_uni_math_uproot_assign_mup_char:nNn {alpha} \Alpha {"...}
\cs_new_protected:Npn \__l_uni_math_uproot_assign_mup_char:nNn #1 #2 #3 {
    \cs_set:Npx #2 {
      \symup {\char_generate:nn {#3} {12}}
    }
    \cs_set:cpx {#1} {
      \char_generate:nn {#3} {12}
    }
}

% For a \mathalpha command not starting with \mup this will be called as \__l_uni_math_uproot_assign_mup_char:nNn {} \cmd {"...}
\cs_new_protected:Npn \__l_uni_math_uproot_assign_nonmup_alpha:nNn #1 #2 #3 {
    \cs_set:Npx #2 {
      \char_generate:nn {#3} {12}
    }
}

\group_begin:
\cs_set:Npn \l_tmp_cs:n #1 {
  \group_end:

  \cs_new_protected:Npn \__l_uni_math__check_mup_helper:w ##1 #1 ##2 \q_mark ##3 ##4 \q_stop {
    ##3 {##2}
  }

  \cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathalpha :nn } ##1 {
    \exp_after:wN \__l_uni_math__check_mup_helper:w \token_to_str:N ##1 \q_mark \__l_uni_math_uproot_assign_mup_char:nNn #1 \q_mark \__l_uni_math_uproot_assign_nonmup_alpha:nNn \q_stop ##1
  }
}

\exp_args:No \l_tmp_cs:n {
  \token_to_str:N \mup
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathfence :nn } #1 #2 {
  \cs_set:Npx #1 {
    \char_generate:nn {#2} {12}
  }
  \cs_set:cpx {l \cs_to_str:N #1} {
    \Udelimiter 4 ~ \symlummain #2 ~
  }
  \cs_set:cpx {r \cs_to_str:N #1} {
    \Udelimiter 5 ~ \symlummain #2 ~
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathaccent :nn } #1 #2 {
  \cs_set_protected:Npx #1 {
    \Umathaccent fixed 0 ~ \symlummain #2 ~
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathbotaccent :nn } #1 #2 {
  \cs_set:Npx #1 {
    \Umathaccent bottom~fixed 0 ~ \symlummain #2 ~
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathaccentwide :nn } #1 #2 {
  \cs_set:Npx #1 {
    \Umathaccent 0 ~ \symlummain #2 ~
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathbotaccentwide :nn } #1 #2 {
  \cs_set:Npx #1 {
    \Umathaccent bottom 0 ~ \symlummain #2 ~
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathaccentoverlay :nn } #1 #2 {
  \cs_set:Npx #1 {
    \Umathaccent overlay 0 ~ \symlummain #2 ~
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathover :nn } #1 #2 {
  \cs_set:Npx #1 ##1 {
    \mathop {
      \Udelimiterover \symlummain #2 { ##1 }
    }
    \limits
  }
}

\cs_new:cpn { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N \mathunder :nn } #1 #2 {
  \cs_set:Npx #1 ##1 {
    \mathop {
      \Udelimiterunder \symlummain #2 { ##1 }
    }
    \limits
  }
}

\cs_generate_variant:Nn \exp_args:Ne {c}
\cs_new:Npn \UnicodeMathSymbol #1 #2 #3 #4 {
  \use:c { __l_uni_math_UnicodeMathSymbol_ \token_to_str:N #3 :nn }
    {#2} {#1}
}
\input {unicode-math-table}
\cs_undefine:N \UnicodeMathSymbol

\cs_set_protected:Npn \triangle { \mathord { \bigtriangleup } }
\cs_set_protected:Npn \mathellipsis { \mathinner { \unicodeellipsis } }
\cs_set_protected:Npn \cdots { \mathinner { \unicodecdots } }

\clist_map_inline:nn {
  \to \rightarrow,
  \le \leq,
  \ge \geq,
  \neq \ne,
  \bigcirc \mdlgwhtcircle,
  \circ \vysmwhtcircle,
  \bullet \smblkcircle,
  \yen \mathyen,
  \sterling \mathsterling,
  \diamond \smwhtdiamond,
  \emptyset \varnothing,
  \hbar \hslash,
  \land \wedge,
  \lor \vee,
  \owns \ni,
  \gets \leftarrow,
  \mathring \ocirc,
  \lnot \neg,
  \longdivision \longdivisionsign,
  \backepsilon \upbackepsilon,
  \eth \matheth,
  \dotsb@ \cdots,
  \@cdots \cdots,
  \| \Vert,
} {
  \cs_set_eq:NN #1
}

\cs_new:Npn \__l_uni_math_set_math_active:npx #1 {
  \char_set_mathcode:nn { #1 } { "8000 }
  \cs_set_protected:cpx { \char_generate:nn {"FFFF} {12} \char_generate:nn { #1 } {12} }
}

\__l_uni_math_set_math_active:npx { `\' } {
  \prime_helper:w "2032~
}

\__l_uni_math_set_math_active:npx { `\` } {
  \prime_helper:w "2035~
}

\int_step_inline:nnn {"0} {"F} {
  \__l_uni_math_set_math_active:npx { "FE00 + #1 } {
    \__l_uni_math_variation_selector:w #1 ~
  }
}

\int_step_inline:nnn {"10} {"FF} {
  \__l_uni_math_set_math_active:npx { "E00F0 + #1 } {
    \__l_uni_math_variation_selector:w #1 ~
  }
}

\cs_set_protected:Npn \uproot #1 {
  \__l_uni_math_uproot:w #1 \scan_stop:
}

\cs_set_protected:Npn \leftroot #1 {
  \__l_uni_math_leftroot:w #1 \scan_stop:
}
%    \end{macrocode}
% Some fixes for \pkg{amsmath}: Since \pkg{amsmath} is defining \cs{leftroot},
% \cs{uproot} and \cs{root} with non Unicode definitions, we need to hide our definitions
% and restore them afterwards.
% We define \cs{varGamma} to stop \pkg{amsmath} from trying to define greek letter variants.
%    \begin{macrocode}
\tl_const:Nn \c__l_uni_math_amsmath_cmds_tl {
  \uproot
  \leftroot
  \iint
  \iiint
  \iiiint
  \dddot
  \ddddot
  \overleftrightarrow
  \underrightarrow
  \underleftarrow
  \underleftrightarrow
  \hat
  \check
  \tilde
  \acute
  \grave
  \dot
  \ddot
  \breve
  \bar
  \vec
  \mathring
  \DOTSC
  \DOTSI
  \DOTSX
  \DOTSB
  \mdots@
  \cdots
  \ldots
}
\tl_const:Nn \c__l_uni_math_amsmath_cmds_defined_tl {
  \prod
  \coprod
  \bigwedge
  \bigvee
  \bigcap
  \bigcup
  \bigodot
  \bigoplus
  \bigotimes
  \bigsqcup
  \root
  \int
  \oint
  \overrightarrow
  \overleftarrow
}
\hook_gput_code:nnn { package/amsmath/before } {.} {
  \tl_map_inline:Nn \c__l_uni_math_amsmath_cmds_tl {
    \cs_new_eq:cN { __l_uni_math_saved_ \cs_to_str:N #1 } #1
    \cs_undefine:N #1
  }
  \tl_map_inline:Nn \c__l_uni_math_amsmath_cmds_defined_tl {
    \cs_new_eq:cN { __l_uni_math_saved_ \cs_to_str:N #1 } #1
  }
  \cs_set:Npn \varGamma { \temporary_definition_do_not_use }
}
\hook_gput_code:nnn { package/amsmath/after } {.} {
  \tl_map_inline:Nn \c__l_uni_math_amsmath_cmds_tl {
    \cs_set_eq:Nc #1 { __l_uni_math_saved_ \cs_to_str:N #1 }
    \cs_undefine:c { __l_uni_math_saved_ \cs_to_str:N #1 }
  }
  \tl_map_inline:Nn \c__l_uni_math_amsmath_cmds_defined_tl {
    \cs_set_eq:Nc #1 { __l_uni_math_saved_ \cs_to_str:N #1 }
    \cs_undefine:c { __l_uni_math_saved_ \cs_to_str:N #1 }
  }
  \cs_undefine:N \varGamma
}
\addto@hook \every@math@size {
  \__l_uni_math_every_math_size:
}
%    \end{macrocode}
% \subsection{Customization}
% We defined templates to customize the behavior of \pkg{lua-unicode-math}.
% The main customization point for the user is the \texttt{lua-unicode-math-style} which
% selects how \cs{symnormal} and \cs{symbf} behave.
%    \begin{macrocode}
\NewTemplateType {lua-unicode-math-style} {0}
%    \end{macrocode}
%
% In the default interface \texttt{substyles} a mathstyle is defined in terms of
% two nested instances of type \texttt{lua-unicode-math-style-cmd}. This template allows to
% define or redefine a mathstyle like \texttt{normal}, \texttt{bf} or \texttt{up} with corresponding
% \cs{sym...} command.
%    \begin{macrocode}
\NewTemplateType {lua-unicode-math-style-cmd} {1}
\DeclareTemplateInterface {lua-unicode-math-style} {substyles} {0} {
  normal: instance {lua-unicode-math-style-cmd},
  bf: instance {lua-unicode-math-style-cmd},
  sf: instance {lua-unicode-math-style-cmd},
  bfsf: instance {lua-unicode-math-style-cmd},
}
%    \end{macrocode}
%
% By default a new style command instance is defined by defining mappings for the five main
% math alphabets to existing styles.
%    \begin{macrocode}
\DeclareTemplateInterface {lua-unicode-math-style-cmd} {alphabet-style-mapping} {1} {
  Latin: tokenlist,
  latin: tokenlist,
  Greek: tokenlist,
  greek: tokenlist,
  digit: tokenlist,
}
%    \end{macrocode}
%
% By default a new style command instance is defined by defining mappings for the five main
% math alphabets to existing styles.
%    \begin{macrocode}
\DeclareTemplateCode {lua-unicode-math-style} {substyles} {0} {
  normal = \__l_uni_math_instance_normal:n,
  bf = \__l_uni_math_instance_bf:n,
  sf = \__l_uni_math_instance_sf:n,
  bfsf = \__l_uni_math_instance_bfsf:n,
} {
  \__l_uni_math_instance_normal:n { normal }
  \__l_uni_math_instance_bf:n { bf }
  \__l_uni_math_instance_sf:n { sf }
  \__l_uni_math_instance_bfsf:n { bfsf }
}
\cs_generate_variant:Nn \__l_uni_math_set_mathstyle_mappings:NNNNNN { cccccc }
\tl_new:N \l__l_uni_math_Latin_style_tl
\tl_new:N \l__l_uni_math_latin_style_tl
\tl_new:N \l__l_uni_math_Greek_style_tl
\tl_new:N \l__l_uni_math_greek_style_tl
\tl_new:N \l__l_uni_math_digit_style_tl
\DeclareTemplateCode {lua-unicode-math-style-cmd} {alphabet-style-mapping} {1} {
  Latin = \l__l_uni_math_Latin_style_tl,
  latin = \l__l_uni_math_latin_style_tl,
  Greek = \l__l_uni_math_Greek_style_tl,
  greek = \l__l_uni_math_greek_style_tl,
  digit = \l__l_uni_math_digit_style_tl,
} {
  \__l_uni_math_provide_mathstyle_id:n { #1 }
  \__l_uni_math_set_mathstyle_mappings:cccccc
    { c__l_uni_math_attribute_sym #1 _int }
    { c__l_uni_math_attribute_sym \l__l_uni_math_Latin_style_tl _int }
    { c__l_uni_math_attribute_sym \l__l_uni_math_latin_style_tl _int }
    { c__l_uni_math_attribute_sym \l__l_uni_math_Greek_style_tl _int }
    { c__l_uni_math_attribute_sym \l__l_uni_math_greek_style_tl _int }
    { c__l_uni_math_attribute_sym \l__l_uni_math_digit_style_tl _int }
}
%    \end{macrocode}
%
% Finally we define some defaults.
%    \begin{macrocode}
\DeclareInstance{lua-unicode-math-style}{TeX}{substyles}{
  normal = TeX,
  bf = TeX-bf,
  sf = upright-sf,
  bfsf = upright-bfsf,
}
\DeclareInstance{lua-unicode-math-style}{ISO80000-2}{substyles}{
  normal = ISO80000-2,
  bf = ISO80000-2-bf,
  sf = italic-sf,
  bfsf = italic-bfsf,
}
\DeclareInstance{lua-unicode-math-style}{french}{substyles}{
  normal = french,
  bf = upright-bf,
  sf = upright-sf,
  bfsf = upright-bfsf,
}
\DeclareInstance{lua-unicode-math-style}{upright}{substyles}{
  normal = upright,
  bf = upright-bf,
  sf = upright-sf,
  bfsf = upright-bfsf,
}
\DeclareInstance{lua-unicode-math-style-cmd}{TeX}{alphabet-style-mapping}{
  Latin = it,
  latin = it,
  Greek = up,
  greek = it,
  digit = up,
}
\DeclareInstance{lua-unicode-math-style-cmd}{TeX-bf}{alphabet-style-mapping}{
  Latin = bfup,
  latin = bfup,
  Greek = bfup,
  greek = bfit,
  digit = bfup,
}
\DeclareInstance{lua-unicode-math-style-cmd}{ISO80000-2}{alphabet-style-mapping}{
  Latin = it,
  latin = it,
  Greek = it,
  greek = it,
  digit = up,
}
\DeclareInstance{lua-unicode-math-style-cmd}{ISO80000-2-bf}{alphabet-style-mapping}{
  Latin = bfit,
  latin = bfit,
  Greek = bfit,
  greek = bfit,
  digit = bfup,
}
\DeclareInstance{lua-unicode-math-style-cmd}{french}{alphabet-style-mapping}{
  Latin = up,
  latin = it,
  Greek = up,
  greek = up,
  digit = up,
}
\DeclareInstance{lua-unicode-math-style-cmd}{upright}{alphabet-style-mapping}{
  Latin = up,
  latin = up,
  Greek = up,
  greek = up,
  digit = up,
}
\DeclareInstance{lua-unicode-math-style-cmd}{upright-bf}{alphabet-style-mapping}{
  Latin = bfup,
  latin = bfup,
  Greek = bfup,
  greek = bfup,
  digit = bfup,
}
\DeclareInstance{lua-unicode-math-style-cmd}{upright-sf}{alphabet-style-mapping}{
  Latin = sfup,
  latin = sfup,
  Greek = sfup,
  greek = sfup,
  digit = sfup,
}
\DeclareInstance{lua-unicode-math-style-cmd}{italic-sf}{alphabet-style-mapping}{
  Latin = sfit,
  latin = sfit,
  Greek = sfit,
  greek = sfit,
  digit = sfit,
}
\DeclareInstance{lua-unicode-math-style-cmd}{upright-bfsf}{alphabet-style-mapping}{
  Latin = bfsfup,
  latin = bfsfup,
  Greek = bfsfup,
  greek = bfsfup,
  digit = bfsfup,
}
\DeclareInstance{lua-unicode-math-style-cmd}{italic-bfsf}{alphabet-style-mapping}{
  Latin = bfsfit,
  latin = bfsfit,
  Greek = bfsfit,
  greek = bfsfit,
  digit = bfsfit,
}
\UseInstance {lua-unicode-math-style} {TeX}
%    \end{macrocode}
%
% \subsection{Math text alphabet adaption}
% When used without fontspec, the math text alphabets are not automatically replaced with Unicode fonts.
% For the common case of having Computer Modern configured as text font we are replacing the font with
% Latin Modern in base mode.
%
%    \begin{macrocode}
\group_begin:
\use:e { \cs_new:Npn \exp_not:N \__l_uni_math_helper:w #1\token_to_str:c {OT1/cm}#2\token_to_str:N /#3 } \s_stop#4\q_nil #5#6 {
  \tl_if_empty:nTF {#4} {
    #6
  } {
    #5 \exp_not:c {TU/lm#2-base/#3}
  }
}
\cs_set:Npn \alpha@elt #1 #2 #3 {
  \exp_not:N \alpha@elt \exp_not:N #1
  \exp_last_unbraced:Ne \__l_uni_math_helper:w { \token_to_str:N #3 \s_stop \token_to_str:c{OT1/cm/} \s_stop } \q_nil
    { \exp_not:N \M@TU }
    { \exp_not:N #2 \exp_not:N #3 }
}
\tl_gset:Nx \alpha@list {
  \alpha@list
}

\cs_set:Npn \getanddefine@fonts #1 #2 {
  \exp_not:n { \getanddefine@fonts #1 }
  \exp_last_unbraced:Ne \__l_uni_math_helper:w { \token_to_str:N #2 \s_stop \token_to_str:c{OT1/cm/} \s_stop } \q_nil
    {}
    { \exp_not:N #2 }
}
\cs_set:Npn \__l_uni_math_install_mathalphabet_helper:NNNN #1 #2 #3 #4 {
  \exp_not:n { #1 #2 }
  \exp_last_unbraced:Ne \__l_uni_math_helper:w { \token_to_str:N #4 \s_stop \token_to_str:c{OT1/cm/} \s_stop } \q_nil
    { \exp_not:N \M@TU }
    { \exp_not:N #3 \exp_not:N #4 }
}
\cs_set:Npn \install@mathalphabet #1 #2 {
  \exp_not:n { \install@mathalphabet #1 }
  { \__l_uni_math_install_mathalphabet_helper:NNNN #2 }
}
\cs_set:Npn \version@elt #1 {
  \tl_gset:Nx #1 {
    #1
  }
}
\version@list
\group_end:
%    \end{macrocode}
% \end{implementation}
