非 ASCII 字符作为参数

非 ASCII 字符作为参数

我想对文本中的某些字符进行一些特殊处理。在此示例中,只是将它们加粗:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\newcommand\<[1]{\textbf{#1}}

\begin{document}
f\<oo b\<ar b\<öll
\end{document}

对于前两种情况,此方法有效,但对于非 ascci 字符“ö”则无效。出现错误消息

! Package inputenc Error: Unicode char \u8:\check@icr not set up for use with LaTeX.

这是在 utf8 中组成“ö”的两个字节之间报告的。

  1. 我知道这适用于 XeLaTeX 或 LuaLaTeX(只需删除 inputenc 行)。它不适用于 pdfLaTeX 和 (DVI)LaTeX。

  2. 一个解决方法是写入\<{ö}

  3. 但是有没有办法让它与 pdflatex 一起工作而不使用那个解决方法?

(在实际应用中,使用活动字符,因为目的是尽可能少地干扰源文本的视图。)

答案1

你可以这样做,但我不确定你是否应该这样做:-)

在此处输入图片描述

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

%\newcommand\<[1]{\textbf{#1}}
\makeatletter
\def\<{\expandafter\zz}
\def\zz#1{%
   \ifx\UTFviii@two@octets#1% could be 3 or 4 octets, but not today
     \expandafter\zztwo
    \else
     \expandafter\zzone{#1}%
 \fi}
\def\zztwo#1#2{\zzone{\UTFviii@two@octets#1#2}}
\makeatother
\def\zzone#1{\textbf{#1}}

\begin{document}

f\<oo b\<ar b\<öll


f\<{o}o b\<ar b\<{ö}ll

\end{document}

答案2

我很抱歉我的回答不是 LaTeX 格式的,但我想说的是,我们将 UTF-8 代码视为普通 8 位 pdftex 中的一个标记,这样我们就可以避免 David 和 egreg 的答案中显示的复杂性。您可以尝试创建 UTF-8 编码文件:

\input lmfonts

\def\<#1{{\bf#1}}
f\<oo b\<öll €\<€ f\<{oö} f\< öo
\bye

并通过 进行处理pdftex -fmt csplain test.tex

来自 egreg 的图片

说明:该格式csplain由 pdfTeX 的 encTeX 扩展生成,它能够在输入处理器级别解释 UTF-8 代码,并将它们作为单个标记(字节或控制序列)返回给标记处理器。它能够将\write原始 UTF-8 代码返回到日志和文件。

答案3

通用答案,也涵盖三字节和四字节 UTF-8 字符的情况;\<ö\<{ö}允许。如果出现空格,如上例所示,则删除该空格。

也许应该添加一个控制序列测试,以便捕获错误的输入;只要您只有字符或{之后的字符\<,它就应该是安全的。

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{textcomp}
\usepackage{lmodern}

\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\<}{}
 {
  \pst_boldify:
 }

\tl_new:N \l__pst_first_byte_tl
\cs_new_protected:Npn \pst_boldify:
 {
  \peek_catcode_ignore_spaces:NTF \c_group_begin_token
   {
    \textbf
   }
   {
    \pst_boldify_aux:N
   }
 }

\cs_new_protected:Npn \pst_boldify_aux:N #1
 {
  \tl_set:Nx \l__pst_first_byte_tl
   {
    \int_compare:nT { `#1 < 128 } { 0 }
    \int_to_bin:n { `#1 }
   }
  \regex_replace_once:nnN { 0[01]*\Z } { } \l__pst_first_byte_tl
  \str_case:on { \l__pst_first_byte_tl }
   {
    { }      { \textbf { #1 } }
    { 11 }   { \pst_do_bold:nn { #1 } }
    { 111 }  { \pst_do_bold:nnn { #1 } }
    { 1111 } { \pst_do_bold:nnnn { #1 } }
   }
 }
\cs_new_protected:Npn \pst_do_bold:nn #1 #2
 {
  \textbf{#1#2}
 }
\cs_new_protected:Npn \pst_do_bold:nnn #1 #2 #3
 {
  \textbf{#1#2#3}
 }
\cs_new_protected:Npn \pst_do_bold:nnnn #1 #2 #3 #4
 {
  \textbf{#1#2#3#4}
 }

\ExplSyntaxOff

\begin{document}
f\<oo b\<öll €\<€ f\<{oö} f\< öo
\end{document}

其思路是,如果下一个标记(删除空格后)是括号,则\textbf执行 just。否则,检查下一个标记并将其转换为二进制形式的字符代码;从包含的第一个零开始删除所有内容,以确定我们必须管理的 UTF-8 字符是一字节、两字节、三字节还是四字节。最后,做出适当的决定。

在此处输入图片描述

无需正则表达式替换,即可执行算术测试;\pst_boldify_aux:N然后应定义

\cs_new_protected:Npn \pst_boldify_aux:N #1
 {
  \int_compare:nTF { `#1<128 }
   {
    \textbf
   }
   {
    \int_compare:nTF { 192 <= `#1 < 224 }
     {
      \pst_do_bold:nn { #1 }
     }
     {
      \int_compare:nTF { 224 <= `#1 < 240 }
       {
        \pst_do_bold:nnn { #1 }
       }
       {
        \pst_do_bold:nnnn { #1 }
       }
     }
   }
 }

其余部分保持原样(除了l3regex不再需要加载)。

相关内容