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}

ravi
  • 1,618
  • 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. – Ulrike Fischer Jul 12 '21 at 14:17

1 Answers1

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

Skillmon
  • 60,462
  • I really ought to fix at least hyperref and kvoptions to do use the raw lists – David Carlisle Jul 12 '21 at 15:23
  • @DavidCarlisle additionally we should nag Joseph to also fix pgfopts and l3keys2e. – Skillmon Jul 12 '21 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 Jul 12 '21 at 17:07
  • @Gaussler it is related to the same issue. the argument handling is designed for a4paper,12pt not for keyval, it is fully expanded and all spaces are removed. The new raw option list handling allows modified option hanlers to access the original argument and use keyval processing without pre-expansion. But whichever package you are using to parse that argument needs to be updated to use the raw option lists. – David Carlisle Jul 12 '21 at 17:16
  • @Gaussler even if you use a key=value solution that accesses the raw option list, this will not work currently. – Skillmon Jul 12 '21 at 18:56
  • @Skillmon: Thank you very much for kindly providing and explaining the answer. Unfortunately, I did not have the expkv package. I am using TeX Live 2020. I downloaded dtx files one by one and used pdftex. But I am still can't see spaces. Something wrong with the dtx conversion? Can you please have a look at my project file in shared Dropbox? – ravi Jul 13 '21 at 13:30
  • 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 Jul 13 '21 at 14:34
  • @Skillmon: Thank you again. Using \AtEndPreamble{\hypersetup{pdfauthor={{\docauthorname}}}} it is easy to get \docauthorname but I could not understand, how to create a setup macro that is called after the package is loaded I tried using \define@key{mysuperclass.cls} from \RequirePackage{xkeyval} but it does not seem working. I am sharing my project in Dropbox. Can you please have a look? Thank you so much. – ravi Jul 17 '21 at 13:06
  • 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 Jul 17 '21 at 13:12
  • @Skillmon: Thank you very much. I added the suggested workaround in the question above and accepted the answer. Thanks again. – ravi Jul 18 '21 at 04:25