Strano comportamento di \ jobname

Sep 01 2020

Supponiamo che io abbia un file denominato G1 (SK).texcontenente

\def\SK{SK}

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

\expandafter\parse\jobname

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

\bye

Quando lo eseguo, stampa distinct, anche se il valore di jobnameè "G1 (SK)". Quando uso

\expandafter\parse"G1 (SK)"

funziona come previsto e stampa equal.

Come posso risolvere questo problema?

Risposte

4 egreg Sep 01 2020 at 19:56

\jobnameproduce caratteri del codice categoria 12, mentre il testo sostitutivo di \SKcontiene caratteri del codice categoria 11.

Esistono diversi modi per affrontare il problema. Se usi pdftexche supporta le estensioni e-TeX

\edef\SK{\detokenize{SK}}

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

\expandafter\parse\jobname

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

\bye

Potresti anche sfruttare \pdfstrcmp:

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

\expandafter\parse\jobname

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

\bye

perché \pdfstrcmpfa il confronto tra stringhe indipendentemente dai codici di categoria (ed espande le macro nei suoi argomenti).

In ogni caso, non dovresti farlo \def\language, perché \languageè una primitiva di TeX.

Una soluzione più flessibile 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

Viene stampato "La lingua è SK", ma se utilizzo un nome lavoro diverso, ad esempio XYZ(X), ottengo "Lingua non definita ".

Il comando \checklanguageè completamente espandibile e quindi funziona in \edef. Il token da eseguire per ogni stringa dipende da te e dall'applicazione prevista. Nota che non devi preoccuparti delle virgolette aggiunte se c'è uno spazio nel nome, perché le prime righe estraggono semplicemente ciò che è tra le parentesi (primo gruppo di).

4 DonHosek Sep 01 2020 at 18:44

\jobnameassegna il codice di categoria 12 a tutti i caratteri tranne lo spazio quando è impostato. Puoi ottenere il risultato desiderato facendo qualcosa del genere:

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