Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Many classes provide \part, \chapter, \section and even more deeply nested sectioning levels.

All of them allow three forms of usage (I restrict for sake of simplicity to \section, it just stands short for any of the section level commands):

  • \section{fooooooo} -> The short section title will be fooooooo too.
  • \section[foo]{fooooooo} -> The short section title will be just foo, and the section title will be fooooooo.
  • \section*{foo} -> No toc entry and no increase of section counter.

I have encountered (not only as a consequence of questions at TeX.SX) following problem that it is sometimes necessary to redefine the behaviour of section, adding some start code to be executed just before the section title is printed on the page and some code directly afterwards, or do some configuration otherwise, affecting future code.

Some of these tasks can be just done with hooks as provided by the etoolbox package or really rewrite at least the top code level of section via \@ifstar and \@ifnextchar[ etc.

I want to use another approach, by adding key values in the first optional argument to section without changing the complete syntax of \section, say (assuming some keys are already defined...)

\section[foo,AnyKey={AnyKeyValue},AnotherKey=true]{foooooo}

This means a mixing of a non key part of the 1st argument and (lots of) key parts of the same argument.

This means, that the traditional short toc entry is grabbed as first part the rest is treated by the key value package commands, say xkeyval.

However, at least in the case of xkeyval, saying \setkeys{FamilyA}{#1} will fail, since it will find a 'key' named 'foo' which is not defined and stop with an error message.

Is a peaceful coexistence of key value and non key parts within an argument (regardless optional or not) possible?

Here is a non working example, where I use a dummy command instead of redefining \section.

\documentclass[paper=a4,12pt]{scrartcl}

\usepackage{etoolbox}
\usepackage{xkeyval}
\usepackage{xstring}% Possibly needed




\makeatletter
\define@key{FamilyA}{AnyKey}{%
\typeout{Yes!!!}
\def\AnyKeyMacro{#1}%
}%

\define@key{FamilyA}{FirstArgKey}[]{%
\def\FirstArgKeyMacro{#1}%
}%

\define@boolkey{FamilyA}{AnotherKey}[false]{%
%% not completely setup so far
}%

\makeatother



\newrobustcmd{\SomeCommand}[2][]{%
% Grabbing the non-key-argument and process it, then fill
% setkeys with the rest of it. 

%  \setkeys{FamilyA}{#1}% Fails, since xkeyval complains about a possible non-key argument part of #1
%%%%
% Rest of code, with usage of key macros etc. and #2...

}% 

\begin{document}

\SomeCommand[foo,AnyKey={This Is A Key Value},AnotherKey=true]{Another sophisticated argument}%

\end{document}

Some notes:

  • If there is no key value given, the redefined \section command should work as the not redefined version, apart from portions of code, which were added and do not need configuration via keys.
  • A redefinition of \section syntax itself is not an option, since this would break basically any package/document
  • A small solution could be \section[ShortSectionTitle=foo,AnyKey={...}]{foooopoo}, but this falls into the category of changing the syntax as well. Perhaps it is possible to catch those cases
  • The special role of , character in a key value environment should nevertheless allow to make short section titles containing , characters, as in \section[{This is a short, but effective title},AnyKey={...}]
share|improve this question
    
How would you handle the optional list of items when you don't want to supply a ToC-title? In those cases, you will always supply \section[,AnyKey={..},...]{foooooo}? I assume so since you mention that you will be mixing the two types of key/no-key-value components, of which the 1st is always the non-key-value component. I think in general it would be better (and also easier) to provide elements in a consistent way, similar to your suggestion using \section[toc={foo},AnyKey={..},...]{foooooo}. Why? This would allow you to change the order of the key-values as well. –  Werner May 28 at 5:43
    
@Werner: You are right, I am aware, that I still have to handle the case [,AnyKey={...}] in the sense that the value of the 2nd argument is used as toc entry. I agree with you also, that restricting the non key part has to be specified first is 'annoying'. The arbitrary order of toc={foo},AnyKey={} is seductive, of course, I considered it already, but how can I 'people' to use that syntax ;-) I also had the idea of something like many commands from xstring provide: \command[option]{mandatory}[another option] where the 1st. optional argument is not needed for the 2nd opt. arg. –  Christian Hupfer May 28 at 6:02
    
@ChristianHupfer The KOMA classes mentioned by Ulrike have some heuristics (based on the presence of = at the top level of the optional argument) for deciding whether the old (with just the short title) or new (with key-value pairs) syntax is used. As a general rule, key evaluation should be independent of the specification order; having the first part as a special optional argument won't help clarity. –  egreg May 28 at 9:56
    
@egreg, @Ulrike: Thanks to you both, for the comments on KOMA classes, I did not knew about that feature. I struggled with that 1st non key part too, but also with the syntax change from traditional behaviour ([shorttitle]) style to key values. –  Christian Hupfer May 28 at 11:08
    
If you use pgfkeys instead of xkeyval, it is possible to specify behavior for "unknown" keys. For instance, in this question, I show how to set up a key handler that passes unknown keys to an \includegraphics command. –  Charles Staats May 29 at 16:35

2 Answers 2

up vote 3 down vote accepted

The following provides a mixture of starred and optional argument for \section with the requirement to use toc=<ToC entry> for sections' ToC-level entry.

enter image description here

\documentclass{article}
\usepackage[margin=1in]{geometry}% Just for this example
\usepackage{xkeyval,xparse}

\let\oldsection\section

\makeatletter
\define@cmdkey{section}[section@]{toc}[\relax]{}
\define@cmdkey{section}[section@]{AnyKey}[\relax]{}
\define@cmdkey{section}[section@]{AnotherKey}[\relax]{}

\RenewDocumentCommand{\section}{s o m}{%
  \setkeys{section}{toc,AnyKey,AnotherKey}% Set default keys
  \IfNoValueF{#2}{\setkeys{section}{#2}}% Set user-supplied keys
  \IfBooleanTF{#1}{% \section*
    \oldsection*{#3}%
    \expandafter\ifx\section@toc\relax\else\addcontentsline{toc}{section}{\protect\numberline{}\section@toc}\fi%
  }{% \section
    \expandafter\ifx\section@toc\relax
      \oldsection{#3}%
    \else
      \oldsection[\section@toc]{#3}%
    \fi    
  }%
  \expandafter\ifx\section@toc\relax\else \noindent toc: \section@toc \par\fi%
  \expandafter\ifx\section@AnyKey\relax\else \noindent AnyKey: \section@AnyKey \par\fi%
  \expandafter\ifx\section@AnotherKey\relax\else \noindent AnotherKey: \section@AnotherKey \par\fi%
}
\makeatother

\begin{document}

{\let\section\oldsection% Just for this example
\tableofcontents
}

\section[
  AnyKey     = {This Is A Key Value},
  toc        = {foo},
  AnotherKey = {true}]
  {A title}

\section*[
  AnyKey     = {Something}]
  {Another title}

\section*[
  toc        = {bar},
  AnotherKey = {Something else}]
  {A title again}

\section{Short}

\section*{Title}

\section[
  AnyKey     = {foobar},
  AnotherKey = {barfoo}]
  {Final title}

\end{document}

As mentioned in comments, the advantage of providing the ToC-entry using a key-value approach allows you to change the order of specification, if needed. However, if need be, the definition of the new \section could be updated to use an interface like (say)

\section*[<options>]{<title>}[<toc title>]
share|improve this answer
    
This looks good! Please object me, if I ask: Could \section* not anyway redefined with an optional arg and using key value syntax (with toc=..., as you suggested?) without xparse? I never tried to provide a starred command with an optional arg, but I think it should be possible anyway. –  Christian Hupfer May 28 at 6:52
    
@ChristianHupfer: So you want an interface \section*{...} and \section[..]{...} (without xparse) since you never use \section*[..]{...}? –  Werner May 30 at 20:29
    
No, I will drop that request. I already wrote code for something like \section*[...]{...} now and switched to key=value interface. I accepted your answer for its elaborate usage of code, although Ulrike's statement was fine as well. Unfortunately I cannot share accepting ;-) –  Christian Hupfer May 30 at 20:33

Not really an answer but too long for a comment. The KOMA-class already have a syntax for keys in the option argument of sectioning commands. It is activated with one of headings=optiontoXXX. You can extend the keys (but you naturally will have to add keys for toc and head then too, to avoid side effects):

\documentclass[headings=optiontoheadandtoc]{scrartcl}

\makeatletter
\define@key{KOMAarg.section}{prefix}{\noindent\llap{\sectfont\size@section#1}}
\makeatother
\begin{document}
\tableofcontents

\section[tocentry=blub,head=blabla,prefix=*]{abc}

\end{document}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.