在使用时存在许多问题utf8
输入编码时的问题有关的问题,我认为最接近我的问题是,普通文本文档中的哪些字符会破坏 LaTeX?。
我的软件包的一个用户censor
问我是否可以让软件包的\blackout
宏处理utf8
变音符号。到目前为止,答案是“不”。我将问题缩小到宏\bl@t
,该宏审查参数#2
,然后通过参数重新调用递归#1
。我能说的最好的问题是,utf8
编码需要超过 1 个字节来处理变音符号之类的东西,因此#2
传递给的\bl@t
只有半个字符,因此它会阻塞。
这是一个 MWE,如果取消注释其中两行注释中的任意一行,都会破坏代码:
\documentclass{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{censor}
\makeatletter
\def\stringend{$}
\long\def\blackout#1{\def~{-}\censor@Block#1\stringend\let~\sv@tilde}
\long\def\censor@Block{\IfNextToken\stringend{\@gobble}%
{\IfNextToken\@sptoken{ \bl@t{\censor@Block}}%
{\bl@t{\censor@Block}}}}
\long\def\bl@t#1#2{\if\bpar#2\par\else\if.#2\censordot\else\censor{#2}\fi\fi#1}
\makeatother
\begin{document}
äöüß, \censor{äöüß}\par
\blackout{ab\par cd}\par
%\blackout{ä}\par
\makeatletter
%\bl@t xä
\end{document}
包的\censor
宏在变音符上工作得很好,但\blackout
更具体地说,\bl@t
服务例程却不行。如果您希望它更简单,您可以将视为\bl@t
(\def\bl@t#1#2{\censor{#2}#1}
但这不适用于\par
输入流中的 s)。始终是对剩余输入字符串#1
的重新调用。\censor@Block
编辑:看起来,如果输入流中接下来是一个多字节输入字符,那么这个定义
\long\def\bl@t#1#2#3{\if\bpar#2#3\par\else\if.#2#3\censordot\else
\censor{#2#3}\fi\fi#1}
可以正确吸收它。因此,反转注释的调用:
%\blackout{ab\par cd}\par
\blackout{äöüß}\par
\makeatletter
\bl@t xä
运行良好。因此,关键在于能够提前确定输入流中接下来是什么类型的字符,并选择适当的解析方法。
答案1
与其担心 utf-8,不如让 inputenc 担心这个问题,将所有字符扩展为 LICR(latex 内部格式),这样你就可以支持[latin1]
或任何其他东西了。我还修改了\if
它\ifx
,因为它\if
看起来不对(虽然我真的不知道代码在做什么:-)
\documentclass{article}
\usepackage[ngerman]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{censor}
\makeatletter
\def\stringend{$}
\long\def\blackout#1{%
\protected@edef\tmp{#1}%
\def~{-}\expandafter\censor@Block\tmp\stringend\let~\sv@tilde}
\long\def\censor@Block{\IfNextToken\stringend{\@gobble}%
{\IfNextToken\@sptoken{ \bl@t{\censor@Block}}%
{\bl@t{\censor@Block}}}}
\long\def\bl@t#1#2{%
\ifx\bpar#2\let\next\par\else\ifx.#2\let\next\censordot\else\def\next{\censor{#2}}\fi\fi
\next#1}
\makeatother
\begin{document}
äöüß, \censor{äöüß}\par
abcd, \censor{abcd}\par
\blackout{ab\par cd}\par
\blackout{ä}\par
\end{document}