Я пытаюсь внести изменения в большой документ, в котором используются макросы в стиле TeX, например:
{\defun SomeFunctionName arg1 arg2}
Макрос \defun
определяется как \newcommand{\defun}{\tt}
.
Могу ли я настроить это определение, чтобы получить SomeFunctionName arg1 arg2
часть как аргумент, чтобы разрешить более сложное определение? Например, Fox, если бы это defun
был правильный макрос LaTeX, я мог бы поместить рамку вокруг текста или поместить что-то до и после и т. д.
Минимальный пример:
\documentclass{article}
\newcommand{\defun}{\tt}
\begin{document}
\section{\defun SomeFunctionName arg1 arg2}
Call {\defun SomeFunctionName} to foo the bar.
\end{document}
Как я могу (например) добавить какой-то текст до и после каждого вызова defun
? Каков общий подход к обработке содержимого {\defun ...}
в качестве аргумента, за исключением редактирования всех вхождений?
Уточню: это большой документ двадцатилетней давности. Я его не писал.
решение1
\documentclass{article}
\protected\def\defun{\expandafter\zdefun\expandafter{\iffalse}\fi}
\def\zdefun#1{A \fbox{#1} B\egroup}
\begin{document}
\section{\defun SomeFunctionName arg1 arg2}
Call {\defun SomeFunctionName} to foo the bar.
\end{document}
Здесь
\iffalse}\fi
расширяется до нуля, поэтому
\expandafter{\iffalse}\fi
расширяется до одного несовпадающего, {
но является совпадающим {}
, поэтому может быть включен в определение.
Так что дано
{\defun SomeFunctionName}
Начинает {
группу и
\defun SomeFunctionName}
расширяется за один шаг до
\expandafter\zdefun\expandafter{\iffalse}\fi SomeFunctionName}
и на следующем этапе
\zdefun{SomeFunctionName}
\zdefun
имеет обычный #1
аргумент, который разделен {
только что вставленным нами и , }
который был изначально в файле. (Обратите внимание, что }
изначально это был разделитель закрытия группы, теперь он используется как разделитель аргументов, поэтому не закрывает группу.)
Итак, это расширяется за один шаг до
A \fbox{SomeFunctionName} B\egroup
и
A \fbox{SomeFunctionName} B
набирается, и наконец
\egroup
закрывает группу, начатую {
в исходном файле.
решение2
Я бы предпочел такой подход: использовать функцию поиска и замены в вашем любимом редакторе и заменить {\defun
на \textdefun{
.
EDIT: Как отмечает @Clément, это не работает в таких случаях, как \section{\defun abc def}
. Боюсь, что эти случаи ускользнут даже от более сложного подхода на основе регулярных выражений, поскольку придется добавлять дополнительную закрывающую скобку.
решение3
Вы можете сделать это с помощью \aftergroup
:
\documentclass{article}
\protected\def\defun{\aftergroup\newdefun\aftergroup{}}
\newcommand\newdefun[1]{\fbox{#1}}
\begin{document}
\tableofcontents
\section{Here {\defun SomeFunctionName arg1 arg2}}
Call {\defun SomeFunctionName} to foo the bar.
\end{document}
Действует то же ограничение, что и в ответе Дэвида Карлайла: вызовы, \defun
которые не появляются внутри пары фигурных скобок, будут нарушены. В случае
\section{\defun Whatever}
ошибка будет при обработке \tableofcontents
. Но \section{{\defun Whatever}}
будет вести себя хорошо.