Caractere não-ascii como argumento

Caractere não-ascii como argumento

Quero fazer algo especial com alguns caracteres do texto. Neste exemplo, isso está apenas em negrito:

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\newcommand\<[1]{\textbf{#1}}

\begin{document}
f\<oo b\<ar b\<öll
\end{document}

Isso funciona bem para os dois primeiros casos, mas não para o caractere não-ascci "ö". Há uma mensagem de erro

! Package inputenc Error: Unicode char \u8:\check@icr not set up for use with LaTeX.

que é relatado entre os dois bytes que compõem "ö" em utf8.

  1. Eu sei que isso funciona com XeLaTeX ou LuaLaTeX (apenas removendo a linha inputenc). Não funciona em pdfLaTeX e (DVI)LaTeX.

  2. Uma solução alternativa é escrever \<{ö}.

  3. Mas existe uma maneira de fazer isso funcionar com o pdflatex sem essa solução alternativa?

(Na aplicação real é usado um caractere ativo, pois o objetivo é ter algo que perturbe o menos possível a visualização do texto fonte.)

Responder1

Você pode fazer isso, mas não tenho certeza se deveria :-)

insira a descrição da imagem aqui

\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}

Responder2

Lamento pela minha resposta não-LaTeX, mas gostaria de dizer quepodetrate os códigos UTF-8 como um token no pdftex normal de 8 bits e podemos evitar as complicações mostradas nas respostas de David e egreg. Você pode tentar criar o arquivo codificado em UTF-8:

\input lmfonts

\def\<#1{{\bf#1}}
f\<oo b\<öll €\<€ f\<{oö} f\< öo
\bye

e processe-o por pdftex -fmt csplain test.tex.

uma imagem de egreg

Explicação: O formato csplainé gerado com a extensão encTeX do pdfTeX, que é capaz de interpretar códigos UTF-8 no nível do processador de entrada e os retorna como tokens únicos (byte ou sequência de controle) para o processador de tokens. É capaz de retornar ao log e \writearquivar os códigos UTF-8 originais.

Responder3

Uma resposta geral, cobrindo também os casos de caracteres UTF-8 de três e quatro bytes; \<öou \<{ö}é permitido. Se um espaço se infiltrar, como no último exemplo, ele será removido.

Talvez deva ser adicionado um teste para uma sequência de controle, para detectar entradas erradas; contanto que você tenha apenas caracteres ou {depois \<, deve 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}

A ideia é que se o próximo token (depois de remover os espaços) for uma chave, apenas \textbfseja executado. Caso contrário, o próximo token é examinado e convertido em um código de caracteres em formato binário; tudo é retirado do primeiro zero incluído para determinar se o caractere UTF-8 que devemos gerenciar é um, dois, três ou quatro bytes. Finalmente, a decisão apropriada é tomada.

insira a descrição da imagem aqui

Sem uma substituição de expressão regular, um teste aritmético pode ser realizado; a definição de \pst_boldify_aux:Ndeveria então ser

\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 }
       }
     }
   }
 }

com o resto como está (exceto que o carregamento l3regexnão é mais necessário).

informação relacionada