
我想對文本中的某些字元做一些特別的事情。在這個例子中,只是將它們加粗:
\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
執行。否則,檢查下一個標記並將其轉換為二進位形式的字元代碼;所有內容都從包含的第一個零中刪除,以確定我們要管理的 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
不再需要加載)。