
Quiero hacer algo especial con algunos personajes del texto. En este ejemplo, los pone en negrita:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\newcommand\<[1]{\textbf{#1}}
\begin{document}
f\<oo b\<ar b\<öll
\end{document}
Esto funciona bien para los dos primeros casos, pero no para el carácter "ö" que no es ascci. Hay un mensaje de error
! Package inputenc Error: Unicode char \u8:\check@icr not set up for use with LaTeX.
que se informa entre los dos bytes que componen "ö" en utf8.
Sé que esto funciona con XeLaTeX o LuaLaTeX (simplemente eliminando la línea inputenc). No funciona en pdfLaTeX y (DVI)LaTeX.
Una solución es escribir
\<{ö}
.¿Pero hay alguna manera de hacer que esto funcione con pdflatex sin esa solución alternativa?
(En la aplicación real se utiliza un carácter activo, ya que el objetivo es tener algo que perturbe la vista del texto fuente lo menos posible).
Respuesta1
Puedes hacer esto, pero no estoy seguro de que debas hacerlo :-)
\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}
Respuesta2
Lamento mi respuesta que no es LaTeX, pero quisiera indicar quepoderTrate los códigos UTF-8 como un token en un pdftex normal de 8 bits y podremos evitar las complicaciones que se muestran en las respuestas de David y egreg. Puedes intentar crear el archivo codificado en UTF-8:
\input lmfonts
\def\<#1{{\bf#1}}
f\<oo b\<öll €\<€ f\<{oö} f\< öo
\bye
y procesarlo por pdftex -fmt csplain test.tex
.
Explicación: El formato csplain
se genera con la extensión encTeX de pdfTeX, que es capaz de interpretar códigos UTF-8 en el nivel del procesador de entrada y los devuelve como tokens únicos (byte o secuencia de control) al procesador de tokens. Puede volver al registro y \write
archiva los códigos UTF-8 originales.
Respuesta3
Una respuesta general, que cubre también los casos de caracteres UTF-8 de tres y cuatro bytes; \<ö
o \<{ö}
está permitido. Si aparece un espacio, como en el último ejemplo, se elimina.
Tal vez debería agregarse una prueba para una secuencia de control, a fin de detectar entradas incorrectas; Siempre que tengas solo caracteres o {
después \<
, debería ser seguro.
\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}
La idea es que si el siguiente token (después de eliminar espacios) es una llave, simplemente \textbf
se ejecuta. De lo contrario, el siguiente token se examina y se convierte en un código de carácter en formato binario; Se elimina todo desde el primer cero incluido para determinar si el carácter UTF-8 que tenemos que gestionar es de uno, dos, tres o cuatro bytes. Finalmente se toma la decisión adecuada.
Sin una sustitución de expresiones regulares, se puede realizar una prueba aritmética; la definición de \pst_boldify_aux:N
debería ser entonces
\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 }
}
}
}
}
con el resto como está (excepto que l3regex
ya no es necesario cargarlo).