(我正在使用 ConTeXt,但我怀疑答案可能在于纯 TeX。)
我创建了一个环境,它接受一个参数myBufferName
,并将其内容存储在同名的缓冲区中。不幸的是,参数后面的所有空格都会被吞噬,我不知道如何正确阻止这种情况。如果我将常见的吞噬阻止器{}
和\
放在 之后,它们最终会逐字进入缓冲区\dostartbuffer
。
\startluacode
-- Print contents of buffer b to stdout and tmp.txt for inspection
function printbuffer(b)
-- Once to stdout ...
print('====')
print(buffers.getcontent(b))
print('====')
-- ... and once to tmp.txt.
jan = io.open('tmp.txt', 'w')
jan:write(buffers.getcontent(b))
jan:close()
end
\stopluacode
% This environment stores its contents in a custom-named buffer.
% (The #1 merely allows whitespace, like this: `\startMyBuffer [name]`)
\def\startMyBuffer#1[#2]
{% Store the name --- we'll need it when defining stopMyBuffer
\def\myBufferName{#2}
% ConTeXt macro that defines the \start... and \stop... commands.
\dostartbuffer[#2][startMyBuffer][stopMyBuffer]}
%% % Hack I currently use: a dot at the end of the definition.
%% \def\startMyBuffer#1[#2]
%% {\def\myBufferName{#2}
%% \dostartbuffer[#2][startMyBuffer][stopMyBuffer].}
%% % ^
%% % |
%% % I later remove the dot using Lua.
% On closing the buffer, print its contents.
\def\stopMyBuffer
{\ctxlua
{printbuffer('\myBufferName')}}
% Test it. You'll see the first line loses its leading whitespace :-(
\starttext
\startMyBuffer[myNameIsNobody]
Andra moi ennepe,
mousa,
polutropon.
\stopMyBuffer
\stoptext
当你尝试运行它时,
Andra moi ennepe,
mousa,
polutropon.
作为缓冲区的内容。
答案1
您将宏定义为
\def\startMyBuffer#1[#2]
{....}
为了避免宏观进食空间,使用
\def\startMyBuffer#1[#2]%
{...}
(请注意%
末尾的。下一行末尾也有一个尾随空格。因此,宏的正确定义是
\def\startMyBuffer#1[#2]%
{% Store the name --- we'll need it when defining stopMyBuffer
\def\myBufferName{#2}% <<<<---- ADDED THS
% ConTeXt macro that defines the \start... and \stop... commands.
\dostartbuffer[#2][startMyBuffer][stopMyBuffer]}
如果您不想担心这一切,请使用\starttexdefinition ... \stoptexdefinition
。
\starttexdefinition startMyBuffer #1[#2]
% Store the name --- we'll need it when defining stopMyBuffer
\def\myBufferName{#2}
% ConTeXt macro that defines the \start... and \stop... commands.
\dostartbuffer[#2][startMyBuffer][stopMyBuffer]
\stoptexdefinition
答案2
的一般语法\def
是
\def<name><parameter text>{<replacement text>}
,其中<parameter text>
与输入匹配。参数文本可以包含参数标记(#1
、#2
、...)和其他标记,例如#1[#2]abc
。其他标记与输入完全匹配——在此示例中,如果 TeX 无法找到序列<something>[<something>]abc
,它将停止并显示错误。找到匹配项后,各<something>
部分将被视为每个参数文本定义的宏参数,但其他匹配的标记将被直接吃掉。在您的情况下, 的参数文本\startMyBuffer
在 之后包含空格[#2]
,因此它也将被匹配和吃掉。
查看此 Plain TeX 文档的输出来查看差异:
\def\readsome#1\relax{`#1'}
\def\a[]
{\readsome}
\def\b[]{\readsome}
\a[]
test\relax
\b[]
test\relax
\bye
结论:不要在宏参数文本中放置多余的符号。对于 Plain TeX/LaTeX,{
在指定所有参数后立即跟上 let;对于 ConTeXt,%
在参数文本后放置 a 以忽略换行符和后面的空格。
答案3
我不确定我是否理解了你的问题,但你似乎表明你不想要 TeX 吞噬空白。如果这就是你想要的,请查看命令\obeyspaces
(Plain TeX) 和\obeywhitespace
(eTeX)。