4

Consider the integral. $\int_{0}^{1} x dx$ creates an integral with bounds 0 and 1.

I defined the evaluate command like so:

\newcommand{\evaluate}[3]{\left. #1 \right \rvert_{#2}^{#3}}

Which I can now use:

$\evaluate{\frac{x^2}{2}}{0}{1}$

I would like to be able to use this syntax instead:

$\evaluate{\frac{x^2}{2}}_{0}^{1}$

In the same vein, I could make another command:

$\integral{x dx}_{0}^{1}

Is that at all possible?

  • For \evaluate you can just remove the superscript and subscript from the command definition: \newcommand{\evaluate}[1]{\left. #1 \right \rvert}. The integral is harder to implement because the super- and subscripts aren't at the end. Might still be possible, but tricky. – Emma Oct 15 '16 at 2:11
  • Can you please expand the code snippet that you have posted to a full minimal working example. A MWE should compile and be as small as possible to demonstrate your problem. – Andrew Oct 15 '16 at 3:37
7

Here is a slightly modified version for the \integral operator to present the general idea of a way to define such "flexible" scripts.

\integral only takes the arguments of the main expression, i.e. the parts which should come after the integral sign with scripts. Those are stored in a temporary command \temp@expr. We set the integral sign and then call a helper macro \integral@ which inspects the next token. If the next token is a subscript character _, another helper macro \integral@sub is called that gobbles the _, reads the following argument (the actual subscript), produces the subscript output, and calls \integral@ again as a superscript may follow.

The same is done if a superscript character occurs (\integral@sup). If the next token isn't either a sub- or superscript character, the integral expression is finished and we can typeset the temporarily stored expression. The inspection via \@ifnextchar here allows us to keep the number and order of scripts flexible:

\documentclass{article}

\usepackage{amsmath}

\makeatletter
\def\integral#1#2{\def\temp@expr{#1\,\mathrm d#2}\int\integral@}
\def\integral@{%
    \@ifnextchar{_}{\integral@sub}{%
    \@ifnextchar{^}{\integral@sup}{\temp@expr}}%
}%
\def\integral@sub#1#2{_{#2}\integral@}
\def\integral@sup#1#2{^{#2}\integral@}
\makeatother

\begin{document}

\[
    \integral{x^2}{x} \qquad
    \integral{x^2}{x}_a \qquad
    \integral{x^2}{x}^b \qquad
    \integral{x^2}{x}_a^b \qquad
    \integral{x^2}{x}^b_a
\]

\end{document}

Output:

enter image description here

  • 1
    Nice You could mention that if the command is always going to gave limits on the integral, with the subscript first, then there is a shorter solution using \def; namely, \def\integral#1_#2^#3{\int_{#2}^{#3}#1\,dx}. What you have is more flexible, which is better! – Andrew Oct 15 '16 at 3:54
2

I suggest a different and much more flexible approach, with a key-value syntax.

The keys for \integral are

  • lb for the lower bound
  • ub for the upper bound
  • type for the integral type (default \int)
  • along (a semantic alias for lb)
  • domain (for multiple integrals, it also does \limits)
  • style for overriding the current math style

This way, the same command can be used for much more purposes.

The command \evaluate is simpler; it accepts lb, ub and size, the last one for overriding the style chosen by \left and \right.

\documentclass{article}
\usepackage{xparse} % for expl3
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\diff}{} % for differentials
 {
  \mathop{}\!d
 }

\NewDocumentCommand{\integral}{O{}m}
 {
  \group_begin:
  \keys_set:nn { patenaude/integral } { #1 }
  \patenaude_integral:n { #2 }
  \group_end:
 }

\NewDocumentCommand{\evaluate}{O{}m}
 {
  \group_begin:
  \keys_set:nn { patenaude/evaluate } { #1 }
  \patenaude_evaluate:n { #2 }
  \group_end:
 }

\keys_define:nn { patenaude/integral }
 {
  type .tl_set:N  = \l_patenaude_integral_type_tl,
  type .initial:n = \int,
  lb .tl_set:N    = \l_patenaude_integral_lb_tl,
  ub .tl_set:N    = \l_patenaude_integral_ub_tl,
  along .tl_set:N = \l_patenaude_integral_lb_tl,
  style .tl_set:N = \l_patenaude_integral_style_tl,
  domain .code:n  =
   {
    \tl_set:Nn \l_patenaude_integral_lb_tl { #1 }
    \tl_put_right:Nn \l_patenaude_integral_type_tl { \limits }
   }
 }

\cs_new_protected:Nn \patenaude_integral:n
 {
  \l_patenaude_integral_style_tl % the math style
  \l_patenaude_integral_type_tl % the chosen integral type
  \tl_if_empty:NF \l_patenaude_integral_lb_tl % the lower bound or domain
   {
    \c_math_subscript_token { \l_patenaude_integral_lb_tl }
   }
  \tl_if_empty:NF \l_patenaude_integral_ub_tl % the upper bound
   {
    \c_math_superscript_token { \l_patenaude_integral_ub_tl }
   }
  #1 % the function
 }

\keys_define:nn { patenaude/evaluate }
 {
  lb .tl_set:N = \l_patenaude_evaluate_lb_tl,
  ub .tl_set:N = \l_patenaude_evaluate_ub_tl,
  size .tl_set:N = \l_patenaude_evaluate_size_tl,
 }

\cs_new_protected:Nn \patenaude_evaluate:n
 {
  \tl_if_empty:NT \l_patenaude_evaluate_size_tl % no chosen size
   {
    \kern-\nulldelimiterspace \left.
   }
  #1 % the function
  \, % some space
  \tl_if_empty:NTF \l_patenaude_evaluate_size_tl
   {% no chosen size
    \right|
   }
   {
    \l_patenaude_evaluate_size_tl |
   }
  \tl_if_empty:NF \l_patenaude_evaluate_lb_tl % the lower bound or domain
   {
    \c_math_subscript_token { \l_patenaude_evaluate_lb_tl }
   }
  \tl_if_empty:NF \l_patenaude_evaluate_ub_tl % the upper bound
   {
    \c_math_superscript_token { \l_patenaude_evaluate_ub_tl }
   }
 }

\ExplSyntaxOff

\begin{document}

\[
\integral{x^2\diff x}             \qquad
\integral[lb=a]{x^2\diff x}       \qquad
\integral[ub=b]{x^2\diff x}       \qquad
\integral[lb=a,ub=b]{x^2\diff x}  \qquad
\integral[ub=b,lb=a]{x^2\diff x}
\]

\[
\integral[type=\iint,domain=\Omega]{xy\diff x\diff y} \qquad
\integral[type=\oint,along=\gamma]{f(z)\diff z}
\]

\[
\integral[style=\textstyle,lb=a,ub=b]{f(x)\diff x}
\]

\[
\evaluate[lb=0,ub=1]{\frac{x^2}{2}}            \qquad
\evaluate[lb=0,ub=1,size=\Big]{\frac{x^2}{2}}  \qquad
\evaluate[lb=0,ub=1]{x}                        \qquad
\evaluate[lb=0,ub=1,size=\big]{x}
\]

\end{document}

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.