Пустое место в таблице / Неопределенная последовательность управления в собственной команде

Пустое место в таблице / Неопределенная последовательность управления в собственной команде

Я написал макрос, который разбивает число на его цифры и записывает их в таблицу, и у меня есть 2 вопроса по нему. MWE:

\documentclass{article}
\usepackage{pgffor, etoolbox}
\newcommand*\mytablecontents{}
\newcommand*\numtostr[1]{
\renewcommand*\mytablecontents{}
\pgfmathtruncatemacro{\laenge}{ln(#1)/ln(10)+1}
\pgfmathtruncatemacro{\aziffer}{#1}
\foreach \i [remember=\aziffer as \aziffer] in {\laenge,...,1} {%
    \pgfmathtruncatemacro{\ziffer}{\aziffer/(10^(\i-1))}
    \pgfmathtruncatemacro{\aziffer}{\aziffer-\ziffer*(10^(\i-1))}
    \xappto\mytablecontents{$\ziffer$}
    \if\i1
        \gappto\mytablecontents{\\}
    \else
        \gappto\mytablecontents{&}
    \fi
}%
\mytablecontents
}%

\begin{document}

\begin{tabular}{*{7}{|r}}
    \numtostr{6563}
    \numtostr{3475}
\end{tabular}

\end{document}

1) При просмотре результата видно, что в первом столбце много пустого места. Почему так?

2) Я также попытался написать макрос, который использует в качестве аргументов два числа и записывает их в таблицу, используя макрос выше:

\newcommand*{\test}[2]{%
\pgfmathtruncatemacro{\groesse}{ln(\i)/ln(10)+1}
\begin{tabular}{*{\groesse}{r}}
    \numtostr{#1}
    \numtostr{#2}
\end{tabular}
}%

Потом \test{123}{234}выдает ошибку "Неопределенная управляющая последовательность". Почему так происходит?

решение1

  • Убедитесь, что определение макроса не вносит непреднамеренных пробелов.

  • Определите \iперед его использованием при выполнении \test.

  • Как отметил Дэвид в комментариях, \ifглючит, так как возвращает true всякий раз, когда \iрасширяется до числа, начинающегося с двух одинаковых цифр. Замените его, например, на \ifnum\i=1\relax.

Вот ваш код с исправлениями.

\documentclass{article}
\usepackage{pgffor, etoolbox}
\newcommand*\mytablecontents{}
\newcommand*\numtostr[1]{%
\renewcommand*\mytablecontents{}%
\pgfmathtruncatemacro{\laenge}{ln(#1)/ln(10)+1}%
\pgfmathtruncatemacro{\aziffer}{#1}%
\foreach \i [remember=\aziffer as \aziffer] in {\laenge,...,1} {%
    \pgfmathtruncatemacro{\ziffer}{\aziffer/(10^(\i-1))}%
    \pgfmathtruncatemacro{\aziffer}{\aziffer-\ziffer*(10^(\i-1))}%
    \xappto\mytablecontents{$\ziffer$}%
    \ifnum\i=1\relax
        \gappto\mytablecontents{\\}%
    \else
        \gappto\mytablecontents{&}%
    \fi
}%
\mytablecontents
}%

\newcommand*{\test}[2]{%
\pgfmathtruncatemacro{\groesse}{ln(\i)/ln(10)+1}
\begin{tabular}{*{\groesse}{r}}
    \numtostr{#1}
    \numtostr{#2}
\end{tabular}
}%

\begin{document}

\begin{tabular}{*{7}{|r}}
    \numtostr{6563}
    \numtostr{3475}
\end{tabular}

\renewcommand\i{100}
\test{123}{234}

\end{document}

введите описание изображения здесь

решение2

Избыточные пробелы возникают из-за незащищенных концов линий.

Вот другая реализация, которая создает таблицу из

\digittable{<comma separated list of numbers>}

Есть необязательный аргумент для установки минимального количества отображаемых цифр (дополненных пробелами), см. пример кода. Вы также можете ввести операцию над целыми числами, макросы вычислят результат самостоятельно.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\digittable}{O{0}m}
 {
  \martin_digittable:nn { #1 } { #2 }
 }

\seq_new:N \l__martin_digittable_numbers_seq
\seq_new:N \l__martin_digittable_entry_seq
\int_new:N \l__martin_digittable_length_int
\tl_new:N \l__martin_digittable_body_tl

\cs_new_protected:Nn \martin_digittable:nn
 {
  \seq_clear:N \l__martin_digittable_numbers_seq
  \clist_map_inline:nn { #2 }
   {
    \seq_put_right:Nx \l__martin_digittable_numbers_seq { \int_eval:n { ##1 } }
   }
  % compute the maximum length
  \int_zero:N \l__martin_digittable_length_int
  \seq_map_inline:Nn \l__martin_digittable_numbers_seq
   {
    \int_set:Nn \l__martin_digittable_length_int
     {
      \int_max:nn { \l__martin_digittable_length_int } { \tl_count:n { ##1 } }
     }
   }
  \int_set:Nn \l__martin_digittable_length_int
   {
    \int_max:nn { \l__martin_digittable_length_int } { #1 }
   }
  % build the table rows
  \tl_clear:N \l__martin_digittable_body_tl
  \seq_map_inline:Nn \l__martin_digittable_numbers_seq
   {% pad the current digit with \__martin_digittable_blank:
    % first split the current item at every token
    \seq_set_split:Nnn \l__martin_digittable_entry_seq { } { ##1 }
    % add to the left the needed amount of blanks
    \prg_replicate:nn { \l__martin_digittable_length_int - \tl_count:n { ##1 } }
     {
      \seq_put_left:Nn \l__martin_digittable_entry_seq { \__martin_digittable_blank: }
     }
    % form the next table row, by inserting & between items
    \tl_put_right:Nx \l__martin_digittable_body_tl
     {
      \seq_use:Nn \l__martin_digittable_entry_seq { & }
      \exp_not:N \\
     }
   }
  % produce the table
  \begin{tabular}{|*{\l__martin_digittable_length_int}{c|}}
  \hline
  \l__martin_digittable_body_tl
  \hline
  \end{tabular}
 }

\cs_new_protected:Nn \__martin_digittable_blank:
 {
  \phantom{0}
 }
\ExplSyntaxOff

\begin{document}

\digittable{3329+3234,3475,212,1}

\bigskip

\digittable[6]{6563,3475,212,1}

\end{document}

введите описание изображения здесь

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