我正在尝试获取自己的通用标题命令,我可以使用它来将 pdf 文件作为标题页包含进去,该文件是否存在,或者使用 xkeyval 包包含按键细分的文本。
我的问题是能够透明地使用\title[my_pdf_file.pdf]
或\title[maintitle=My main title, subtitle=My subtitle]
。
我现在在类文件中的代码是这样的:
\AtBeginDocument{%
% Use bullets in lists instead of large dashes. Must be inside the document scope to work.
\renewcommand{\labelitemi}{\textbullet}
% Redefine the title commmand
% makeatletter and makeatother are unneeded in class files.
%\makeatletter
% Restrict the commands to the internals of this class file.
\def\@maintitle{}
\def\@subtitle{}
\def\@author{}
\define@key{title}{maintitle}{%
\def\@maintitle{%
\hrule%
\vspace{0.4cm}
% We always need to define \par in scope for a font size change, otherwise, if the title is ever longer than a line, it will wrap to the next line with huge characters on a normal baseline.
{\Huge\textbf{#1}\par}%
\vspace{0.4cm}%
\hrule
}%
}
\define@key{title}{subtitle}{%
\def\@subtitle{%
\vspace{1.5cm}
{\Large{#1}\par}%
}%
}
\define@key{title}{author}{%
\def\@author{%
{\emph{Author: #1}\par}%
}%
}
% The outer bracket is the renewcommand syntax, the inner one is a group definition avoiding \@author to leak out and be the default in later uses.
\renewcommand{\title}[1][]{{%
\IfFileExists{./#1}{%
\includepdf[pages={1}]{#1}%
}%
{%
\setkeys{title}{#1}
\key@ifundefined{#1}{\PackageError{'#1' is not a valid key}}
\begin{titlepage}
\begin{center}
\renewcommand{\hrule}{\rule{\linewidth}{1mm}}
\@maintitle
\@subtitle
\vfill%
\@author
\end{center}
\end{titlepage}%
}
}}
}
我遇到的问题是:
- 当使用 \title[my_pdf_file.pdf] 时,下划线会被解释,但我不想手动对其进行转义。
- 当使用以文本形式编写的标准手册标题时
\title[maintitle=Some long\\main title]
,似乎\IfFileExists
被解释并且标题被写了两次:一次在一页上未格式化,另一次在下一页,但那一次的格式正确(大写字母,居中,文本上方和下方都有线条) - 如果我指定的值不是有效的可读文件,并且该值也不是有效的键(也不是主标题、副标题或作者),则会出现错误。我无法工作
\key@ifundefined{#1}{\PackageError{'#1' is not a valid key}}
。
答案1
您的问题很难回答,但我找到了一种不同的方法,这种方法有效,而且可能符合您的兴趣。但首先,您的问题是:
- 我不知道如何使用您的方法正确处理文件名中的下划线。一般建议是避免使用它们(但我建议的方法允许使用它们)
- 我不知道为什么会发生这种情况,不知何故其内部
\IfFileExists
原因导致其参数的扩展(我认为这是因为maintitle
未找到使用 etc 关键字时指定的“文件”,然后再次解析该文件名以查看它是否包含子文件夹)。 - 宏
\key@undefined
不是包的一部分keyval
。但你不需要它。的标准行为keyval
已经提供了此功能(即:当指定之前未声明的键时产生编译错误)
诚然,我之前的回答没什么用。所以让我们尝试不同的方法。
为什么不提供外部 pdf 的文件名作为另一个关键字,而是“直接”提供它?我建议的解决方案是:
\title[maintitle=My main title, subtitle=My subtitle]
或者
\title[externalpdf=wonderful_title.pdf]
甚至,你可以将两者结合起来,这样如果外部 pdf 存在,则使用它,如果不存在,则使用其他关键字:
\title[externalpdf=wonderful_title.pdf, maintitle=My main title, subtitle=My subtitle]
使用这种方法,您会意外地获得在文件名中使用下划线的功能。
这是实现方式:
\documentclass[11pt, oneside]{report}
\usepackage{pdfpages}
\usepackage{keyval}
\makeatletter
\AtBeginDocument{%
% Use bullets in lists instead of large dashes. Must be inside the document scope to work.
\renewcommand{\labelitemi}{\textbullet}
% Redefine the title commmand
% makeatletter and makeatother are unneeded in class files.
%\makeatletter
% Restrict the commands to the internals of this class file.
\def\@maintitle{}
\def\@subtitle{}
\def\@author{}
\def\@filename{}
\define@key{title}{maintitle}{%
\def\@maintitle{%
\hrule%
\vspace{0.4cm}
% We always need to define \par in scope for a font size change, otherwise, if the title is ever longer than a line, it will wrap to the next line with huge characters on a normal baseline.
{\Huge\textbf{#1}\par}%
\vspace{0.4cm}%
\hrule
}%
}
\define@key{title}{subtitle}{%
\def\@subtitle{%
\vspace{1.5cm}
{\Large{#1}\par}%
}%
}
\define@key{title}{author}{%
\def\@author{%
{\emph{Author: #1}\par}%
}%
}
\define@key{title}{externalfile}{%
\def\@filename{#1}%
}
\renewcommand{\title}[1][]{{%
\setkeys{title}{#1}
\IfFileExists{\@filename}{%
\includepdf[pages={1}]{\@filename}%
}%
{%
\begin{titlepage}
\begin{center}
\renewcommand{\hrule}{\rule{\linewidth}{1mm}}
\@maintitle
\@subtitle
\vfill%
\@author
\end{center}
\end{titlepage}%
}
}}
}
\makeatother
\begin{document}
\title[externalfile=wonderful_title.pdf, maintitle=My main title, subtitle=My subtitle]
\chapter{Testing...}
\end{document}