LATEX-L Archives

Mailing list for the LaTeX3 project

LATEX-L@LISTSERV.UNI-HEIDELBERG.DE

Options: Use Forum View

Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Will Robertson <[log in to unmask]>
Reply To:
Mailing list for the LaTeX3 project <[log in to unmask]>
Date:
Mon, 22 Aug 2011 10:53:06 +0930
Content-Type:
text/plain
Parts/Attachments:
text/plain (78 lines)
On 22/08/2011, at 6:13 AM, Joseph Wright wrote:

> Okay, there are several approaches we might consider in this area. There
> are also questions about what is needed. For example, is it important to
> _know_ the two independent lists of keys, or just to pass unknown keys
> from one root to another? I guess I favour the later approach, provided
> it can do the required work here.

In my case, actually the former is more useful. (Well, at least to know the list of keys that weren't set.) In the vein of some of the more complex keyval packages, I don't find it super-useful to be able to set keys for multiple roots at once, as in your suggested:

 \keys_define:nn { foo }
   {
     unknown .redirect:n = { bar }
   }


Perhaps I should clarify a little more here. Speaking generally, the type of option processing I am used to (say in Mathematica) would occur in something like the following stages:

* Read user input of keys for some new function
* Process the keys specific to this function
* Do some stuff
* Execute an internal function that takes the leftover keys

Speaking for fontspec specifically, the reason I need multiple passes over keys is that some options are more important than others, internally. For example, depending on the "Renderer" setting, font features need to be expressed in different ways; also if the font is path-based rather than automatically found in fc-cache or whatever, its argument to \font needs to be different.

So even though it might be considered a bit ugly, the general process is

* Read user input with fontspec options
* Decide whether the font is path-based (one keyval parse)
* Decide what renderer to use and set up font-shape-specific options (another keyval parse)
* Finally process all the regular font features (final, main, keyval parse)
* (Actually that step happens up to eight or ten times for all the different font shape variations.)

I'm certainly willing to admit that this convolution of keyval parsing and actual font-selection mechanics isn't the cleanest way to write the code, it is in some ways simpler.

What I'm using presently in fontspec to do this is:

\keys_define:nn {fontspec-preparse}
  { unknown .code:n = { \fontspec_keys_filter:n {#1} } }

\cs_new:Nn \fontspec_keys_filter:n
  {
    \clist_put_right:Nx \l_fontspec_keys_leftover_clist
      { \l_keys_key_tl = { \exp_not:n {#1} } }
  }

\cs_new:Nn \fontspec_keys_set:nn
  {
    \clist_clear:N \l_fontspec_keys_leftover_clist
    \keys_set:nn {#1} {#2}
  }

So each \keys_set:nn stage can be separate but information from the previous can be passed along using \l_fontspec_keys_leftover_clist. (Not that this solution is particularly optimal, but it works for now.)

If you'd prefer me to refactor my code before trying to accommodate this particular use case, I can certainly understand this.


> I'm not sure if a separate \keys_filter: function is needed, or what is
> better is an extension to \keys_define:nn such that \keys_set:nn gains
> additional abilities. Taking the later approach, we might introduce a
> ".redirect:n" property:
> 
>  \keys_define:nn { foo }
>    {
>      unknown .redirect:n = { bar }
>    }
> 
> With this approach, we'd need to decide whether to wait until the end of
> the 'parent' \keys_set:nn run before doing the redirections, or to do
> the setting 'now', or indeed whether we need both variants. As I say, at
> the moment I'd go with 'interleaved' setting. You can also imagine
> extending such a property to named keys.


While I'm not arguing that this isn't a useful feature at all, I don't think it will work for my particular case (at least with the way that the code is written now). I'd be hesitant to add such a feature, though, until a very compelling use case comes along.

-- Will

ATOM RSS1 RSS2