过去我问过一个关于在 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}