Comportamento estranho de \jobname

Comportamento estranho de \jobname

Suponha que eu tenha um arquivo chamado G1 (SK).texcontendo

\def\SK{SK}

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

\expandafter\parse\jobname

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

\bye

Quando eu executo, ele imprime distinct, mesmo que o valor de jobnameseja "G1 (SK)". Quando eu uso

\expandafter\parse"G1 (SK)"

funciona como esperado e imprime equal.

Como posso consertar isso?

Responder1

\jobnameproduz caracteres do código de categoria 12, enquanto o texto de substituição \SKcontém caracteres do código de categoria 11.

Existem várias maneiras de lidar com o problema. Se você usar pdftexsuporte a extensões e-TeX

\edef\SK{\detokenize{SK}}

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

\expandafter\parse\jobname

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

\bye

Você também pode explorar \pdfstrcmp:

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

\expandafter\parse\jobname

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

\bye

porque \pdfstrcmpa comparação de strings é independente dos códigos de categoria (e expande macros em seus argumentos).

De qualquer forma, você não deveria fazer isso \def\language, porque \languageé uma primitiva do TeX.

Uma solução mais flexível com 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

Isso imprime “O idioma é SK”, mas se eu usar um nome de trabalho diferente, digamos XYZ(X), recebo “Idioma indefinido”.

O comando \checklanguageé totalmente expansível e funciona em \edef. O token a ser executado para cada string depende de você e do aplicativo pretendido. Observe que você não precisa se preocupar com as aspas adicionadas se houver um espaço no nome, porque as primeiras linhas apenas extraem o que está entre os (primeiro conjunto de) parênteses.

Responder2

\jobnameatribui o código de categoria 12 a todos os caracteres, exceto espaço, quando definido. Você pode obter o resultado desejado fazendo algo assim:

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

informação relacionada