%D \module
%D   [       file=math-lop,
%D        version=2022.02.10,
%D          title=\CONTEXT\ Math Macros,
%D       subtitle=Large operators,
%D         author={Hans Hagen & Mikael Sundqvist},
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

\writestatus{loading}{ConTeXt Math Macros / Large Operators}

% $\textstyle        \Uoperator          \Udelimiter "0 \fam "222B {t} {b} {x}$\blank
% $\textstyle        \Uoperator          \Udelimiter "0 \fam "222B {t} {b} {\frac{1}{x}}$\blank
% $\displaystyle x + \Uoperator          \Udelimiter "0 \fam "222B {t} {b} {\frac{1}{x}}$\blank
% $              x + \Uoperator nolimits \Udelimiter "0 \fam "222B {t} {b} {\frac{1}{x}}$\blank
% $              x + \Uoperator limits   \Udelimiter "0 \fam "222B {t} {b} {\frac{1}{x}}$\blank

\unprotect

\installcorenamespace{mathoperators}
\installcorenamespace{mathoperatormethod}

\mathlimitsmode\plusone % make long script look right ... font dependent!

\installcommandhandler \??mathoperators {mathoperator} \??mathoperators

\setupmathoperator
  [\c!left=\zerocount,
   \c!mathclass=\mathoperatorcode,
   \c!bottomcolor=\mathoperatorparameter\c!numbercolor,
   \c!topcolor=\mathoperatorparameter\c!numbercolor,
   \c!textcolor=\mathoperatorparameter\c!color,
   \c!numbercolor=\mathoperatorparameter\c!color,
   \c!symbolcolor=\mathoperatorparameter\c!color]

\aliased\let\setupmathoperators\setupmathoperator

\appendtoks
    % todo: only define when there's left or right
    \protected\instance\edefcsname\currentmathoperator\endcsname{\math_operator{\currentmathoperator}}%
    % todo: under definition control
    \protected\instance\edefcsname\e!start\currentmathoperator\endcsname{\math_operator_start{\currentmathoperator}}%
    \protected\instance\edefcsname\e!stop \currentmathoperator\endcsname{\math_operator_stop}%
\to \everydefinemathoperator

% more generic:

\defcsname\??mathoperatormethod\v!horizontal\endcsname{nolimits }
\defcsname\??mathoperatormethod\v!vertical  \endcsname{limits }

% The ones we wlready had:

\letcsname\??mathoperatormethod    \v!auto\endcsname\empty
\letcsname\??mathoperatormethod autolimits\endcsname\empty
\letcsname\??mathoperatormethod   nolimits\expandafter\endcsname\csname\??mathoperatormethod\v!horizontal\endcsname
\letcsname\??mathoperatormethod     limits\expandafter\endcsname\csname\??mathoperatormethod\v!vertical  \endcsname

%D With the auto option DisplayOperatorMinHeight will kick in unless we explicitly set the size or
%D use the start|-|stop variant (which will size automatically). The default of this font parameter
%D are a bit on the small size which doesn't work well with fonts other than Latin Modern that has
%D a large one. Keep in mind that we have e.g. integrals as operators and not fixed characters.

\installlocalcurrenthandler\??mathoperators {mathoperator}

\lettonothing\m_operator_text

\protected\def\math_operator_common#1#2%
  {\setlocalmathoperatorcurrent{#1}% \edef\currentmathoperator{#1}%
   \setupcurrentmathoperator[#2]%
   \scratchclass\mathcodechecked{\mathoperatorparameter\c!mathclass}\relax
   \edef\p_left{\mathoperatorparameter\c!left}%
   \Uoperator
     \usedcolorparameterattributes{\mathoperatorparameter\c!symbolcolor}%
     \begincsname\??mathoperatormethod\mathoperatorparameter\c!method\endcsname
     \ifchkdimension\mathoperatorparameter\c!size\or
       \s!depth \lastchkdimension
       \s!height\lastchkdimension
       \s!axis   % variants
       \s!noaxis % extensibles (assumes also axis)
       \s!exact  % make sure we don't overshoot when there are no variants and extensibles
     \orelse\ifcstok{\mathoperatorparameter\c!size}\v!auto
       \s!auto
     \fi
     \s!class \scratchclass
   % \s!attr \indexofregister \c_attr_mathsize \attributeunsetvalue
     % todo: find a way to pick up or pass sup/sub to here
     \Umathchar \scratchclass \fam
       \ifchknumber\p_left\or
         \lastchknumber
       \else
         \expandafter`\p_left
       \fi
     {\edef\m_operator_text{\mathoperatorparameter\c!top}%
      \ifempty\m_operator_text\else
         \mathstrut % todo: make option
         \usemathoperatorcolorparameter\c!topcolor
         \m_operator_text
      \fi}%
     {\edef\m_operator_text{\mathoperatorparameter\c!bottom}%
      \ifempty\m_operator_text\else
         \mathstrut % todo: make option
         \usemathoperatorcolorparameter\c!bottomcolor
         \m_operator_text
      \fi}%
    \usemathoperatorcolorparameter\c!textcolor}

\tolerant\protected\def\math_operator#1#*[#S#2]#*#:#=% mandate braces
  {\math_operator_common{#1}{#2}#3\Uright \s!rightclass \mathintegralcode .}

\tolerant\protected\def\math_operator_start#1#*[#S#2]%
  {\math_operator_common{#1}{#2}}

\protected\def\math_operator_stop
  {\Uright \s!rightclass \mathintegralcode .}
% {\Uright \s!rightclass \mathintegralcode \Umathchar\zerocount \fam \zerocount }

% \def\math_operator_default_size % is now the auto option
%   {\ifconditional\indisplaymath\ifcase\Umathoperatorsize=\maxdimen\else
%      \Umathoperatorsize\displaystyle
%    \fi\fi}

% TODO: Add 4 (inherited) classes and then define them automatically from char-def
% instead.

\definemathoperator [integrals]
\definemathoperator [summations]
\definemathoperator [products]
\definemathoperator [operators]

\setupmathoperators [summations] [\c!size=\v!auto]
\setupmathoperators [products]   [\c!size=\v!auto]
\setupmathoperators [operators]  [\c!size=\v!auto]

\setupmathoperators [integrals]
  [\c!size=\v!auto,
   \c!mathclass=\mathintegralcode,
   \c!method=\mathematicsparameter\c!integral] % cf Mikael's wish

\setupmathematics[\c!integral=nolimits]

\definemathoperator [integral]    [integrals]  [\c!left="222B] % these might go unless we decide
\definemathoperator [iintegral]   [integrals]  [\c!left="222C] % to have verbose parents but who
\definemathoperator [iiintegral]  [integrals]  [\c!left="222D] % will use them
\definemathoperator [iiiintegral] [integrals]  [\c!left="2A0C]

\definemathoperator [int]        [integrals]  [\c!left="222B] %                          INTEGRAL
\definemathoperator [iint]       [integrals]  [\c!left="222C] %                DOUBLE    INTEGRAL
\definemathoperator [iiint]      [integrals]  [\c!left="222D] %                TRIPLE    INTEGRAL
\definemathoperator [iiiint]     [integrals]  [\c!left="2A0C] %                QUADRUPLE INTEGRAL OPERATOR
\definemathoperator [oint]       [integrals]  [\c!left="222E] %                CONTOUR   INTEGRAL
\definemathoperator [oiint]      [integrals]  [\c!left="222F] %                SURFACE   INTEGRAL
\definemathoperator [oiiint]     [integrals]  [\c!left="2230] %                VOLUME    INTEGRAL
\definemathoperator [intc]       [integrals]  [\c!left="2231] %      CLOCKWISE           INTEGRAL
\definemathoperator [ointc]      [integrals]  [\c!left="2232] %      CLOCKWISE CONTOUR   INTEGRAL
\definemathoperator [aointc]     [integrals]  [\c!left="2233] % ANTI CLOCKWISE CONTOUR   INTEGRAL

\definemathoperator [sumint]                [integrals]  [\c!left="2A0B] % Integral with sum
\definemathoperator [barint]                [integrals]  [\c!left="2A0D] % Integral with bar
\definemathoperator [doublebarint]          [integrals]  [\c!left="2A0E] % Integral with double bar
\definemathoperator [slashint]              [integrals]  [\c!left="2A0F] % Integral with slash
\definemathoperator [aodownintc]            [integrals]  [\c!left="2A11]
\definemathoperator [rectangularpoleintc]   [integrals]  [\c!left="2A12]
\definemathoperator [semicirclepoleintc]    [integrals]  [\c!left="2A13]
\definemathoperator [circlepoleoutsideintc] [integrals]  [\c!left="2A14]
\definemathoperator [circlepoleinsideintc]  [integrals]  [\c!left="2A15]
\definemathoperator [squareintc]            [integrals]  [\c!left="2A16]
\definemathoperator [hookleftarrowint]      [integrals]  [\c!left="2A17]
\definemathoperator [timesint]              [integrals]  [\c!left="2A18]
\definemathoperator [capint]                [integrals]  [\c!left="2A19]
\definemathoperator [cupint]                [integrals]  [\c!left="2A1A]
\definemathoperator [upperint]              [integrals]  [\c!left="2A1B]
\definemathoperator [lowerint]              [integrals]  [\c!left="2A1C]

\definemathoperator [sum]           [summations] [\c!left="2211] % N-ARY SUMMATION
\definemathoperator [blackboardsum] [summations] [\c!left="2140] % blackboard summation
\definemathoperator [modtwosum]     [summations] [\c!left="2A0A] % modulo two summation


\definemathoperator [prod]       [products]   [\c!left="220F] % N-ARY PRODUCT
\definemathoperator [coprod]     [products]   [\c!left="2210] % N-ARY COPRODUCT

% todo: middles too

\definemathoperator [bigwedge]   [operators]  [\c!left="22C0] %  N-ARY LOGICAL AND
\definemathoperator [bigvee]     [operators]  [\c!left="22C1] %  N-ARY LOGICAL OR
\definemathoperator [bigcap]     [operators]  [\c!left="22C2] %  N-ARY LOGICAL INTERSECTION
\definemathoperator [bigcup]     [operators]  [\c!left="22C3] %  N-ARY         UNION
\definemathoperator [bigodot]    [operators]  [\c!left="2A00] %  N-ARY CIRCLED DOT          OPERATOR
\definemathoperator [bigoplus]   [operators]  [\c!left="2A01] %  N-ARY CIRCLED PLUS         OPERATOR
\definemathoperator [bigotimes]  [operators]  [\c!left="2A02] %  N-ARY CIRCLED TIMES        OPERATOR
\definemathoperator [bigudot]    [operators]  [\c!left="2A03] %  N-ARY         UNION        OPERATOR WITH DOT
\definemathoperator [biguplus]   [operators]  [\c!left="2A04] %  N-ARY         UNION        OPERATOR WITH PLUS
\definemathoperator [bigsqcap]   [operators]  [\c!left="2A05] %  N-ARY SQUARE  INTERSECTION OPERATOR
\definemathoperator [bigsqcup]   [operators]  [\c!left="2A06] %  N-ARY SQUARE  UNION        OPERATOR
\definemathoperator [bigtimes]   [operators]  [\c!left="2A09] %  N-ARY         TIMES        OPERATOR

\definemathoperator [leftouterjoin]     [operators]  [\c!left="27D5] % left outer join
\definemathoperator [rightouterjoin]    [operators]  [\c!left="27D6] % right outer join
\definemathoperator [fullouterjoin]     [operators]  [\c!left="27D7] % full outer join
\definemathoperator [bigbottom]         [operators]  [\c!left="27D8] % big bottom
\definemathoperator [bigtop]            [operators]  [\c!left="27D9] % big top
\definemathoperator [bigsolidus]        [operators]  [\c!left="29F8] % big solidus
\definemathoperator [bigreversesolidus] [operators]  [\c!left="29F9] % big reverse solidus
\definemathoperator [bigdoublewedge]    [operators]  [\c!left="2A07] % big double wedge
\definemathoperator [bigdoublevee]      [operators]  [\c!left="2A08] % big double vee


%D \im{∫_ 2 \neq ∑_3 \neq ∑^3 \neq ∏_4^5 \neq ∏_4}\blank
%D \dm{∫_ 2 \neq ∑_3 \neq ∑^3 \neq ∏_4^5 \neq ∏_4}\blank

% \amcode`∫ \activecatcode \letcharcode`∫ \int
% \amcode`∑ \activecatcode \letcharcode`∑ \sum
% \amcode`∏ \activecatcode \letcharcode`∏ \prod

\permanent\protected\def\registermathsymbolcommand
  {\afterassignment\math_register_symbol_command\scratchcounter}

\def\math_register_symbol_command
  {\amcode\scratchcounter\activecatcode
   \letcharcode\scratchcounter}

\registermathsymbolcommand "222B \int
\registermathsymbolcommand "222C \iint
\registermathsymbolcommand "222D \iiint
\registermathsymbolcommand "2A0C \iiiint
\registermathsymbolcommand "222E \oint
\registermathsymbolcommand "222F \oiint
\registermathsymbolcommand "2230 \oiiint
\registermathsymbolcommand "2231 \intc
\registermathsymbolcommand "2232 \ointc
\registermathsymbolcommand "2233 \aointc

\registermathsymbolcommand "2A0B \sumint
\registermathsymbolcommand "2A0D \barint
\registermathsymbolcommand "2A0E \doublebarint
\registermathsymbolcommand "2A0F \slashint
\registermathsymbolcommand "2A11 \aodownintc
\registermathsymbolcommand "2A12 \rectangularpoleintc
\registermathsymbolcommand "2A13 \semicirclepoleintc
\registermathsymbolcommand "2A14 \circlepoleoutsideintc
\registermathsymbolcommand "2A15 \circlepoleinsideintc
\registermathsymbolcommand "2A16 \squareintc
\registermathsymbolcommand "2A17 \hookleftarrowint
\registermathsymbolcommand "2A18 \timesint
\registermathsymbolcommand "2A19 \capint
\registermathsymbolcommand "2A1A \cupint
\registermathsymbolcommand "2A1B \upperint
\registermathsymbolcommand "2A1C \lowerint

\registermathsymbolcommand "2211 \sum
\registermathsymbolcommand "2140 \blackboardsum
\registermathsymbolcommand "2A0A \modtwosum

\registermathsymbolcommand "220F \prod
\registermathsymbolcommand "2210 \coprod

\registermathsymbolcommand "22C0 \bigwedge
\registermathsymbolcommand "22C1 \bigvee
\registermathsymbolcommand "22C2 \bigcap
\registermathsymbolcommand "22C3 \bigcup
\registermathsymbolcommand "2A00 \bigodot
\registermathsymbolcommand "2A01 \bigoplus
\registermathsymbolcommand "2A02 \bigotimes
\registermathsymbolcommand "2A03 \bigudot
\registermathsymbolcommand "2A04 \biguplus
\registermathsymbolcommand "2A05 \bigsqcap
\registermathsymbolcommand "2A06 \bigsqcup
\registermathsymbolcommand "2A09 \bigtimes

\registermathsymbolcommand "27D5 \leftouterjoin
\registermathsymbolcommand "27D6 \rightouterjoin
\registermathsymbolcommand "27D7 \fullouterjoin
\registermathsymbolcommand "27D8 \bigbottom
\registermathsymbolcommand "27D9 \bigtop
\registermathsymbolcommand "29F8 \bigsolidus
\registermathsymbolcommand "29F9 \bigreversesolidus
\registermathsymbolcommand "2A07 \bigdoublewedge
\registermathsymbolcommand "2A08 \bigdoublevee

\protect \endinput
