Символ, не входящий в набор 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 и мы можем избежать осложнений, показанных в ответах Дэвида и 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генерируется с помощью расширения encTeX pdfTeX, которое способно интерпретировать коды 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больше не нужна).

Связанный контент