# Set value of \geometry keys from a macro

I am trying to set parameters of the geometry package via macros. For example

\def\xxx{false}
\geometry{twoside=\xxx}


However the above command, nor \expandafter\geometry{twoside=\xxx} seem to work; I also tried \expandafter\geometry\expandafter{twoside=\xxx} as suggested by pass to \geometry{} options using a macro - keyval error . Is there a way to make this work? (Preferably an expl3 way)

Your sequence of \expandafter's only reaches t.

There may be better ways, but without further details on your document class and where \xxx is set, this can work

\def\xxx{false} % or true

\expandafter\geometry\expanded{twoside=\xxx}


If you don't trust your users to have a recent TeX distribution that supports \expanded, you can do

\def\xxx{false} % or true

\begingroup\edef\x{\endgroup\noexpand\geometry{twoside=\xxx}}\x


A more generic way could be

\newcommand{\js@set@geometry@option}[2]{%
\expandafter\js@set@geometry@option@aux\expandafter{#2}{#1}%
}
\newcommand\js@set@geometry@option@aux[2]{\geometry{#2=#1}}


so you can call

\js@set@geometry@option{twoside}{\xxx}


and any other option can be used.

For expl3 keys, you can define a choice key:

\documentclass{book}
\usepackage{xparse,geometry,lipsum}

\ExplSyntaxOn

\NewDocumentCommand{\selectoptions}{m}
{
\keys_set:nn { jason/class } { #1 }
}

\keys_define:nn { jason/class }
{
twoside .choices:nn = { true, false } { \geometry{twoside=#1} },
twoside .default:n = true,
}

\ExplSyntaxOff

\selectoptions{twoside}

\begin{document}

\chapter{Test chapter}

\section{Test section}

\lipsum[1-20]

\end{document}

• I am actually try to set this from a l3keys boolean value. I have twosided .bool_set:N = \l__twosided, and I was trying \gemetry{twoside=\bool_if:nTF \l__twosided {true} {false}}. Maybe there's a better way to extract the boolean? – Jason Siefken Jun 12 '20 at 16:58
• @JasonSiefken Use a choice key – egreg Jun 12 '20 at 17:29
• That's a nice solution :-). Can you have .choices:nn and .set_bool:N? – Jason Siefken Jun 12 '20 at 20:51
• @JasonSiefken You can use any code inside the second part, together with \geometry{twoside=#1}, for instance \bool_gset:Nn \g_jason_twoside_bool { \use:c { c_#1_bool } } – egreg Jun 12 '20 at 21:46

In \geometry{twoside=\xxx}, what you need is to expand \xxx first, then \geometry. In \expandafter\geometry\expandafter{twoside=\xxx}, t is expanded first, then \geometry.

Here is a solution, to use a macro to collect the key-value list, then pass it to \geometry{...}.

\usepackage{etoolbox}

\makeatletter
\def\geo@options{}

\appto\geo@options{twoside=}
% now \geo@options == "twoside="

\def\xxx{false}
\expandafter\appto\expandafter\geo@options{\xxx}
% now \geo@options == "twoside=false"

\expandafter\geometry\expandafter{\geo@options}
\makeatother