非 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執行。否則,檢查下一個標記並將其轉換為二進位形式的字元代碼;所有內容都從包含的第一個零中刪除,以確定我們要管理的 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不再需要加載)。

相關內容