1

Assume I have a file named G1 (SK).tex containing

\def\SK{SK}

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

\expandafter\parse\jobname

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

\bye

When I run it, it prints distinct, even if the value of jobname is "G1 (SK)". When I use

\expandafter\parse"G1 (SK)"

it works as expected and prints equal.

How can I fix this?

2

2 Answers 2

4

\jobname produces characters of category code 12, while the replacement text of \SK contains characters of category code 11.

There are several ways to cope with the problem. If you use pdftex that supports e-TeX extensions

\edef\SK{\detokenize{SK}}

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

\expandafter\parse\jobname

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

\bye

You could also exploit \pdfstrcmp:

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

\expandafter\parse\jobname

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

\bye

because \pdfstrcmp does string comparison independent of category codes (and expands macros in its arguments).

In any case, you shouldn't do \def\language, because \language is a TeX primitive.

A more flexible solution with 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

This prints “Language is SK”, but if I use a different jobname, say XYZ(X), I get “Undefined language”.

The command \checklanguage is fully expandable and so works in \edef. The token to execute for each string are up to you and your intended application. Note that you don't need to care about the quotes added if there is a space in the name, because the first lines just extract what's between the (first set of) parentheses.

2
  • Thanks. By the way, do you know whether regex_replace_once is implemented using only TeX primitives? It looks very difficult
    – Patrik Bak
    Sep 2, 2020 at 12:18
  • @PatrikBak e-TeX is required
    – egreg
    Sep 2, 2020 at 12:21
4

\jobname assigns category code 12 to all characters except space when it's set. You can get your desired result doing something like this:

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .