标准类具有分段命令,其第一个参数可选,可以包含用于目录和运行头的 alt 标题。如果需要使用 keyval 接口而不更改用户 API,则可以在其后传递键。下面的代码尝试检测第一个参数是否带有短标题和/或键。我的问题是,如何改进它以及任何其他建议。我通过符号的存在来检测键的存在=
。如果键的形式为 pgfkeys 中的样式或普通键中的 |10pt|,则此方法会失败。我可以要求用户用诸如但不想这样的信号标记短标题的结尾,>>
这样就可以处理旧文档而无需进行更改。另一种方法是添加一个虚拟键,以便用户输入始终在左侧。还有其他想法吗?
\documentclass{book}
% Needed if using g-specifier
\usepackage{xparse}
% use pgfkeys for key-val lists
\usepackage{pgfkeys,xcolor}
% create set-keys macro with family /phd
\newcommand\cxset{\pgfqkeys{/phd/.is family}}
% define some keys
\cxset{keya/.store in=\AAA,
keyb/.store in = \BBB,
keyc/.store in = \CCC}
% give some values to the keys
\cxset{keya = AAA,
keyb = BBB,
keyc = CCC}
% set a style so we can append to and modify later on
\cxset{defaults/.style ={keya = AAA,
keyb = BBB,
keyc = CCC }
}
\usepackage{hyperref}
\begin{document}
\tableofcontents
\ExplSyntaxOn
\tl_new:N \short_title_tl
\tl_new:N \long_title_tl
\tl_new:N \saved_keys_tl
\tl_new:N \short_or_long_title_tl
% initialize to error
\tl_set:Nn\short_or_long_title_tl{\ERROR}
%
\NewDocumentCommand\altorkeys{ s o +m }
{
\IfValueTF{#2}
{ % need 2 lists one for tail another
% one for original input
\tl_set:Nn\l_tmpa_clist{#2}
\clist_gpop:NN\l_tmpa_clist\l_tmpa_tl
% save unpopped
\tl_set:Nn\l_tmpb_clist{#2}
% check first item for = as a signal we have keys
% alt signal count items might fail?
\tl_if_in:NnTF\l_tmpa_tl{=}
{
%\clist_push:NV \l_tmpa_clist\l_tmpa_tl
\clist_map_inline:Nn \l_tmpb_clist {\appendstyle{##1}}
\tl_set:Nn\short_or_long_title_tl{#3}
\tl_set_eq:NN \saved_keys_tl\l_tmpb_clist
}
{ %case we have short title
\clist_map_inline:Nn \l_tmpa_clist {\appendstyle{##1}}
\tl_set_eq:NN \short_title_tl\l_tmpa_tl
\tl_set_eq:NN\short_or_long_title_tl\l_tmpa_tl
}
% At this point we can end wit an empty clist as we popped
% the first item and it only had one item
\clist_if_empty:NT\l_tmpa_clist
{
\clist_push:NV \l_tmpa_clist\l_tmpa_tl
\tl_set_eq:NN\short_or_long_title_tl\l_tmpa_tl
}
}
% case empty options
{
\tl_set:Nn\short_or_long_title_tl{#3}
}
% case star
\IfBooleanT#1
{
\tl_set:Nn \short_or_long_title_tl{#3}
}
% print title
%\section[\short_or_long_title_tl]{#3}
}
\def\appendstyle#1{
\cxset{defaults}
\cxset{ defaults/.append~style={#1}}
\cxset{ defaults}
}
\NewDocumentCommand\mocktest{ }
{
\altorkeys[short mock]{Long mock title}
\section[\short_or_long_title_tl]{\short_or_long_title_tl}
\altorkeys[short mock, keya=a,keyb=b, keyc=c]{Long mock title with short and keys}
\section[\short_or_long_title_tl]{\short_or_long_title_tl}
\altorkeys[keya=a,keyb=b]{Long mock title with keys}
\section[\short_or_long_title_tl]{\short_or_long_title_tl}
\altorkeys{Long mock title,nostar, nooptions, noshort }
\section{\short_or_long_title_tl}
\altorkeys*[short*]{Long mock title,star, nooptions, short *}
\section*{\short_or_long_title_tl}
This~should~not~be~in~the~contents\par
========Keys Test ==================\par
Keys must~show a,b,c\par
\AAA\par
\BBB\par
\CCC
}
\ExplSyntaxOff
\mocktest
\section*[short]{Vanilla LaTeX section star with empty options}
\section{}
This is a section in Vanilla LaTeX with empty title
\end{document}