4

Is it possible to take the parameters of a macro, and actually do maths with them? I need to calculate a 'Total' to go in a table that is built by a macro, i.e.:

\documentclass[]{article}
\newcommand{\mytest}[3]{\
\textbf{Marking Grid}

Logic (50\%): #1 

Spelling (25\%): #2

Scholarly engagement (25\%): #3

Total: a*.5 + b*.25 + c*.25
 }

\begin{document}
\mytest{10}{20}{30}
\end{document}
  • side note You have a backslash (mytest}[3][\ ) and I wonder if you were trying to escape à la Python the end-of-line but it does not work this way in TeX. – user4686 Nov 22 '17 at 7:29
7

Here's a simple expl3 solution:

grid

\documentclass[]{article}

\usepackage{expl3,xparse}

\ExplSyntaxOn
\NewDocumentCommand { \mytest } { m m m }
    {
        \textbf{Marking ~ Grid}\par 
        Logic ~ (50\%): ~ #1\par    
        Spelling ~ (25\%): ~ #2\par
        Scholarly ~ engagement ~ (25\%): ~#3\par
        Total: ~ \fp_eval:n{#1*.5 + #2*.25 + #3*.25}
    }
\ExplSyntaxOff
\begin{document}
\mytest{10}{20}{30}
\end{document}
4

Also:

\documentclass{article}
\usepackage{xintexpr}

\newcommand{\mytest}[3]{%
\textbf{Marking Grid}

Logic (50\%): #1 

Spelling (25\%): #2

Scholarly engagement (25\%): #3

% [2] means to print with 2 digits after decimal mark
% Total: \xinttheiexpr [2] (#1)*.5 + (#2)*.25 + (#3)*.25\relax
% or, as xintexpr understands fractions:
Total: \xinttheiexpr [2] #1/2 + #2/4 + #3/4\relax
% (I hesitated using parentheses to allow #1, #2, #3 being expressions
% but they are used "naked" already above so I take they should be
% integers only)
}

\begin{document}
\mytest{10}{20}{30}
\end{document}

An alternative which defines intermediate variables, this is potentially useful for increasing readability of source if it evolves.

\documentclass{article}
\usepackage{xintexpr}

\newcommand{\mytest}[3]{%
\textbf{Marking Grid}

\xintdefvar logic:= #1;%
Logic (50\%): \xinttheexpr logic\relax

\xintdefvar spelling:= #2;%
Spelling (25\%): \xinttheexpr spelling\relax

\xintdefvar schol_engag:= #3;%
Scholarly engagement (25\%): \xinttheexpr schol_engag\relax

Total: \xinttheiexpr [2] logic/2 + spelling/4 + schol_engag/4\relax
}

\begin{document}
\mytest{10}{20}{30}
\end{document}

enter image description here

2

The following example

  • uses e-TeX for the calculation
  • and formats the entries in a table.
\documentclass[]{article}
\usepackage{booktabs}
\usepackage{siunitx}

\makeatletter
\newcommand{\mytest}[3]{%
  \begin{tabular}{@{}l@{ }r@{}}
    \multicolumn{2}{@{}l@{}}{\textbf{Marking Grid}}\\
    Logic (\SI{50}{\percent}): & #1 \\
    Spelling (\SI{25}{\percent}): & #2 \\
    Scholarly engagement (\SI{25}{\percent}): & #3 \\
    Total: &
    \strip@pt\dimexpr
      .5\dimexpr(#1pt)\relax +
      .25\dimexpr(#2pt)\relax +
      .25\dimexpr(#3pt)\relax
    \relax
  \end{tabular}%
}
\newcommand{\mytesti}[3]{%
  \begin{tabular}{@{}l@{ }rr@{}}
    \multicolumn{3}{@{}l@{}}{\textbf{Marking Grid}}\\
    Logic: & #1 & (\SI{50}{\percent})\\
    Spelling: & #2 & (\SI{25}{\percent})\\
    Scholarly engagement: & #3 & (\SI{25}{\percent}) \\
    \cmidrule{2-2}
    Total: &
    \strip@pt\dimexpr
      .5\dimexpr(#1pt)\relax +
      .25\dimexpr(#2pt)\relax +
      .25\dimexpr(#3pt)\relax
    \relax
  \end{tabular}%
}
\makeatother

\begin{document}
  \noindent
  \mytest{10}{20}{30}

  \medskip
  \noindent
  \mytesti{9}{17}{31}
\end{document}

Result

Automatic alignment at the decimal marker

The following example analyzes the numbers and counts the integer and decimal figures and passes the counts to option table-format for the column type S of package siunitx.

\documentclass[]{article}
\usepackage{booktabs}
\usepackage{siunitx}

\makeatletter
\newcommand{\mytest}[3]{%
  \begingroup
    \edef\NumberA{\strip@pt\dimexpr(#1pt)\relax}%
    \edef\NumberB{\strip@pt\dimexpr(#2pt)\relax}%
    \edef\NumberC{\strip@pt\dimexpr(#3pt)\relax}%
    \edef\Total{%
      \strip@pt\dimexpr
        .5\dimexpr(#1pt)\relax +
        .25\dimexpr(#2pt)\relax +
        .25\dimexpr(#3pt)\relax
      \relax
    }%
    \edef\FiguresInteger{1}%
    \edef\FiguresDecimal{0}%
    \expandafter\mytest@measure\NumberA..\@nil
    \expandafter\mytest@measure\NumberB..\@nil
    \expandafter\mytest@measure\NumberC..\@nil
    \expandafter\mytest@measure\Total..\@nil
    \begin{tabular}{@{}lS[table-format=\FiguresInteger.\FiguresDecimal]r@{}}
      \multicolumn{3}{@{}l@{}}{\textbf{Marking Grid}}\\
      Logic: & \NumberA & (\SI{50}{\percent})\\
      Spelling: & \NumberB & (\SI{25}{\percent})\\
      Scholarly engagement: & \NumberC & (\SI{25}{\percent}) \\
      \cmidrule(lr){2-2}
      Total: & \Total & \\
    \end{tabular}%
  \endgroup
}
\def\mytest@measure#1.#2.#3\@nil{%
  % Count digits before decimal marker
  \edef\tmp{\the\numexpr-1+\mytest@count0#1\relax}%
  \ifnum\tmp>\FiguresInteger\relax
    \let\FiguresInteger\tmp
  \fi
  % Count digits after decimal marker
  \edef\tmp{\the\numexpr-1+\mytest@count0#2\relax}%
  \ifnum\tmp>\FiguresDecimal\relax
    \let\FiguresDecimal\tmp
  \fi
}
\def\mytest@count#1{%
  \ifx#1\relax
  \else
    +1%
    \expandafter\mytest@count
  \fi
}
\makeatother

\begin{document}
  \noindent
  \mytest{10}{20}{30}

  \medskip
  \noindent
  \mytest{9.5}{23}{31.25}
\end{document}

Result with alignment at decimal marker

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.