修改分段命令的可选参数以传递键值列表

修改分段命令的可选参数以传递键值列表

标准类具有分段命令,其第一个参数可选,可以包含用于目录和运行头的 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}

相关内容