在 Knuthian TeX 中检测 \input-file(而不是 \read-file)的结尾?

在 Knuthian TeX 中检测 \input-file(而不是 \read-file)的结尾?

在 Knuthian-TeX 中,我想要一个宏,它可以切换到 verbatim-category-code-régime,然后调用另一个宏,该宏逐个处理当前输入文件中的字符,直到到达当前输入文件的末尾。

就像是:

\def\initprocessloop
  {%
    \begingroup
    \catcode`\\=12 \catcode`\{=12 \catcode`\}=12 \catcode`\$=12 %
    \catcode`\&=12 \catcode`\#=12 \catcode`\^=12 \catcode`\^^M=12 %
    \catcode`\^^I=12 \catcode`\_=12 \catcode`\^^A=12 \catcode`\%=12 %
    \catcode`\~=12 \catcode`\ =12 \processloop
  }
\def\processloop #1%
  {%
    There is the character ``\string#1.''
    \if⟨end of current input-file is not reached⟩%
    \expandafter\processloop\else\expandafter\endgroup\fi
  }

问题:

是否有可能在 Knuthian-TeX 中实现测试?\if⟨end of current input-file is not reached⟩..\else..\fi

思考在 eTeX 中我可以使用\everyeof这个,但我明确要求使用 Knuthian-TeX。

我不想使用它,\read因为\read它会连续读取尽可能少的括号平衡行集,并且每当读取这样的集合时就会定义一个宏,而我并不真正需要它,因此认为这是浪费内存。

答案1

由于文件的结尾是\outer(grrr),你不能用宏参数绕过它,但你可以使用它\let,通过一些未记录的限制,你可以报告文件

abc
123
\hbox{123}

作为

the letter a
the letter b
the letter c
the character ^^M
the character 1
the character 2
the character 3
the character ^^M
the character \
the letter h
the letter b
the letter o
the letter x
the character {
the character 1
the character 2
the character 3
the character }
the character ^^M

使用


\def\zz{\afterassignment\zzz\let\tmp= }
\def\zzz{\ifx\tmp\endgroup\endgroup\else\zzzz\expandafter\zz\fi}
\def\zzzz{\immediate\write20{\meaning\tmp}}

\def\setup#1{%
\begingroup
\catcode`\^^M=12 %
\catcode`\\=12 %
\catcode`\{=12 %
\catcode`\}=12 %
\catcode`\ =12 %
\catcode`\%=12 %
\expandafter\zz\input #1 %
\endgroup
}


\setup{\jobname.txt}



\bye

答案2

您希望检测文件的结尾\input

TeXbook,第 20 章:定义(也称为宏),说:

[...] 当宏定义前面带有 时\outer,相应的控制序列将不允许出现在任何正在高速吸收令牌的地方。\outer不能出现在参数 [...] 中,也不能出现在定义的参数文本或替换文本中,也不能出现在对齐的前言中,也不能出现在被跳过的条件文本中。
如果\outer宏确实出现在这些地方,TeX 会停止正在执行的操作并报告“失控”情况或“不完整”条件。输入文件的结尾或对齐模板也被认为是\outer这个意义的;[...]

\if..我怀疑在 Knuthian-TeX 中仅通过纯可扩展例程(例如,完全可扩展的宏或条件)来检测输入文件的结尾是可能的。

我建议使用一个可以利用 ε-TeX 扩展的引擎,并且\everyeof可以用它来放入绝对不是逐字逐句的标记,因此可以被生成出来。

我认为按字符处理大型输入文件可能需要一些时间。



从 TeXbook 第 20 章中可以推断出 - 与 TeX 抓取宏参数/定义的参数文本/定义的替换文本/对齐的前言/要跳过的条件文本的机制不同 - TeX 的分配机制\futurelet不会干扰文件结尾的事实\outer

因此,人们可以\futurelet在使用宏抓取参数之前,滥用这种方法来摆脱文件的结尾。

当然,这意味着\futurelet在每次获取参数的迭代中都有一个-assignment,所以这可能不是您想要的,但是为了完整性而提出这个技巧。

示例文件样本通过以下方式逐字处理\input

abc
123
\hbox{123}

\input处理-file verbatim的代码:

\long\def\firstoftwo#1#2{#1}%
\long\def\secondoftwo#1#2{#2}%
\def\initprocessloop#1%
  {%
    \begingroup
    \catcode`\\=12 \catcode`\{=12 \catcode`\}=12 \catcode`\$=12 %
    \catcode`\&=12 \catcode`\#=12 \catcode`\^=12 \catcode`\^^M=12 %
    \catcode`\^^I=12 \catcode`\_=12 \catcode`\^^A=12 \catcode`\%=12 %
    \catcode`\~=12 \catcode`\ =12 %
    \expandafter\futurelet\expandafter\scratchy\expandafter\processloop\input"#1"\relax
  }%
\begingroup
\endlinechar=-1 % <- ends of lines will not yield spaces with this setting.
\catcode`\^^M=12 \catcode`\^^I=12 \catcode`\^^A=12 %
\firstoftwo{
  \endgroup
  \def\processloop#1
    {
      \ifx\relax#1\expandafter\firstoftwo\else\expandafter\secondoftwo\fi
      {\endgroup}{
        \par There is the %
             \if\string#1^^Mreturn character\else
               \if\string#1^^Ihorizontal tab character\else
                 \if\string#1^^Astart of heading character\else
                   character ``{\tt\string#1}''
                 \fi
               \fi
             \fi
             .
        \futurelet\scratchy\processloop
      }
    }
}{}%
%%
\initprocessloop{sample.tex}
\bye

pdf 输出:

在此处输入图片描述

相关内容