У меня есть следующая команда:
\newcommand{\addtonewcount}[2]{\advance\#1 #2\relax}
#1 — это название счетчика, а #2 — это степень, на которую нужно увеличить счетчик.
Команда возвращает ошибку. Как это можно решить?
Вот более полный пример:
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\newcommand{\addtonewcount}[2]{\advance\#1 #2\relax}
\begin{document}
\newcount\testcountone
\addtonewcount{testcountone}{7}
\end{document}
решение1
#1
в теле макроса, когда вы определяете макрос, это место, куда вставляется фактический параметр, когда макрос используется и обрабатывается. С другой стороны, \#1
это управляющая последовательность \#
, за которой следует токен 1
. Это совершенно другое. Если вы действительно хотите преобразовать a name
в управляющую последовательность \name
(уже прочитанную в параметре), то вам нужно использовать \csname ...\endcsname
пару примитивов TeX.
Ваше определение должно быть таким:
\def\addtonewcount#1#2{\advance \csname#1\endcsname by#2\relax}
Обратите внимание, что \csname...\endcsname
это расширяемые примитивы TeX, а \advance
примитив TeX работает на уровне основного процессора и считывает свои параметры после расширения. Поэтому \expandafter
в этом случае вам не нужно использовать примитив TeX.
Примечание 2: by
ключевое слово is необязательно для \advance
примитива. Я использую его в своих макросах, чтобы повысить читаемость кода макроса. В настоящее время нам не нужно экономить память TeX в таких случаях. Это было важно 40 лет назад, когда был создан TeX.
решение2
Вот определение\addtocounter
\addtocounter:
macro:#1#2->\@ifundefined {c@#1}{\@nocounterr {#1}}{\global \advance \csname c@#1\endcsname #2\relax }
Сначала он проверяет, определен ли счетчик №1, и, если да, добавляет к нему №2.