3

I have been defining a mathematic formula using NewDocumentCommand. This works well, but I do manage to get line breaks.

A minimal working example can be found below. Part of the construction is borrowed from parse variable length comma separated list into command (Peter Grill's answer).

\documentclass{article}

\usepackage{amsmath}
\usepackage{pgffor}
\usepackage{xparse}

\NewDocumentCommand{\formulaEx}{m}{
    \gdef\separator{}
    \gdef\formula{}
    \foreach \x in {1,...,#1} {%
        \xdef\formula{\formula \separator \frac{1}{(1+\x)^{\x}} }
        \gdef\separator{ + }
    }
    \formula
    \gdef\formula{}
}

\begin{document}

\begin{align*}
 P &= \formulaEx{10}
\end{align*}

\end{document}

This does not generate any line break. Replacing + by + \\ or + \newline yields an error. I also tried to use the package breqn but it is ineffective (no error but no line break).

I have tried a number of workarounds (such as adapting the solution proposed here tex capacity exceeded when using breqn package with a separate macro), but all of them were useless.

Many thanks for your help.

  • If you don't need it aligned, nor in display style, you can ditch the align* and go with $P = \formulaEx{10}$ – Steven B. Segletes Nov 6 '17 at 17:40
  • Thanks. Not aligned could be ok, but I really would like to keep the display style. – isanco Nov 6 '17 at 17:48
  • 1
    you can not in general use \xdef with content containing latex commands. – David Carlisle Nov 6 '17 at 18:26
  • I tried to use other loops (instead of pgffor) to use edef instead of xdef but the problem remains. I guess this is related to expansion and I am not 100% clear (to say the least) with expansion. – isanco Nov 6 '17 at 20:14
2

It was token hell, but the hill was taken, sir.

\documentclass{article}
\usepackage{lipsum}
\usepackage{amsmath}
\usepackage{pgffor}
\usepackage{xparse}
\newcommand\addtoformula[1]{\global\formula\expandafter{\the\formula#1}}
\newcommand\exaddtoformula[1]{\expandafter\global\expandafter\addtoformula\expandafter{#1}}
\newtoks\formula
\newtoks\formx
\NewDocumentCommand{\formulaEx}{m}{
    \gdef\separator{}
    \formula{}
    \foreach \x in {1,...,#1} {%
      \exaddtoformula{\separator\allowbreak\dfrac{1}}%
      \formx{}%
      \formx\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter(%
        \expandafter\expandafter\expandafter1\expandafter\expandafter\expandafter+%
          \expandafter\x\expandafter)\expandafter^\expandafter{\x}}
      \expandafter\addtoformula\expandafter{\expandafter{\the\formx}}%
      \gdef\separator{ +\rule[-4ex]{0pt}{0pt}}% PROVIDES EXTRA INTERLINE VERTICAL SPACE
    }
    \the\formula\vspace{-2ex}% UNDOES EXTRA SPACE ON LAST LINE
}
\begin{document}
\lipsum[1]
\begin{center}
$P = \formulaEx{10}$
\end{center}
\lipsum[2]
\end{document}

enter image description here

Something of an aligned style presentation can be achieved by way of invocation as follows:

\begin{center}
$P = \parbox[t]{4in}{$\formulaEx{10}$}$
\end{center}

enter image description here

Of course, while I went through the effort to build the token list in the above solution, there is really no need to do so when pursuing things in inline mode, and one can, instead, output each fraction directly.

\documentclass{article}
\usepackage{lipsum}
\usepackage{amsmath}
\usepackage{pgffor}
\usepackage{xparse}
\NewDocumentCommand{\formulaEx}{m}{
    \gdef\separator{}
    \foreach \x in {1,...,#1} {%
      \separator \dfrac{1}{(1+\x)^{\x}} 
      \gdef\separator{ +\rule[-4ex]{0pt}{0pt}}% PROVIDES EXTRA INTERLINE VERTICAL SPACE
    }
    \vspace{-2ex}% UNDOES EXTRA SPACE ON LAST LINE
}
\begin{document}
\lipsum[1]
\begin{center}
$P = \formulaEx{10}$
\end{center}
\lipsum[2]
\end{document}
  • 1
    A bunch of 'stacked' \expandafter macros ... without stackengine? Impressive, mostly impressive ;-) – user31729 Nov 6 '17 at 19:11
  • Thanks! Impressive indeed. I can see why I did not figure out... – isanco Nov 6 '17 at 20:05
1

You can use breqn, if you wish. On the other hand, it takes more time to build this for the package than to type in the whole formula directly.

\documentclass{article}
\usepackage{breqn}
\usepackage{xparse}

\ExplSyntaxOn
\seq_new:N \l__isanco_formula_temp_seq

\NewDocumentCommand{\FormulaEx}{mmm}
 {% #1 = times to repeat, #2 = control sequence, #3 = formula
  \cs_set_protected:Nn \__isanco_formula_repeat:n { #3 }
  \int_step_inline:nnnn { 1 } { 1 } { #1 }
   {
    \seq_put_right:Nx \l__isanco_formula_temp_seq
     {
      \exp_not:o { \__isanco_formula_repeat:n { ##1 } }
     }
   }
  \tl_new:N #2
  \tl_set:Nx #2 { \seq_use:Nn \l__isanco_formula_temp_seq { + } }
 }
\ExplSyntaxOff

\FormulaEx{10}{\formulaA}{\frac{1}{(1+#1)^{#1}}}

\begin{document}

\begin{dmath*}
P=\formulaA
\end{dmath*}

\end{document}

enter image description here

  • Many thanks! It works perfectly. I did not dig enough the breqn solution. – isanco Nov 7 '17 at 8:42

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.