%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

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

\setupmathoperator
  [\c!left=\zerocount,
   \c!mathclass=\mathoperatorcode]

\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}

\protected\def\math_operator_operator#1#2%
  {\setlocalmathoperatorcurrent{#1}% \edef\currentmathoperator{#1}%
   \setupcurrentmathoperator[#2]%
   \Uoperator
     \usedcolorparameterattributes{\mathoperatorparameter\c!color}%
     \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 \mathcodechecked{\mathoperatorparameter\c!mathclass} %
     \s!attr \indexofregister \c_attr_mathsize \attributeunsetvalue
     % todo: find a way to pick up or pass sup/sub to here
     \Udelimiter \zerocount \fam \mathoperatorparameter\c!left
     {\edef\m_operator_text{\mathoperatorparameter\c!top}%
      \ifempty\m_operator_text\else
         \mathstrut % todo: make option
         \dousecolorparameter{\mathoperatorparameter\c!topcolor}
         \m_operator_text
      \fi}%
     {\edef\m_operator_text{\mathoperatorparameter\c!bottom}%
      \ifempty\m_operator_text\else
         \mathstrut % todo: make option
         \dousecolorparameter{\mathoperatorparameter\c!bottomcolor}
         \m_operator_text
      \fi}}

\tolerant\protected\def\math_operator#1#*[#S#2]#*#:#=% mandate braces
  {\math_operator_operator{#1}{#2}#3\Uright.}

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

\protected\def\math_operator_stop
  {\Uright.}
% {\Uright\Udelimiter\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

\protect \endinput

