I'm afraid I still don't get how I'm supposed to handle the communication of options among packages in a LaTeX3/expl3 context. Let us say I have a package pkg1 where I define an option opt_pkg1 that is set in the document, but which is actually used just to drive the options (opt1_pkg2,opt2_pkg2...) with which another package pkg2 is loaded from the first (pkg1). What's a correct way to do this by using l3keys?

I'll try to make my point clear by way of a small example, something akin to a semiMnotWE: There are missing declarations for some Booleans, besides other tidbits making it a not working example... It is supposed just to be able to convey my point. Observe that I have switched from pkg1(2) to pkgA(B) due to syntax requirements.

The basic message behind it is: In pkgA I define the options that allow me to set the typeface and the separate possibility to choose a sans face in the main document. Setting the typeface leads pkgA to load one or another extra package (pkgB) and, in this case, my choosing a sans face leads to loading pkgB with one or another option. Hope I've been able to make my point clear...

This is pkgA.sty, although in general -- in my case -- this will be a class file:

 {LaTeX2e/LaTeX3 package}

\RequirePackage{xparse,l3keys2e}% Needed?

\NewDocumentCommand\SetTBool { m }
    \bool_set_true:c { g_pkgA_#1_bool }

\keys_define:nn { pkgA }
    typeface .choice_code:n =
        { \SetTBool { \tl_use:N \l_keys_choice_tl } },
    typeface .generate_choices:n = { lucida, libertine },
    typeface .initial:n = libertine,

    sans-face .choice_code:n =
        { % Watch out! 
          % The next switch does not work as it is, but I guess it conveys my point
           \tl_if_eq:NnT \l_keys_choice_tl { sansbiolinum }
              % In this branch I set or pass (???) the { sansbiolinum = true } option to pkgB 
    sans-face .generate_choices:n = { sansbiolinum, sansmyriad }, 

\DeclareDocumentCommand\DocumentSetup { +m }
 { \keys_set:nn { pkgA }{ #1 } }

\ProcessKeysOptions { pkgA }

\bool_if:NT \g_pkgA_lucida_bool { \RequirePackage{pkgB} }

Next comes pkgB.sty:

 {LaTeX2e/LaTeX3 package}


\keys_define:nn { pkgB }
    sansbiolinum .bool_set:N = \g_pkgB_sansbiolinum_bool,

\ProcessKeysOptions { pkgB }    

\bool_if:NT \g_pkgB_sansbiolinum_bool 
  { \RequirePackage[osf]{biolinum} }

Lastly, in the "document" (.tex file), I have something like:



   typeface = lucida,
   sans-face = sansbiolinum,

 \ProcessKeysOptions { pkgA }

 Blah, blah, blah.
  • Could you edit in a more concrete example? Something along the first lines of pkg1 (if I understand the question correctly)? Aug 24, 2013 at 14:36
  • As I understand it, you just want to pass options from one package to another. You shouldn't be assuming any internal structural relationship between the two, so should be passing the options as normal. Do I miss something?
    – Joseph Wright
    Aug 24, 2013 at 15:35
  • Please, see the edit to my OP.
    – Marcos
    Aug 24, 2013 at 16:49
  • 1
    You can't use pkg1 and pkg2 as part of control sequence names. Please, edit them like pkgI and pkgII or something like that. They're good in module names for \keys_define:nn, but \g_pkg2_sansbiolinum_bool is illegal.
    – egreg
    Aug 24, 2013 at 17:01
  • @egreg: Done. Thx.
    – Marcos
    Aug 24, 2013 at 17:05

1 Answer 1


The fact that each package uses l3keys internally should not affect at all how you pass load-time options: you should use the defined interfaces of pkgB. As described, pkgB only makes its options available at load time (we don't see the docs, but the way the code is written suggests there is no \pkgBsetup). As such, you should make available in pkgA an option which only works before pkgB is loaded: probably again a load-time option. This can then pass information to pkgB using \PassOptionsToPackage as normal.

  • Your answer seemed to me a bit cryptic, but finally I got everything I needed straight and I find the LaTeX3/expl3 key-value experience to be much more satisfying than any of its LaTeX2e counterparts.
    – Marcos
    Sep 2, 2013 at 13:45

You must log in to answer this question.

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