是否可以获取宏的参数,并实际用它们进行数学运算?我需要计算“总计”以放入由宏构建的表中,即:
\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}
答案1
这是一个简单的 expl3 解决方案:
\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}
答案2
还:
\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}
定义中间变量的替代方法,如果它发展的话,这对于提高源的可读性很有用。
\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}
答案3
下面的例子
- 使用 e-TeX 进行计算
- 并将条目格式化为表格形式。
\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}
小数点处自动对齐
下面的示例分析数字并计算整数和小数,并将计数传递table-format
给包的列类型S
的选项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}