0

I want to create a macro \verticalStep which will produce a vertical skip of fixed length, and take two optional arguments, negative and small.

So for you could use

  • \verticalStep for a standard vertical skip
  • \VerticalStep[negative] for reducing vertical skip by standard length
  • \verticalStep[small] for a small fixed vertical skip
  • \VerticalStep[negative, small] for reducing vertical skip by small standard length

I have been looking into xkeyval and pgfkeys and could not for the life of me find a simple or straightforward example of how I may go about parsing the argument and checking for the options. I managed to find this, but the only answer uses expl3 and I wonder if there is a more elegant solution that does not require switching syntax

3

2 Answers 2

2

Here is a solution using pgfkeys. The .is if handler allows one to easily connect PGF keys to \iffoobar TeX boolean switches.

\documentclass{article}
\usepackage{pgfkeys}

\makeatletter
\newif\ifmy@verticalStep@small           % initially false
\newif\ifmy@verticalStep@negative        % initially false

\pgfkeys{
  /my@verticalStep/options/.cd,
  small/.is if=my@verticalStep@small,
  negative/.is if=my@verticalStep@negative,
}

\NewDocumentCommand \verticalStep { O{} }
  {%
    \begingroup
    \pgfkeys{/my@verticalStep/options/.cd, #1}%
    %
    \par                        % my choice
    \vspace{%
      \ifmy@verticalStep@negative -\fi
      \ifmy@verticalStep@small \smallskipamount \else \bigskipamount \fi
    }%
    \endgroup
  }
\makeatother

\setlength{\parindent}{0pt}

\begin{document}

Normal:\verticalStep
Small:\verticalStep[small]

Negative:\verticalStep[negative]
% The negative skip we just did rewound exactly one line here, because
% \baselineskip and \bigskipamount have the same natural “width” (12pt), and
% the natural width of \parskip is 0pt. That's why I do this \hspace*{4.5em},
% otherwise “Negative” would be overprinted.
\hspace*{4.5em}Negative and small:\verticalStep[negative, small]
The end.

\end{document}

enter image description here

1

Simple macros like these can be created with expkv-cs quite comfortably.

The \ekvcSplit macro sets up a command that takes one mandatory argument (hence we use a \NewDocumentCommand-defined wrapper for the optional argument), and splits it into separate arguments in the order of the defined primary keys, so that you can use #1 for the first key in the definition. Additional keys that don't correspond to arguments directly can be set up using \ekvcSecondaryKeys (which we can use to set up your flag-like keys, which will then just forward specific values to your underlying keys).

\documentclass{article}
\usepackage{expkv-cs}

\makeatletter
% grabbing argument as an optional argument
\NewDocumentCommand\VerticalStep{O{}}{\VerticalStep@{#1}}
\ekvcSplit\VerticalStep@
  {
     length = 0pt % value doesn't matter, will be set by ekvcChange
    ,sign = {} % empty for positive, else -
    ,star = {}
  }{\vspace#3{#2#1}}
\ekvcSecondaryKeys\VerticalStep@
  {
     nmeta negative = {sign=-}
    ,nmeta small = {length=1cm}
    ,nmeta standard = {length=2cm}
    ,nmeta force = {star=*}
  }
\ekvcChange\VerticalStep@{standard}
\makeatother

\begin{document}
abc
\VerticalStep

def
\VerticalStep[negative]

ghi
\VerticalStep[small,negative]

jkl
\VerticalStep[length=5cm]% arbitrary sizes also possible

mno
\end{document}

Another solution using a more traditional key=value interface as provided by expkv-def. This uses a skip-register to store the length, the standard and small keys change the length in that register, and the negative-key works as a Boolean (so can be set true or false).

\documentclass{article}

\usepackage{expkv-def}
\makeatletter
\ekvdefinekeys{VerticalStep}
  {
     skip    length   = \VerticalStep@length
    ,nmeta   standard = {length = 2cm}
    ,initial standard
    ,nmeta   small    = {length = 1cm}
    ,boolTF  negative = \VerticalStep@negative
  }
\ekvsetdef\VerticalStepSetup{VerticalStep}
\NewDocumentCommand\VerticalStep{O{}}
  {%
    \begingroup
      \VerticalStepSetup{#1}%
      \vspace{\VerticalStep@negative{-}{}\VerticalStep@length}%
    \endgroup
  }
\makeatother

\begin{document}
abc
\VerticalStep

def
\VerticalStep[negative]

ghi
\VerticalStep[small,negative]

jkl
\VerticalStep[length=5cm]% arbitrary sizes also possible

mno
\end{document}

Outputs of both look identical:

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .