[Tex/LaTex] How to check if the filename of a LaTeX document contains a string

conditionalsjobname

I am preparing a LaTeX beamer presentation for students. I am looking for a simple way to create two versions of my presentation.

One version for the Students, which just contains the text of the tasks they get for homework and an other one for me which also contains the solution.

So I have created a macro that is intended to check if the file name contains "student".
If it does, the macro outputs nothing, and if it does not, the argument is passed:

\newcommand{\hausaufgabenLoesung}[1]{%
    \IfSubStringInString{student}{\jobname}{}{#1}%
}

But this does not work as intended.
No matter how I name the file, the conditional always goes to the false-expression.
I think the \jobname macro returns something which can not be processed by \IfSubStringInString but I have no other idea how I could approach this.

If I replace the \jobname macro in the conditional with a fixed string, it works as intended but this would render it fairly useless.

I used \jobname to avoid including the currfile-package, but with the currfile-macros I get the same behaviour. I am using texlive 2014 pdflatex on Linux and Windows.

Anyone here got a hint for that?

Here is a minimal complete example:

\documentclass[ngerman]{beamer}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}

\usepackage{ifthen}
\usepackage{substr}

\newcommand{\hausaufgabenLoesung}[1]{%
    \IfSubStringInString{student}{\jobname}{}{#1}%
}

\begin{document}

\begin{frame}{Title}{Subtitle}
    \begin{itemize}
        \item \jobname
        \item Visible in both files
        \hausaufgabenLoesung{\item Solution not in the student file}
    \end{itemize}
\end{frame}

\end{document}

Best Answer

The characters in \jobname have category code 12 and this defies substr, which uses an \ifx based comparison. You can simply stringify student, using the fact that substr commands fully expand their arguments:

\documentclass[ngerman]{beamer}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}

\usepackage{substr}

\newcommand{\hausaufgabenLoesung}[1]{%
    \IfSubStringInString{\detokenize{student}}{\jobname}{}{#1}%
}

\begin{document}

\begin{frame}{Title}{Subtitle}
    \begin{itemize}
        \item \jobname
        \item Visible in both files
        \hausaufgabenLoesung{\item Solution not in the student file}
    \end{itemize}
\end{frame}

\end{document}

This is what I get if the file name doesn't contain student:

enter image description here

This is what I get if the file name contains student:

enter image description here


A classical solution (without \detokenize):

\documentclass[ngerman]{beamer}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}

\usepackage{substr}

\begingroup\escapechar=-1
\xdef\studentstring{\string\student}
\endgroup

\newcommand{\hausaufgabenLoesung}[1]{%
    \IfSubStringInString{\studentstring}}{\jobname}{}{#1}%
}

\begin{document}

\begin{frame}{Title}{Subtitle}
    \begin{itemize}
        \item \jobname
        \item Visible in both files
        \hausaufgabenLoesung{\item Solution not in the student file}
    \end{itemize}
\end{frame}

\end{document}

A solution with regular expressions (vastly generalizable):

\documentclass[ngerman]{beamer}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}

\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\hausaufgabenLoesung}{m}
 {
  \regex_match:nVF {student} \c_job_name_tl {#1}
 }
\cs_generate_variant:Nn \regex_match:nnF { nV }
\ExplSyntaxOff

\begin{document}

\begin{frame}{Title}{Subtitle}
    \begin{itemize}
        \item \jobname
        \item Visible in both files
        \hausaufgabenLoesung{\item Solution not in the student file}
    \end{itemize}
\end{frame}

\end{document}
Related Question