![Неполный \iffalse с \pgfmathsetmacro](https://rvso.com/image/353034/%D0%9D%D0%B5%D0%BF%D0%BE%D0%BB%D0%BD%D1%8B%D0%B9%20%5Ciffalse%20%D1%81%20%5Cpgfmathsetmacro.png)
Я хочу сгенерировать таблицу с помощью \foreach
команды, чтобы записи таблицы зависели от строки и столбца. Я хотел протестировать следующий код:
\documentclass{article}
\usepackage{pgffor,etoolbox}
\newcommand*\tas[2]{
\pgfmathsetmacro{\sat}{#1+#2}
\sat
}
\newcommand*\mytablecontents{}
\foreach \i in {1,...,7}{
\foreach \j in {1,...,7}{
\xappto\mytablecontents{\tas{\i}{\j}}
\gappto\mytablecontents{&}
}
\gappto\mytablecontents{\\}
}
\begin{document}
\begin{tabular}{c|cc|ccc|cc}
\mytablecontents
\end{tabular}
\end{document}
Это дает ошибку "Incomplete \iffalse". Я читал, что причиной этой ошибки является использование \pgfmathsetmacro
. Кто-нибудь знает, как с этим справиться?
решение1
\pgfmathsetmacro
не расширяется, поэтому он не «оценивается» в \edef
(что происходит \xappto
в варианте \xdef
).
Сначала можно вычислить сумму, сохранить ее в макросе, а затем добавить расширенную версию:
\documentclass{article}
\usepackage{pgffor,etoolbox}
\newcommand*\tas[2]{%
\pgfmathsetmacro{\sat}{#1+#2}%
}
\newcommand*\mytablecontents{}
\foreach \i in {1,...,7}{%
\foreach \j in {1,...,7}{%
\tas{\i}{\j}%
\xappto\mytablecontents{\sat &}
}%
\gappto\mytablecontents{\\}
}
\begin{document}
\begin{tabular}{c|cc|ccc|cc}
\mytablecontents
\end{tabular}
\end{document}
В качестве альтернативы можно использовать расширяемую арифметику: expl3
предоставляет ее с помощью xfp
и \fpeval
:
\documentclass{article}
\usepackage{pgffor,etoolbox,xfp}
\newcommand*\mytablecontents{}
\foreach \i in {1,...,7}{%
\foreach \j in {1,...,7}{%
\xappto\mytablecontents{\fpeval{\i+\j}&}
}%
\gappto\mytablecontents{\\}
}
\begin{document}
\begin{tabular}{c|cc|ccc|cc}
\mytablecontents
\end{tabular}
\end{document}
Просто чтобы показать возможности ( pgfmath
хотя не все, охваченные доступны), если вы измените \xappto
вызов на
\xappto\mytablecontents{\fpeval{round(\i*sqrt(\j),2)}&}
выход будет
Тот же результат с полным expl3
кодом:
\documentclass{article}
\usepackage{expl3}
\ExplSyntaxOn
\tl_clear:N \l_tmpa_tl
\int_step_inline:nnnn { 1 } { 1 } { 7 }
{ % outer cycle: #1
\int_step_inline:nnnn { 1 } { 1 } { 7 }
{ % inner cycle: ##1
\tl_put_right:Nx \l_tmpa_tl { \fp_eval:n {round(#1*sqrt(##1),2)} & }
}
\tl_put_right:Nn \l_tmpa_tl { \\ }
}
\tl_set_eq:NN \mytablecontents \l_tmpa_tl
\ExplSyntaxOff
\begin{document}
\begin{tabular}{c|cc|ccc|cc}
\mytablecontents
\end{tabular}
\end{document}
Обратите внимание, что \tl_put_right:Nx
это аналог \eappto
( x
обозначает eИксpanded) и \tl_put_right:Nn
является аналогом \appto
. Нет необходимости в глобальных определениях, так как \int_step_inline:nnnn
не использует группировку циклов: текущий индекс доступен напрямую как #1
(или ##1
во внутреннем цикле).
решение2
Чтобы избежать этого newcommand
, можно вычислить тот же результат, используя опцию [evaluate = \j as \c using int(\i+\j)]
внутреннего \foreach
цикла.
\documentclass{article}
\usepackage{pgffor,etoolbox}
\newcommand*\mytablecontents{}
\foreach \i in {0,...,7}{
\foreach \j [evaluate = \j as \c using int(\i+\j)] in {0,...,7}{
\xappto\mytablecontents{\c}
\gappto\mytablecontents{&}
}
\gappto\mytablecontents{\\}
}
\begin{document}
\begin{tabular}{c|cc|ccc|cc}
\mytablecontents
\end{tabular}
\end{document}
Вы также можете использовать:
\newcommand*\mytablecontents{}
\foreach \i in {0,...,7}{
\foreach \j in {0,...,7}{
\pgfmathtruncatemacro\c{\i+\j}
\xappto\mytablecontents{\c}
\gappto\mytablecontents{&}
}
\gappto\mytablecontents{\\}%
}
решение3
Ваше исполнение
\xappto\mytablecontents{\tas{\i}{\j}}
предполагает, что \tas{.}{.}
является расширяемым. Однако, поскольку он содержит присваивание ( \pgfmathsetmacro
), это не так. Поэтому вам придется сначала оценить (расширить) выражение, прежде чем включать его как часть вашего app
endage в \mytablecontents
. Поскольку выражение довольно прямолинейно (сложение двух чисел), вы можете просто использовать \number\numexpr#1+#2
:
\documentclass{article}
\usepackage{pgffor,etoolbox}
\newcommand*\tas[2]{%
\number\numexpr#1+#2\relax
}
\newcommand*\mytablecontents{}
\foreach \i in {1,...,7}{
\foreach \j in {1,...,7}{
\xappto\mytablecontents{\tas{\i}{\j}}
\gappto\mytablecontents{&}
}
\gappto\mytablecontents{\\}
}
\begin{document}
\begin{tabular}{c|cc|ccc|cc}
\mytablecontents
\end{tabular}
\end{document}
Расширяемые вычисления легко возможны через интерфейс LaTeX2e для \fp_eval
LaTeX3 вxfp
упаковка:
\usepackage{pgffor,xfp,etoolbox}
\newcommand*\mytablecontents{}
\foreach \i in {1,...,7}{
\foreach \j in {1,...,7}{
\xappto\mytablecontents{\fpeval{\i+\j}}
\gappto\mytablecontents{&}
}
\gappto\mytablecontents{\\}
}