我在 macOS 上运行 TeX Live 2018。它附带一个 Python 脚本de-macro
,可以替代个人宏。输入de-macro test.tex
where test.tex
is
\documentclass{amsart}
\newcommand{\e}{\mathrm{e}}
\renewcommand{\i}{\mathrm{i}}
\begin{document}
\[
\e^{\i\pi}=-1
\]
\end{document}
test-clean.tex
生成与 相同的文件test.tex
。我是否错误地使用了 de-macro,如果没有,有人可以确认这种行为吗?
编辑:同时,我了解到我应该将宏写入文件*-private.sty
并加载此文件。即使这样做,似乎也没有发生任何事情,除了\usepackage{*-private.sty}
被删除。
答案1
默认情况下de-macro
似乎不会\newcommand
在主文件中处理等。下面是包含就地处理的实验性尝试。它适用于示例文件,但可以预料到在更复杂的文件上会失败。
Python 源代码中有一个函数scan_defs()
,用于存储命令和环境的定义。其思路是在执行实际替换函数之前,将此函数作为常规文件处理的一部分进行调用。这是通过在函数中process_file()
大约第 1030 行添加一行来实现的。
def process_file(self, file):
"""Returns the new defs.
"""
file = cut_extension(file, ".tex")
source_file = "%s.tex" % (file)
print("File %s [" % (source_file))
source_fp = open(source_file, "r")
text_str = source_fp.read()
source_fp.close()
self.smart_tokenize(text_str, handle_inputs=True)
if not self.data:
raise Error("Empty tokenization result.")
self.reset()
if self.debug:
source_seen_fname = "%s-seen.tex" % (file)
source_seen_fp = open(source_seen_fname, "w")
source_seen_fp.write(detokenize(self.data))
source_seen_fp.close()
self.scan_defs() ### ADDED THIS FUNCTION CALL
self.data = self.apply_all_recur(self.data, report=True)
result_fname = "%s-clean.tex" % (file)
print("Writing %s [" % (result_fname))
result_fp = open(result_fname, "w")
result_fp.write(self.smart_detokenize())
result_fp.close()
print("] file %s" % (result_fname))
print("] file %s" % (source_file))
这很简单,并且可以执行替换。但是,私有宏/环境定义仍然是文件的一部分,因此这会导致
\documentclass{amsart}
\newcommand{\e}{\mathrm{e}}
\renewcommand{\i}{\mathrm{i}}
\begin{document}
\[
\mathrm{e}^{\mathrm{i}\pi}=-1
\]
\end{document}
这相当多余,并且仍然可能导致转换软件、出版商等出现问题。
要从文件中删除现在未使用的定义,scan_defs()
也可以修改函数(大约 750 行)。该self.data
对象是一个标记列表,因此一旦您知道定义的开始和结束,您就可以使用 Pythondel
函数循环删除所有这些标记。在循环结束时,您应该调整列表位置和当前标记以考虑刚刚删除的标记。
def scan_defs(self):
if not self.legal():
raise Error("No definitions to scan.")
self.reset()
command_defs, env_defs = self.defs
while self.uplegal():
if (esc_str_ty == self.item.type
and self.item.val in ["newcommand", "renewcommand"]):
def_start_pos = self.pos
command_def = self.scan_command_def()
command_defs[command_def.name] = command_def
def_end_pos = self.pos
for del_pos in range(def_start_pos,def_end_pos):
del self.data[def_start_pos]
self.pos = def_start_pos
self.item = self.data[self.pos]
elif (esc_str_ty == self.item.type and self.item.val
in ["newenvironment", "renewenvironment"]):
def_start_pos = self.pos
env_def = self.scan_env_def()
env_defs[env_def.name] = env_def
def_end_pos = self.pos
for del_pos in range(def_start_pos,def_end_pos):
del self.data[def_start_pos]
self.pos = def_start_pos
self.item = self.data[self.pos]
else:
self.next()
这将生成以下 LaTeX 文件:
\documentclass{amsart}
\begin{document}
\[
\mathrm{e}^{\mathrm{i}\pi}=-1
\]
\end{document}
请注意,换行符不会被删除,因为它们不是命令定义的一部分。
正如评论中提到的那样,Pandoc 也可以做到这一点,并且无疑更加强大,所以我建议使用它而不是这个答案:)