我正在尝试使用 (La)TeX 作为编程语言的宏预处理器。我的想法是使用包VerbatimOut
中的环境fancyvrb
输出基本上逐字的文本,但使用@
转义字符来引入宏。以下是我所想到的一个例子:
\documentclass{article}
\usepackage{fancyvrb}
\def\definesortfunction #1;{%
#1[] sort(#1[] a) {
if (a.length <= 1) return a;
static #1[] merge(#1[] b, #1[] c) {
#1[] toreturn;
int i = 0, j = 0;
while (i < b.length && j < c.length) {
if (!(c[j] < b[i])) { toreturn.push(b[i]); ++i; }
else { toreturn.push(c[j]); ++j; }
}
while (i < b.length) {
toreturn.push(b[i]);
++i;
}
while (j < c.length) {
toreturn.push(c[j]);
++j;
}
return toreturn;
}
int halfway = floor(a.length / 2);
#1[] b = sort(a[0:halfway]);
#1[] c = sort(a[halfway:a.length]);
return merge(b, c);
}}
\begin{VerbatimOut}[commandchars=@\#~]{testoutputfile.asy}
bool operator <(pair a, pair b) {
return (a.x < b.x || (a.x == b.x && a.y < b.y));
@definesortfunction pair;
\end{VerbatimOut}
\begin{document}
\VerbatimInput{testoutputfile.asy}
\end{document}
就 Asymptote 编译器而言,生成的文件运行良好。问题是 Asymptote 源文件几乎不可读(对人类而言),因为整个宏都排版在一行上 — — 包括最初以三个不同的换行符开头的行。
通过使用活动字符,我能够用字母^^M
或替换换行符\par
(这两者都会破坏 Asymptote 编译器),但我还没有找到用实际换行符替换它们的方法。我该怎么做?
(请注意,我绝不执着于该fancyvrb
软件包;任何具有自定义转义的逐字文件输出环境都可以让我满意,包括当场创建的转义字符。但由于 TeX 代码有时会出现在 Asymptote 文件中,因此能够自定义转义字符至关重要。)
答案1
如果您只需要宏来替换环境VerbatimOut
,那么有以下可能性:
\documentclass{article}
\usepackage{fancyvrb}
\begingroup
\endlinechar=`^^J \obeyspaces% end of lines are newlines
\gdef\definesortfunction #1;{% eat up the space following the macro
#1[] sort(#1[] a) {
if (a.length <= 1) return a;
static #1[] merge(#1[] b, #1[] c) {
#1[] toreturn;
int i = 0, j = 0;
while (i < b.length && j < c.length) {
if (!(c[j] < b[i])) { toreturn.push(b[i]); ++i; }
else { toreturn.push(c[j]); ++j; }
}
while (i < b.length) {
toreturn.push(b[i]);
++i;
}
while (j < c.length) {
toreturn.push(c[j]);
++j;
}
return toreturn;
}
int halfway = floor(a.length / 2);
#1[] b = sort(a[0:halfway]);
#1[] c = sort(a[halfway:a.length]);
return merge(b, c);
}% this % is necessary
}% this % is necessary
\endgroup% this % is necessary
\begin{document}
\begin{VerbatimOut}[commandchars=@\#~]{testoutputfile.asy}
bool operator <(pair a, pair b) {
return (a.x < b.x || (a.x == b.x && a.y < b.y));
@definesortfunction pair;
\end{VerbatimOut}
\VerbatimInput{testoutputfile.asy}
\end{document}
清单如下testoutputfile.asy
:
bool operator <(pair a, pair b) {
return (a.x < b.x || (a.x == b.x && a.y < b.y));
pair[] sort(pair[] a) {
if (a.length <= 1) return a;
static pair[] merge(pair[] b, pair[] c) {
pair[] toreturn;
int i = 0, j = 0;
while (i < b.length && j < c.length) {
if (!(c[j] < b[i])) { toreturn.push(b[i]); ++i; }
else { toreturn.push(c[j]); ++j; }
}
while (i < b.length) {
toreturn.push(b[i]);
++i;
}
while (j < c.length) {
toreturn.push(c[j]);
++j;
}
return toreturn;
}
int halfway = floor(a.length / 2);
pair[] b = sort(a[0:halfway]);
pair[] c = sort(a[halfway:a.length]);
return merge(b, c);
}
输出如下:
答案2
我认为,这类似于各种可用的“问题解决”包所实现的尝试LaTeX
,其中问题的解决方案是排版的,而不是扩展的,而是逐字写入另一个文件以包含在其他位置。
您的方法是首先扩展宏,然后将它们逐字写入编程语言源代码文件?
在我看来,值得看一下包装tcolorbox
——它确实有这样的功能,并且您对LaTeX
输出本身不感兴趣,所以没有必要担心颜色框。