解析 utf8 问题

解析 utf8 问题

在使用时存在许多问题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}

相关内容