0

I am using the xkeyval package to set a key "name". This value is then used in the hyperref package. Please see the sample code below:

File: mysuperclass.cls

\ProvidesClass{mysuperclass}
\LoadClass{article}

\RequirePackage{xkeyval}%

\def\docauthorname{A. U. Thor}%
\def\docname{\jobname.tex}%
\def\docdate{\today}%

\define@key{mysuperclass.cls}{docdate}[\today]{%
  \def\docdate{#1}%
}

\define@key{mysuperclass.cls}{author}[A. U. Thor]{%
  \def\docauthorname{#1}%
}
\define@key{mysuperclass.cls}{docname}[]{%
  \def\docname{#1}%
}

\ExecuteOptionsX{author,docdate}
\ProcessOptionsX%

\RequirePackage{fancyhdr}

\AtBeginDocument{%
\lhead[\docauthorname]{{\docauthorname}}%
\chead[\docdate]{\docdate}%
\rhead[]{\docname}%
\pagestyle{fancy}%
}

\RequirePackage{hyperref}
\hypersetup{%
  pdfauthor={{\docauthorname}}%
}%
\endinput

File: main.tex

\documentclass[docdate=1/1/2016,author=My Full Name with Spaces,docname=yelostfile]{mysuperclass}

\usepackage{blindtext}
\begin{document}
\blindtext[2]
\end{document}

Please note that the above code is taken from here. Below is a screenshot of the generated PDF: enter image description here

Please see below the PDF properties, pay attention to the author name: enter image description here

I found a similar question here and followed it. Unfortunately, it doesn't seem working as expected.

My question is how to retain whitespaces in xkeyval?

Workaround

The actual answer given by @Skillmon which requires TexLive 2021-06-01 and uses the expkv-opt package. @Skillmon, kindly suggested a workaround to avoid such dependencies. I am posting the complete code below for reference:

\begin{filecontents}{mysuperclass.cls}
\ProvidesClass{mysuperclass}
\LoadClass{article}

\RequirePackage{xkeyval}
\RequirePackage{etoolbox}
\RequirePackage{hyperref}
\RequirePackage{fancyhdr}

\define@key{mysuperclass.cls}{docdate}[\today]{
  \def\docdate{#1}
}

\define@key{mysuperclass.cls}{author}[A. U. Thor]{
  \def\docauthorname{#1}
}

\define@key{mysuperclass.cls}{docname}[My Document]{
  \def\docname{#1}
}

\ExecuteOptionsX{author,docdate,docname}
\ProcessOptionsX

\newcommand\setauthor[1]{
  \setkeys{mysuperclass.cls}{author=#1}
}

\newcommand\setdocdate[1]{
  \setkeys{mysuperclass.cls}{docdate=#1}
}

\newcommand\setdocname[1]{
  \setkeys{mysuperclass.cls}{docname=#1}
}

\AtEndPreamble{
  \hypersetup{
    pdfauthor={{\docauthorname}}
  }
  \AtBeginDocument{
    \lhead[\docauthorname]{{\docauthorname}}
    \chead[\docdate]{\docdate}
    \rhead[]{\docname}
    \pagestyle{fancy}
  }
}

\endinput
\end{filecontents}

\documentclass{mysuperclass}
\setauthor{My Full Name with Spaces}
\setdocdate{1/1/2016}
\setdocname{yelostfile}

\usepackage{blindtext}
\begin{document}
\blindtext[2]
\end{document}
1
  • the latex code to handle document options is very eager to remove spaces. with a current latex you could try to use the raw options list instead. Commented Jul 12, 2021 at 14:17

1 Answer 1

4

Like @UlrikeFischer said, LaTeX's original class/package option parsing was eagerly removing spaces. In recent versions there is a raw option list for which the spaces aren't zapped, but most packages don't yet support parsing this list.

To my knowledge the only package parsing the raw options currently is expkv-opt (disclaimer: I'm the author of that).

The following uses expkv-opt to parse the option list given to mysuperclass.cls directly (it doesn't look at the class options if it was loaded via \LoadClass, for this you'd have to also add \ekvoProcessGlobalOptions). To define the keys for expkv-opt you could either use the low-level interface provided by expkv, or use expkv-def to define keys using a key=value interface with a few predefined key types. This answer does the latter.

\begin{filecontents}{mysuperclass.cls}
\ProvidesClass{mysuperclass}
\LoadClass{article}

\RequirePackage{expkv-def,expkv-opt}

\ekvdefinekeys{mysuperclass.cls}
  {
     store   docdate = \docdate
    ,default docdate = \today
    ,initial docdate = \today
    ,store   author  = \docauthorname
    ,default author  = A. U. Thor
    ,initial author  = A. U. Thor
    ,store   docname = \docname
    ,default docname = {}
    ,initial docname = \jobname.tex
  }

\ekvoProcessLocalOptions{mysuperclass.cls}

\RequirePackage{fancyhdr}

\AtBeginDocument{%
\lhead[\docauthorname]{{\docauthorname}}%
\chead[\docdate]{\docdate}%
\rhead[]{\docname}%
\pagestyle{fancy}%
}

\RequirePackage{hyperref}
\hypersetup{%
  pdfauthor={{\docauthorname}}%
}%
\endinput
\end{filecontents}

\documentclass[docdate=1/1/2016,author=My Full Name with Spaces,docname=yelostfile]{mysuperclass}

\usepackage{blindtext}
\begin{document}
\blindtext[2]
\end{document}

Output:

enter image description here

10
  • I really ought to fix at least hyperref and kvoptions to do use the raw lists Commented Jul 12, 2021 at 15:23
  • @DavidCarlisle additionally we should nag Joseph to also fix pgfopts and l3keys2e.
    – Skillmon
    Commented Jul 12, 2021 at 15:23
  • @DavidCarlisle That reminds me of another, similar issue I never got around to asking about in here: If a package \usepackage[...] key value is set to be a command name, it seems that this command is fully expanded for some reason. For instance, this is the case if you run \usepackage[keyval parser=\ekvparse]{semantex}. Is this intentional, and can it be turned off?
    – Gaussler
    Commented Jul 12, 2021 at 17:07
  • 1
    @RaviJoshi the required LaTeX code is from 2021-06-01, if expkv-opt finds that this isn't available it turns to compatibility mode and parses the zapped list like the other packages. Consider updating to TeX Live 2021 for this feature. If that's not possible use another interface (instead of package options create a setup macro that is called after the package is loaded, and delay the evaluation of the keys until the end of the preamble by using \AtEndPreamble provided by the etoolbox package).
    – Skillmon
    Commented Jul 13, 2021 at 14:34
  • 1
    @RaviJoshi I won't look at your project, sorry. What I meant was do something like: \newcommand\mysetup[1]{\setkeys{mysuperclass.cls}{#1}} and tell the users to use that inside their preamble after the package/class was loaded instead of package/class options.
    – Skillmon
    Commented Jul 17, 2021 at 13:12

You must log in to answer this question.

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