Comportamiento extraño de \ jobname

Sep 01 2020

Supongamos que tengo un archivo llamado que G1 (SK).texcontiene

\def\SK{SK}

\def\parse"#1 (#2)"{\def\language{#2}}

\expandafter\parse\jobname

\ifx\SK\language equal\else distinct\fi

\bye

Cuando lo ejecuto, se imprime distinct, incluso si el valor de jobnamees "G1 (SK)". Cuando uso

\expandafter\parse"G1 (SK)"

funciona como se esperaba y se imprime equal.

¿Cómo puedo arreglar esto?

Respuestas

4 egreg Sep 01 2020 at 19:56

\jobnameproduce caracteres del código de categoría 12, mientras que el texto de reemplazo de \SKcontiene caracteres del código de categoría 11.

Hay varias formas de afrontar el problema. Si usa pdftexque admite extensiones e-TeX

\edef\SK{\detokenize{SK}}

\def\parse"#1 (#2)"{\def\filelanguage{#2}}

\expandafter\parse\jobname

\ifx\SK\filelanguage equal\else distinct\fi

\bye

También podrías aprovechar \pdfstrcmp:

\def\parse"#1 (#2)"{\def\filelanguage{#2}}

\expandafter\parse\jobname

\ifnum\pdfstrcmp{SK}{\filelanguage}=0 equal\else distinct\fi

\bye

porque \pdfstrcmphace una comparación de cadenas independiente de los códigos de categoría (y expande macros en sus argumentos).

En cualquier caso, no debería hacerlo \def\language, porque \languagees una primitiva de TeX.

Una solución más flexible con expl3.

\input expl3-generic

\ExplSyntaxOn
\str_new:N \l_bak_file_language_str
\str_set_eq:NN \l_bak_file_language_str \c_sys_jobname_str
\regex_replace_once:nnN { .*? \((.*)\) .* } { \1 } \l_bak_file_language_str

% now the string variable contains the string in parentheses
% extracted from the jobname

\cs_new:Npn \checklanguage
 {
  \str_case:VnF { \l_bak_file_language_str }
   {
    {SK}{Language~is~SK}
    {AB}{Language~is~AB}
    {XYZ}{Language~is~XYZ}
   }
   {Undefined~language}
 }
\ExplSyntaxOff

\checklanguage

\bye

Esto imprime "El idioma es SK", pero si utilizo un nombre de trabajo diferente, por ejemplo XYZ(X), obtengo "Idioma no definido ".

El comando \checklanguagees completamente expandible y, por lo tanto, funciona en formato \edef. El token que se ejecutará para cada cadena depende de usted y de su aplicación prevista. Tenga en cuenta que no necesita preocuparse por las comillas agregadas si hay un espacio en el nombre, porque las primeras líneas simplemente extraen lo que está entre el (primer conjunto de) paréntesis.

4 DonHosek Sep 01 2020 at 18:44

\jobnameasigna el código de categoría 12 a todos los caracteres excepto al espacio cuando está configurado. Puede obtener el resultado deseado haciendo algo como esto:

{
  \catcode`\S=12
  \catcode`\K=12
\gdef\sk{SK}
}
\def\parse"#1 (#2)"{\def\language{#2}}

\expandafter\parse\jobname

\ifx\sk\language equal\else distinct\fi

\bye