在 lualatex 中定义 unicode 字符的替换

在 lualatex 中定义 unicode 字符的替换

过去我问过一个关于在 xelatex 的情况下用 unicode 字符 (FFFD) 替换字符的问题(定义 unicode 字符的替换),效果很好。现在我也需要它用于 lualatex,并发现:在 LuaLaTeX 和 XeLaTeX 中实现 \DeclareUnicodeCharacter

因此我尝试实现它(请注意,由于它之前崩溃了,因此还没有文档):

\documentclass{book}
\usepackage{ifluatex}

\newif\ifunicode
\ifluatex\unicodetrue\fi

\ifunicode
  \usepackage{fontspec}
  \usepackage{newunicodechar}
  \newcommand{\DeclareUnicodeCharacter}[2]{%
    \begingroup\lccode`|=\string"#1\relax
    \lowercase{\endgroup\newunicodechar{|}}{#2}%
  }
\else
  \usepackage[utf8]{inputenc}
\fi

\def\ucr{\adjustbox{width=\CodeWidthChar,height=\CodeHeightChar}{\stackinset{c}{}{c}{-.2pt}{%
   \textcolor{white}{\sffamily\bfseries\small ?}}{%
   \rotatebox{45}{$\blacksquare$}}}}

\ifunicode
  \DeclareUnicodeCharacter{FFFD}{\ucr}
\else
  % some other stuff
\fi

\begin{document}
\end{document}

尽管这给出了错误信息:

! String contains an invalid utf-8 sequence.
\newunicodechar #1#2->\if \relax \detokenize {#1}
                                                 \relax \nuc@emptyargerr \el...

l.23   \DeclareUnicodeCharacter{FFFD}{\ucr}

有什么解决办法吗?

编辑,基于@DavidCarlisle(因为可读性而使用编辑):我尝试\newunicode{?}{\ucr}并得到:

! Undefined control sequence. l.24 \newunicode {�}{\ucr}

(并与\newunicode{\ucr}{?} in get

! Undefined control sequence. l.25 \newunicode {\ucr}{�}

答案1

就像 David Carlisle 在评论中提到的那样,\newunicodechar适用于所有引擎。你可以像这样使用它:

\documentclass{book}
\usepackage{ifluatex}

\newif\ifunicode
\ifluatex\unicodetrue\fi

\ifunicode
\else
  \usepackage[utf8]{inputenc}
\fi
\usepackage{newunicodechar}

\def\ucr{X}

\newunicodechar{�}{\ucr}

\begin{document}
Hallo �.
\end{document}

字符 U+FFFD 具有特殊性:LuaTeX 在内部使用它来标记无效的 Unicode,因此每次 LuaTeX 在您的输入中找到 U+FFFD 时,LuaTeX 都会显示一条错误消息。如果您告诉 LuaTeX 继续,您的文档应该仍能正常工作。

这是一个很好的例子,说明为什么你的源代码永远不应该包含这样的字符。如果你仍然想这样做,你可以在 LuaTeX 看到之前使用 Lua 回调来替换 U+FFFD 字符:

\documentclass{book}
\usepackage{ifluatex}
\usepackage{newunicodechar}

\ifluatex
\usepackage{luacode}
\else
  \usepackage[utf8]{inputenc}
\fi

\def\ucr{X}

\ifluatex
  \begin{luacode*}
    luatexbase.add_to_callback('process_input_buffer', function(buf)
      return buf:gsub(string.utfcharacter(0xFFFD), [[\ucr ]])
    end, 'replace U+FFFD')
  \end{luacode*}
\else
  \newunicodechar{�}{\ucr}
\fi

\begin{document}
Hallo �.
\end{document}

相关内容