我可以让命令不吞噬空格吗?

我可以让命令不吞噬空格吗?

(我正在使用 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)。

相关内容