![非 ASCII 字符作为参数](https://linux22.com/image/290292/%E9%9D%9E%20ASCII%20%E5%AD%97%E7%AC%A6%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0.png)
我想对文本中的某些字符进行一些特殊处理。在此示例中,只是将它们加粗:
\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 中组成“ö”的两个字节之间报告的。
我知道这适用于 XeLaTeX 或 LuaLaTeX(只需删除 inputenc 行)。它不适用于 pdfLaTeX 和 (DVI)LaTeX。
一个解决方法是写入
\<{ö}
。但是有没有办法让它与 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
。
说明:该格式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
不再需要加载)。