Странное поведение \ jobname
Предположим, у меня есть файл с именем, G1 (SK).texсодержащий
\def\SK{SK}
\def\parse"#1 (#2)"{\def\language{#2}}
\expandafter\parse\jobname
\ifx\SK\language equal\else distinct\fi
\bye
Когда я запускаю его, он печатает distinct, даже если значение jobnameравно "G1 (SK)". Когда я использую
\expandafter\parse"G1 (SK)"
он работает как положено и печатает equal.
Как я могу это исправить?
Ответы
\jobnameпроизводит символы кода категории 12, а замещающий текст \SKсодержит символы кода категории 11.
Есть несколько способов справиться с проблемой. Если вы используете, pdftexкоторый поддерживает расширения e-TeX
\edef\SK{\detokenize{SK}}
\def\parse"#1 (#2)"{\def\filelanguage{#2}}
\expandafter\parse\jobname
\ifx\SK\filelanguage equal\else distinct\fi
\bye
Вы также можете использовать \pdfstrcmp:
\def\parse"#1 (#2)"{\def\filelanguage{#2}}
\expandafter\parse\jobname
\ifnum\pdfstrcmp{SK}{\filelanguage}=0 equal\else distinct\fi
\bye
потому \pdfstrcmpчто сравнение строк не зависит от кодов категорий (и расширяет макросы в своих аргументах).
В любом случае этого делать не следует \def\language, потому что \languageэто примитив TeX.
Более гибкое решение с 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
Это напечатает «Язык - SK», но если я использую другое имя, скажем XYZ(X), я получаю «Неопределенный язык».
Команда \checklanguageполностью расширяема и поэтому работает в \edef. Токен, выполняемый для каждой строки, зависит от вас и вашего предполагаемого приложения. Обратите внимание, что вам не нужно заботиться о добавленных кавычках, если в имени есть пробел, потому что первые строки просто извлекают то, что находится между (первым набором) круглых скобок.
\jobnameприсваивает код категории 12 всем символам, кроме пробела, если он установлен. Вы можете получить желаемый результат примерно так:
{
\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