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

2 Answers2

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

frougon
  • 24,283
  • 1
  • 32
  • 55
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

Skillmon
  • 60,462