19

In the TeX FAQ there's a way to test if the jobname is equal to something (comparing the jobname). The difficulty of the naïve test is that the contents of the \jobname primitive are catcode 12 so to test if the \jobname is, say, myfile we need to create a macro containing the string myfile but with catcode 12 and use that to compare against \jobname.

This is all very well if you control the test. But what if you don't? What if there's some test deep in some package that you want to pass the \jobname (or some part of it) to and this test is against a predefined word of catcodes 11.

Is there some way, like \meaning, that can convert its contents to catcode 11?

Added in edit: An example of possible use has been called for.

\documentclass{beamer}
%\url{http://tex.stackexchange.com/q/117892/86}

\expandafter\includeonlylecture\expandafter{\jobname}

\begin{document}

\lecture{An Astonishing Result}{euclid}

\begin{frame}{Euclid's Astonishing Result} \end{frame}

\lecture{A Boring Result}{pythagoras}

\begin{frame}{Pythagoras' Boring Result} \end{frame}

\end{document}

The intention being that:

pdflatex -jobname euclide lectures.tex

and

pdflatex -jobname pythagoras lectures.tex

produce different lectures.

David Carlisle
  • 757,742
Andrew Stacey
  • 153,724
  • 43
  • 389
  • 751
  • related: http://tex.stackexchange.com/questions/6828/jobname-character-codes-and-detokenize – cgnieder Jun 06 '13 at 10:10
  • Are we allowed to use e-TeX? What do we do about non-letter characters? – Joseph Wright Jun 06 '13 at 10:11
  • 3
    e-TeX's \scantokens could be used or each character could be replaced by its letter counterpart. But the trouble with special characters (underscore, @, ...) remains. It is much more efficient and robuster to convert the other string to catcode 12 characters before the comparison. – Heiko Oberdiek Jun 06 '13 at 10:15
  • Joseph: Yes, e-TeX is allowed. As for non-letter characters, let's assume that I'm in a very controlled environment with regards to what I'm testing and can guarantee that \jobname (or an extracted part of it) consists only of letters. Heiko: Granted, but consider this more of a "If I really have to do this, what do I do?". – Andrew Stacey Jun 06 '13 at 10:21
  • Could you show a situation where you might want this? – egreg Jun 06 '13 at 12:26
  • 1
    @AndrewStacey Probably you should ask the maintainer of beamer to allow for string-based comparisons here :-) – Joseph Wright Jun 06 '13 at 15:10
  • @JosephWright Perhaps I ought to add the context that this came up because someone wanted to use the idea of my method of selecting a lecture using the filename but didn't want to use the complicated method that I actually use (described at http://tex.stackexchange.com/a/2569/86) so was trying to just use \jobname as the lecture name. However, as I see now, that is similarly fraught with difficulties! – Andrew Stacey Jun 06 '13 at 15:14
  • @AndrewStacey I've added how you can do for that problem. Of course a string (expanded) based comparison would be better, but that's for beamer's maintainers. – egreg Jun 06 '13 at 15:34
  • I think this is a XY problem. IMHO, changing jobname for conditional typesetting is just wrong. Doesn't any of the LaTeX wrapper provide something similar to ConTeXt's ability of setting modes from command line? – Aditya Jun 06 '13 at 17:59

3 Answers3

15

I don't understand very well the question; category code 12 is used exactly for avoiding problems with category codes and special characters.

With \scantokens you can do it: save the following code as ncjob.tex and run it.

\documentclass{article}

\begingroup
  \everyeof{\noexpand}
  \endlinechar=-1
  \xdef\normaljobname{\scantokens\expandafter{\jobname}}
\endgroup

\def\test{ncjob}

\ifx\test\normaljobname\typeout{SUCCESS}\else\typeout{FAILURE}\fi

\stop

SUCCESS

Important note This requires that the jobname contains only “safe characters”; something like ~ in the file name would make this die horribly.


A possibly safer way is to use expl3:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV }
\NewDocumentCommand{\definenormaljobname}{O{\normaljobname}}
 {
  \tl_set_rescan:NnV #1 { } \c_job_name_tl
 }
\ExplSyntaxOff
\definenormaljobname
\def\test{nc~job}\show\normaljobname

\ifx\test\normaljobname\typeout{SUCCESS}\else\typeout{FAILURE}\fi

\stop

Tested with the command line

pdflatex -jobname 'nc~job' ncjob

This is how your example could be managed; don't use special characters or spaces in the jobname passed from the command line (nor in the lecture labels, of course).

\documentclass{beamer}

\usepackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV }
\NewDocumentCommand{\includelecturefromjobname}{}
 {
  \tl_set_rescan:NnV \l_tmpa_tl { } \c_job_name_tl
  \exp_args:NV \includeonlylecture \l_tmpa_tl
 }
\ExplSyntaxOff

\includelecturefromjobname


\begin{document}

\lecture{An Astonishing Result}{euclid}

\begin{frame}{Euclid's Astonishing Result}
\end{frame}

\lecture{A Boring Result}{pythagoras}

\begin{frame}{Pythagoras' Boring Result}
\end{frame}

Note

As of September 2015, instead of \c_job_name_tl one should use

\c_sys_jobname_str
egreg
  • 1,121,712
5

This allows the filename to have special characters, and still do the comparison (in this case, everything is converted to catcode 12 for the comparison)

\documentclass{article}
\usepackage{ifthen}
\def\display#1{\detokenize\expandafter{#1}}
\def\comparenames#1{%
  \ifthenelse{\equal{\display{#1}}{\display{\comparetest}}}{T}{F}}
\begin{document}
\def\comparetest{myfile}

\def\jbnm{myfile}
\comparenames{\jbnm}

\def\jbnm{\$&o)-}
\comparenames{\jbnm}

\end{document}
2

Save this file as cxviiviiicxcii.tex:

\documentclass{article}

% Save this file as cxviiviiicxcii.tex

\begin{document}


\def\alltoletter {%
    \count 255 0
    \loop
    \catcode\count255 11
    \ifnum\count 255 < 255 \advance \count 255 1 \repeat }

\def\convert #1\to #2{%
        \begingroup
          \everyeof{\noexpand}%
          \endlinechar -1
          \alltoletter
          \edef\x{\scantokens\expandafter{#1}}%
% earlier silly stuff (sorry):  \expandafter\expandafter\expandafter\endgroup
        \expandafter\endgroup
        \expandafter\def\expandafter #2\expandafter{\x}%
    }%


\def\myname {cxviiviiicxcii}%

\convert\jobname\to\jobnameconverted

converted: \ifx\myname\jobnameconverted EQUAL\else UNEQUAL\fi

unconverted: \ifx\myname\jobname EQUAL\else UNEQUAL\fi

\begingroup
\escapechar -1
\xdef\testtwoA {\string\abcdef}
\endgroup

\convert\testtwoA\to\testtwoAconverted

\def\testtwoB {abcdef}

converted: \ifx\testtwoB\testtwoAconverted EQUAL\else UNEQUAL\fi

unconverted: \ifx\testtwoB\testtwoA EQUAL\else UNEQUAL\fi
\end{document}

picture

  • A comment: if the macro whose contents are to be converted to catcode 11 contains a control sequence, say \abc then it seems that \scantokens will transform it into \abc where the first four have catcode 11, and the space is also of catcode 11; except if this \abc is the last thing just before the closing brace in the initial definition of the to-be-converted macro (contents), then no space. So the \alltoletter should possibly end in \catcode32 10, in order for the spaces produced by \scantokens to be standard, thus easing up use of the \convert thing. –  Jun 06 '13 at 17:42