Dziwne zachowanie \ jobname

Sep 01 2020

Załóżmy, że mam plik o nazwie G1 (SK).texzawierający

\def\SK{SK}

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

\expandafter\parse\jobname

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

\bye

Kiedy go uruchamiam, drukuje distinct, nawet jeśli wartość jobnamewynosi "G1 (SK)". Kiedy używam

\expandafter\parse"G1 (SK)"

działa zgodnie z oczekiwaniami i drukuje equal.

Jak mogę to naprawić?

Odpowiedzi

4 egreg Sep 01 2020 at 19:56

\jobnametworzy znaki o kodzie kategorii 12, natomiast tekst zastępczy \SKzawiera znaki o kodzie kategorii 11.

Istnieje kilka sposobów rozwiązania tego problemu. Jeśli używasz pdftextego, który obsługuje rozszerzenia e-TeX

\edef\SK{\detokenize{SK}}

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

\expandafter\parse\jobname

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

\bye

Możesz także wykorzystać \pdfstrcmp:

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

\expandafter\parse\jobname

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

\bye

ponieważ \pdfstrcmpporównuje ciągi niezależnie od kodów kategorii (i rozwija makra w swoich argumentach).

W każdym razie nie powinieneś tego robić \def\language, ponieważ \languagejest to prymityw TeX.

Bardziej elastyczne rozwiązanie z 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

Wyświetla „Język to SK”, ale jeśli użyję innej nazwy stanowiska, powiedzmy XYZ(X), otrzymam „Niezdefiniowany język”.

Polecenie \checklanguagejest w pełni rozszerzalne, więc działa w \edef. Token do wykonania dla każdego ciągu zależy od Ciebie i Twojej aplikacji. Zwróć uwagę, że nie musisz przejmować się dodawanymi cudzysłowami, jeśli w nazwie jest spacja, ponieważ pierwsze wiersze po prostu wyodrębniają to, co znajduje się między (pierwszym zestawem) nawiasów.

4 DonHosek Sep 01 2020 at 18:44

\jobnameprzypisuje kod kategorii 12 do wszystkich znaków z wyjątkiem spacji, gdy jest ustawiony. Możesz uzyskać pożądany rezultat, robiąc coś takiego:

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