如果我将 LaTeX 文件命名为hw1
,我想打印Homework 1
。我该怎么做?
hw1
我可以使用直接打印字符串\jobname
,但我不希望文件名中有空格,或者每次创建新文件时都必须输入空格。
答案1
让我们更一般化一点。我假设你有以下文件
<string><number>.tex
其中<string>
是任意字母字符,<number>
由数字组成。例如,
hw01.tex ... hw10.tex
对于家庭作业或
lect01.tex ... lect21.tex
用于讲座。文件的结构hw
可能是
\input{hw-common}
\begin{document}
\title{Homework \NUMBER}
\author{Georg Raba}
\date{}
\maketitle
Solve the following exercises
...
\end{document}
其中hw-common.tex
将包含\documentclass
行和作业文件的其他常用设置。的任务之一hw-common
应该是\NUMBER
根据文件名进行定义。但是您想重用代码,使其独立于<string>
文件名中的实际内容,因此您可以将相同的代码用于lect-common.tex
。
我们该怎么办?l3regex
像往常一样,LaTeX3 软件包中的软件包可以解决问题。
你hw-common.tex
将拥有
\usepackage{expl3,l3regex}
\ExplSyntaxOn
% Save a copy of \jobname
\tl_set_eq:NN \NUMBER \c_job_name_tl
\regex_replace_once:nnN { [A-Za-z0]* } { } \NUMBER
\ExplSyntaxOff
这样,如果文件为hw01.tex
,\NUMBER
将打印 1,删除前导零。正则表达式匹配所有开头的字母字符和零,并将其替换为空。
笔记
自 2015 年 9 月起,该规范应变为
\usepackage{expl3,l3regex}
\ExplSyntaxOn
% Save a copy of \jobname
\tl_set:NV \NUMBER \c_sys_jobname_str
\regex_replace_once:nnN { [A-Za-z0]* } { } \NUMBER
\ExplSyntaxOff
答案2
\jobname
就像\string
:它扩展为一系列类别代码 12字符,即使所讨论的字符通常不具有 catcode 12(空格除外,空格仍为 catcode 10)。您可以使用分隔参数提取序列的一部分并对其进行处理;最简单的“处理”是将它们保存在宏中。例如,假设您知道您的\jobname
格式始终是XXXXwYYYY
YYYY 是您想要的部分,您可以这样做:
\begingroup
\catcode`\w=12
\def\extracthnum#1w#2\relax{#2}%
\xdef\hnum{\expandafter\extracthnum\jobname\relax}%
\endgroup
%
% ...
%
\title{Homework \hnum}
这或许值得我们稍微解开一下。
\begingroup\catcode`\w=12
开始一个组(您几乎总是希望将类别代码更改包装在一个组中)并将类别代码更改为w
12,以便它w
与 的扩展中的相匹配\jobname
。请注意,这意味着我们不能w
在宏名称中使用,直到我们将其恢复为正常的类别代码。(如果您真的需要,有办法解决这个问题,但我们不讨论这个。)
\def\extracthnum#1w#2\relax{#2}%
定义\extracthnum
为采用两个宏分隔参数。与普通宏不同,这个宏的第一个参数将是所有输入字符,直到但不包括第一个 catcode-12 w
(不在括号组内),第二个参数将是所有字符后w
直到第一次出现。\relax
(我们使用控制序列来界定第二个参数,因为它不可能出现在的扩展中\jobname
。它将被使用和丢弃;我使用是\relax
因为这是传统的,但它可以是任何控制序列。它甚至不需要有定义。)它扩展为它的第二个参数。
\xdef\hnum{\expandafter\extracthnum\jobname\relax}%
此行的处理顺序不寻常,因为 和\xdef
.\expandafter
被 \jobname
扩展了第一的,然后\extracthnum ... \relax
对扩展为的内容进行操作\jobname
,然后宏定义才会发生。由于假设\jobname
具有形式XXXXwYYYY
,因此\hnum
将被定义为YYYY
。的另一个特殊效果\xdef
是使定义全球,也就是说,它将在\endgroup
接下来的内容中生存下来。
答案3
您可以\def
在命令行上使用来指定该值,并在代码中使用该值。
pdflatex "\def\Title{Homework 1}\input{hw1}"
如果命令行中未指定,则文件将用于指定。现在您可以在hw1
文档\providecommand
中的任何位置使用:\Title
\Title
%\def\Title{Homework 1} -- This is defined on the command line
\documentclass{article}
\providecommand*{\Title}{\jobname}
\begin{document}
Title is \Title
\end{document}