
Я хочу сделать что-то особенное с некоторыми символами в тексте. В этом примере это просто выделение их жирным шрифтом:
\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 и мы можем избежать осложнений, показанных в ответах Дэвида и egreg. Вы можете попробовать создать файл в кодировке UTF-8:
\input lmfonts
\def\<#1{{\bf#1}}
f\<oo b\<öll €\<€ f\<{oö} f\< öo
\bye
и обработать его pdftex -fmt csplain test.tex
.
Объяснение: Формат 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
больше не нужна).