%%^^A%% um-code-setchar.dtx -- part of UNICODE-MATH <wspr.io/unicode-math>
%%^^A%% General assignment of maths symbols.

% \section{Setting up maths chars}
%
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \subsection{A token list to contain the data of the math table}
%
% Instead of \cmd\input-ing the unicode math table every time we
% want to re-read its data, we save it within a macro. This has two
% advantages: 1.~it should be slightly faster, at the expense of memory;
% 2.~we don't need to worry about catcodes later, since they're frozen
% at this point.
%
% In time, the case statement inside |set_mathsymbol| will be moved in here
% to avoid re-running it every time.
%
%    \begin{macrocode}
\group_begin:
  \file_get:nnN {unicode-math-table.tex} {} \l_@@_mathtable_tl
  \cs_set:Npn \UnicodeMathSymbol #1#2#3#4
    {
      \exp_not:n { \_@@_sym:nnn {#1} {#2} {#3} }
    }
  \tl_gset:Nx \g_@@_mathtable_tl {\l_@@_mathtable_tl}
\group_end:
%    \end{macrocode}
%
%
% \begin{macro}{\@@_input_math_symbol_table:}
% This function simply expands to the token list containing all the data.
%    \begin{macrocode}
\@@_cs_new:Nn \@@_input_math_symbol_table: {\g_@@_mathtable_tl}
%    \end{macrocode}
% \end{macro}
%
%
% \subsection{Definitions of the active math characters}
%
% Ensure catcodes are appropriate;
% make sure |#| is an `other' so that we don't get confused with \cs{mathoctothorpe}.
%    \begin{macrocode}
\AtBeginDocument{\@@_define_math_chars:}
\@@_cs_new:Nn \@@_define_math_chars:
 {
  \group_begin:
    \cs_set:Npn \_@@_sym:nnn ##1##2##3
     {
      \tl_if_in:nnT
       { \mathord \mathalpha \mathbin \mathrel \mathpunct \mathop \mathfence }
       {##3}
      {
        \exp_last_unbraced:NNx \cs_gset_eq:NN ##2 { \char_generate:nn {##1} {12} }
      }
     }
    \@@_input_math_symbol_table:
  \group_end:
 }
%    \end{macrocode}
%
%
%
% \subsection{Commands for each symbol/glyph/char}
%
% \begin{macro}{\@@_set_mathsymbol:nNNn}
% \darg{A \LaTeX\ symbol font, e.g., \texttt{operators}}
% \darg{Symbol macro, \eg, \cmd\alpha}
% \darg{Type, \eg, \cmd\mathalpha}
% \darg{Slot, \eg, \texttt{"221E}}
% There are a bunch of tests to perform to process the various characters.
% The following assignments should all be fairly straightforward.
%
% The catcode setting is to work around (strange?) behaviour in LuaTeX in which catcode 11 characters don't have italic correction for maths.
% We don't adjust ascii chars, however, because certain punctuation should not have their catcodes changed.
%    \begin{macrocode}
\cs_set:Nn \@@_set_mathsymbol:nNNn
 {
  \bool_lazy_and:nnT
   {
    \int_compare_p:nNn {#4} > {127}
   }
   {
    \int_compare_p:nNn { \char_value_catcode:n {#4} } = {11}
   }
   { \char_set_catcode_other:n {#4} }

  \token_case_meaning:Nn #3
   {
    \mathord   { \@@_set_mathcode:nnn {#4} {#3} {#1} }
    \mathalpha { \@@_set_mathcode:nnn {#4} {#3} {#1} }
    \mathbin   { \@@_set_mathcode:nnn {#4} {#3} {#1} }
    \mathrel   { \@@_set_mathcode:nnn {#4} {#3} {#1} }
    \mathpunct { \@@_set_mathcode:nnn {#4} {#3} {#1} }
    \mathop    { \@@_set_big_operator:nnn {#1} {#2} {#4} }
    \mathopen  { \@@_set_math_open:nnn    {#1} {#2} {#4} }
    \mathclose { \@@_set_math_close:nnn   {#1} {#2} {#4} }
    \mathfence { \@@_set_math_fence:nnnn  {#1} {#2} {#3} {#4} }
    \mathaccent
     { \@@_set_math_accent:Nnnn #2 {fixed} {#1} {#4} }
    \mathbotaccent
     { \@@_set_math_accent:Nnnn #2 {bottom~ fixed} {#1} {#4} }
    \mathaccentwide
     { \@@_set_math_accent:Nnnn #2 {} {#1} {#4} }
    \mathbotaccentwide
     { \@@_set_math_accent:Nnnn #2 {bottom} {#1} {#4} }
    \mathover
     { \@@_set_math_overunder:Nnnn #2 {} {#1} {#4} }
    \mathunder
     { \@@_set_math_overunder:Nnnn #2 {bottom} {#1} {#4} }
    \mathaccentoverlay
%<LU>     { \@@_set_math_accent:Nnnn #2 {overlay~ fixed} {#1} {#4} }
%<XE>     { \@@_set_math_accent:Nnnn #2 {} {#1} {#4} }
   }
 }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\edef\mathfence{\string\mathfence}
\edef\mathover{\string\mathover}
\edef\mathunder{\string\mathunder}
\edef\mathbotaccent{\string\mathbotaccent}
\edef\mathaccentwide{\string\mathaccentwide}
\edef\mathaccentoverlay{\string\mathaccentoverlay}
\edef\mathbotaccentwide{\string\mathbotaccentwide}
%    \end{macrocode}
%
%
% \begin{macro}{\@@_set_big_operator:nnn}
% \darg{Symbol font name}
% \darg{Macro to assign}
% \darg{Glyph slot}
% In the examples following, say we're defining for the symbol \cmd\sum\ ($\sum$).
% In order for literal Unicode characters to be used in the source and still
% have the correct limits behaviour, big operators are made math-active.
% This involves three steps:
% \begin{itemize}
% \item
% The active math char is defined to expand to the macro \cs{sum_sym}.
% (Later, the control sequence \cs{sum} will be assigned the math char.)
% \item
% Declare the plain old mathchardef for the control sequence \cmd\sumop.
% (This follows the convention of \LaTeX/\pkg{amsmath}.)
% \item
% Define \cs{sum_sym} as \cmd\sumop, followed by \cmd\nolimits\ if necessary.
% \end{itemize}
% Whether the \cmd\nolimits\ suffix is inserted is controlled by the
% token list \cs{l_@@_nolimits_tl}, which contains a list of such characters.
% This list is checked dynamically to allow it to be updated mid-document.
%
% Examples of expansion, by default, for two big operators:
% \begin{quote}
% (~\cs{sum} $\to$~) $\sum$ $\to$ \cs{sum_sym} $\to$ \cs{sumop}\cs{nolimits}\par
% (~\cs{int} $\to$~) $\int$ $\to$ \cs{int_sym} $\to$ \cs{intop}
% \end{quote}
%    \begin{macrocode}
\cs_new:Nn \@@_set_big_operator:nnn
 {
  \@@_char_gmake_mathactive:n {#3}
  \cs_set_protected_nopar:Npx \@@_tmpa: { \exp_not:c { \cs_to_str:N #2 _sym } }
  \char_gset_active_eq:nN {#3} \@@_tmpa:

  \@@_set_mathchar:cNnn {\cs_to_str:N #2 op} \mathop {#1} {#3}

  \cs_gset:cpx { \cs_to_str:N #2 _sym }
   {
    \exp_not:c { \cs_to_str:N #2 op   }
    \exp_not:n { \tl_if_in:NnT \l_@@_nolimits_tl {#2} \nolimits }
   }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_set_math_open:nnn}
% \darg{Symbol font name}
% \darg{Macro to assign}
% \darg{Glyph slot}
%    \begin{macrocode}
\cs_new:Nn \@@_set_math_open:nnn
 {
  \tl_if_in:NnTF \l_@@_radicals_tl {#2}
   {
     \cs_if_exist:NF #2
       {
         %% todo: check if the check is necessary
         \cs_gset_protected_nopar:Npx #2 { \exp_not:c { \cs_to_str:N #2 sign } }
       }
     \cs_gset_protected_nopar:cpx { \cs_to_str:N #2 sign }
       {
         \@@_radical:nn {#1} {#3}
       }
     \tl_if_exist:cF {c_@@_radical_\cs_to_str:N #2_tl}
       {
         \tl_const:cn {c_@@_radical_\cs_to_str:N #2_tl} {\use:c{sym #1}~ #3}
       }
   }
   {
     \@@_set_delcode:nnn {#1} {#3} {#3}
     \@@_set_mathcode:nnn {#3} \mathopen {#1}
     \cs_gset_protected_nopar:Npx #2
       { \@@_delimiter:Nnn \mathopen {#1} {#3} }
   }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_set_math_close:nnn}
% \darg{Symbol font name}
% \darg{Macro to assign}
% \darg{Glyph slot}
%    \begin{macrocode}
\cs_new:Nn \@@_set_math_close:nnn
 {
  \@@_set_delcode:nnn {#1} {#3} {#3}
  \@@_set_mathcode:nnn {#3} \mathclose {#1}
  \cs_gset_protected_nopar:Npx #2
    { \@@_delimiter:Nnn \mathclose {#1} {#3} }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_set_math_fence:nnnn}
% \darg{Symbol font name}
% \darg{Macro to assign}
% \darg{Type, \eg, \cmd\mathalpha}
% \darg{Glyph slot}
%    \begin{macrocode}
\cs_new:Nn \@@_set_math_fence:nnnn
 {
  \@@_set_mathcode:nnn {#4} {#3} {#1}
  \@@_set_delcode:nnn  {#1} {#4} {#4}
  \cs_gset_protected_nopar:cpx {l \cs_to_str:N #2}
    { \@@_delimiter:Nnn \mathopen  {#1} {#4} }
  \cs_gset_protected_nopar:cpx {r \cs_to_str:N #2}
    { \@@_delimiter:Nnn \mathclose {#1} {#4} }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_set_math_accent:Nnnn}
% \darg{Accend command}
% \darg{Accent type (string)}
% \darg{Symbol font name}
% \darg{Glyph slot}
%    \begin{macrocode}
\cs_new:Nn \@@_set_math_accent:Nnnn
 {
  \cs_gset_protected_nopar:Npx #1
   { \@@_accent:nnn {#2} {#3} {#4} }
 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_set_math_overunder:Nnnn}
% \darg{Accend command}
% \darg{Accent type (string)}
% \darg{Symbol font name}
% \darg{Glyph slot}
%    \begin{macrocode}
\cs_new:Nn \@@_set_math_overunder:Nnnn
 {
  \cs_gset_protected_nopar:Npx #1 ##1
   {
    \mathop
     { \@@_accent:nnn {#2} {#3} {#4} {{}##1} }
     %      TODO: remove braces above ^^ which work around a LuaTeX bug
    \limits
   }
 }
%    \end{macrocode}
% \end{macro}
%
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}

\endinput

% /©
%
% ------------------------------------------------
% The UNICODE-MATH package  <wspr.io/unicode-math>
% ------------------------------------------------
% This package is free software and may be redistributed and/or modified under
% the conditions of the LaTeX Project Public License, version 1.3c or higher
% (your choice): <http://www.latex-project.org/lppl/>.
% ------------------------------------------------
% Copyright 2006-2019  Will Robertson, LPPL "maintainer"
% Copyright 2010-2017  Philipp Stephani
% Copyright 2011-2017  Joseph Wright
% Copyright 2012-2015  Khaled Hosny
% ------------------------------------------------
%
% ©/
