强制 LuaTeX 忽略未知的 Unicode 字符

强制 LuaTeX 忽略未知的 Unicode 字符

我正在尝试以编程方式过滤或忽略无效的 Unicode 字符,例如 U+0002 (␂),我的字体不支持这些字符,这些字符会生成“文本行包含无效字符。刚刚输入了一个我无法读取的奇怪符号。”错误消息。我无法控制输入文本,因此无法手动删除它们,而且可能无效的字符太多,无法尝试明确地重新映射它们。

我正在寻找类似的解决方案 \makeatletter\def\UTFviii@undefined@err#1{}\makeatother方案这里但这适用于 LuaTeX,而不仅适用于 PdfLaTeX。

答案1

TeX 是一个非常复杂的程序,处理全部可能的输入需要测试全部可能的输入。

因此建议您创建一个包含从 0 到 1114111 的所有 Unicode 字符的文件,并将其输入到您的程序中进行测试。

对于您指出的具体错误,错误消息“刚刚输入了一个我无法读取的奇怪符号”是由于...引起的。

TeX 源代码

catcode 为 15 的字符。不是因为字体不支持

注意,LuaTeX 还有另一种情况会打印“有趣的符号”消息,即:

static void utf_error(void)
{
    const char *hlp[] = {
        "A funny symbol that I can't read has just been (re)read.",
        "Just continue, I'll change it to 0xFFFD.",
        NULL
    };
    deletions_allowed = false;
    tex_error("String contains an invalid utf-8 sequence", hlp);
    deletions_allowed = true;
}

无效的 UTF-8 序列。

无论如何,使用查看角色的 catcode,并列出具有给定 catcode 的所有角色我们可以查看类别代码为 15 的所有角色列表:

\documentclass{article}
\begin{document}
\newcount\charcount
\charcount=0
\loop\ifnum\charcount<1114112 % Change to 256 if not using XeTeX/LuaTeX
  \ifnum\catcode\charcount=15
    Character \number\charcount \ has category code \number\catcode\charcount .

  \fi
  \advance\charcount by 1
\repeat
\end{document}

输出结果只有 0 → 31 和 127 个字符。也就是说,控制字符

如果您要自动生成文件,最简单的方法似乎是提前将它们全部过滤掉。


当然,这样做之后,你可能仍然会遇到等问题%\有一些解决方案不依赖于类别代码来排版文本,例如https://wiki.luatex.org/index.php/TeX_without_TeX(但我认为它们不太容易学)

答案2

\documentclass{article}

\begin{document}

ctrl-A []

\end{document}

生产

! Text line contains an invalid character.
l.5 ctrl-A [^^A
           ]
?

经典的方法是使控制字符可打印,如下所示:

\documentclass{article}

\count0=-1
\loop
\advance\count0 by 1
\ifnum\count0=9 \advance\count0 by 2 \fi
\ifnum\count0=13 \advance\count0 by 1 \fi
\catcode\count0=12
\ifnum\count0<31
\repeat
\count0=0

\begin{document}

ctrl-A []

\end{document}

将它们视为(可能)不在字体中的普通字符,因此会发出警告

Missing character: There is no ^^A (U+0001) in font [lmroman10-regular]:+tlig;!

和输出

在此处输入图片描述

拉丁现代字体什么都不显示,有些字体显示缺少的字形标记。

或者你可以替换 Lua 回调中的所有控制字符:

\documentclass{article}
\makeatletter
\directlua{
  function replacectrl (s)
%   return s:gsub("[\@percentchar c]","^^^^fffd") latin modern doesn't have �
   return s:gsub("[\@percentchar c]","?")
  end
  luatexbase.add_to_callback('process_input_buffer',replacectrl,'replace control chars')
  }
\makeatother
\begin{document}

ctrl-A []

\end{document}

生产

在此处输入图片描述

相关内容