如何检查 LaTeX 文档的文件名是否包含字符串?

如何检查 LaTeX 文档的文件名是否包含字符串?

我正在为学生准备一份 LaTeX 投影仪演示文稿。我正在寻找一种简单的方法来创建两个版本的演示文稿。

一个版本是给学生的,其中只包含他们家庭作业的任务文本;另一个版本是给我的,其中还包含解决方案。

因此我创建了一个宏,用于检查文件名是否包含“student”。如果包含,则宏不输出任何内容,如果不包含,则传递参数:

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

但这并没有按预期工作。无论我如何命名文件,条件总是转到 false 表达式。我认为宏\jobname返回了一些无法处理的内容\IfSubStringInString,但我不知道该如何处理这个问题。

如果我\jobname用固定字符串替换条件中的宏,它会按预期工作,但这会使其变得毫无用处。

我过去常常\jobname避免包含 currfile-package,但使用 currfile-macros 时,我得到了相同的行为。我在 Linux 和 Windows 上使用 texlive 2014 pdflatex。

这里有谁对此有提示吗?

这是一个最小的完整示例:

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

答案1

中的字符\jobname有类别代码 12,这违反了substr使用\ifx基于比较的 。您可以简单地将 字符串化student,因为substr命令会完全展开其参数:

\documentclass[ngerman]{beamer}

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

如果文件名不包含以下内容,我将获得以下结果student

在此处输入图片描述

如果文件名包含以下内容,我将获得以下结果student

在此处输入图片描述


一个经典的解决方案(没有\detokenize):

\documentclass[ngerman]{beamer}

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

使用正则表达式的解决方案(具有广泛的通用性):

\documentclass[ngerman]{beamer}

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

\ExplSyntaxOn
\NewDocumentCommand{\hausaufgabenLoesung}{m}
 {
  \regex_match:nVF {student} \c_sys_jobname_str {#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}

答案2

根据 Ulrike Fischer 的评论,\jobname其中包含“错误”的 catcode 字符,使用某些 hack 无法进行直接比较。一种解决方法是将作业名称写入虚拟文件,然后立即将其读回某个\def\....宏,例如\RealJobName。这可以用作测试的一个字符串占位符。

环境\AtBeginDocument{}钩子会自动执行此操作并“返回”作业名称\RealJobName以供日后使用。

两种方法均substr有效xstring

学生姓名.tex

\documentclass[ngerman]{beamer}

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

\usepackage{ifthen}
\usepackage{substr}
\usepackage{xstring}%

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


\newcommand{\hausaufgabenLoesungXString}[1]{%
\IfSubStr{\RealJobName}{student}{}{#1}%
}


\gdef\RealJobName{}%

\newwrite\mywrite%
\newread\myread%
\AtBeginDocument{%
\immediate\openout\mywrite\jobname.dum%
\immediate\write\mywrite{\jobname}%
\immediate\closeout\mywrite%
\immediate\openin\myread=\jobname.dum%
\read\myread to \RealJobName%
\immediate\closein\myread%
}%

\begin{document}




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

\end{document}

相关内容