Неполный \iffalse с \pgfmathsetmacro

Неполный \iffalse с \pgfmathsetmacro

Я хочу сгенерировать таблицу с помощью \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), это не так. Поэтому вам придется сначала оценить (расширить) выражение, прежде чем включать его как часть вашего appendage в \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_evalLaTeX3 в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{\\}
}

Связанный контент