add tag
निरंजन
I combined the two answers received on [this](https://topanswers.xyz/tex?q=8074) question. `l3`fied the code and have created an `expkv`+`latex3` interface. One new feature is added. It's nearly working, but there are two macros that are not expanding where I want them to. I am failing to understand why. I have the following three expectations.

1. `\l__my_field_tl` and `\l__my_type_tl` work in one segment of my `l3msg` (cf. `field` and `type` entries from the generated log), but fail in the `nfss` entry. I am guessing it's a grouping (local vs. global) problem, but I don't understand how. I start one group in the `meta` key `article` and end it after all the other processing is finished as everything else is inside its scope.

2. `\l__my_font_print_tl` and `\l__my_font_options_print_tl` are not expanding in the message command at all. They need to tell me the font name and loaded font options (as the names suggest). I am pretty sure that the options will be too many, so is there any way I can preprocess them and instead of commas+randomly wrapped text like:

   ```
   (my)             options:  Color=red,Renderer=HarfBuzz,
   (my)             BoldFont=KpSans-Bold.otf
   ```

   I would like to add a line-break and some extra spaces, like:
   
   ```
   (my)             options:  Color=red,
   (my)                       Renderer=HarfBuzz,
   (my)                       BoldFont=KpSans-Bold.otf
   ```
   
   Would require some extra processing, but if its not too much of a burden, I would love to try it.

3. Finally and most importantly, the font is not getting set with the font command! It was getting set before I got into `l3`-fication. Now I don't know where I exactly made the mistake. Here is the code I have created:

```
\documentclass{article}
\usepackage{fontspec}
\usepackage{expkv}
\usepackage{xcolor}
\ExplSyntaxOn
\seq_new:N \l__my_font_options_seq
\seq_new:N \l__my_type_seq
\tl_new:N \l__my_field_tl
\tl_new:N \l__my_type_tl
\tl_new:N \l__my_meta_tl
\tl_new:N \l__my_font_print_tl
\tl_new:N \l__my_font_options_print_tl

\msg_new:nnn { my } { font } {
  A~ font~ has~ been~ successfully~ set:\\
  \tl_if_empty:NF  \l__my_meta_tl {
    meta:\ \ \ \ \ \l__my_meta_tl\\
  }
  cs:\ \ \ \ \ \ \ \c_backslash_str #1\\
  field:\ \ \ \    \l__my_field_tl\\
  type:\ \ \ \ \   \l__my_type_tl\\
  font:\ \ \ \ \   #2\\
  nfss:\ \ \ \ \   #3\\
  options:\ \      #4
}

\cs_new_protected:Npn \__my_new_font_family:Nnn #1#2#3 {
  \newfontfamily {#1} [#2] {#3}
}

\cs_generate_variant:Nn \__my_new_font_family:Nnn { ce }

\cs_new_protected:Npn \__my_process_font:n #1 {
  \seq_set_split:Nnn \l__my_font_options_seq
                     { ;  }
                     { #1 }
  \__my_new_font_family:cen {
    __ my
    _  \l__my_field_tl
    _  \l__my_type_tl
    _  font
  } {
    \seq_item:Nn \l__my_font_options_seq { 2 },
    NFSSFamily = {
        my
      _ \l__my_field_tl
      _ \l__my_type_tl
      _ nfss
    }
  } {
    \seq_item:Nn \l__my_font_options_seq { 1 }
  }
  \tl_set:Ne \l__my_font_print_tl {
    \seq_item:Nn \l__my_font_options_seq { 2 }
  }
  \tl_set:Ne \l__my_font_options_print_tl {
    \seq_item:Nn \l__my_font_options_seq { 1 }
  }
  \seq_put_right:NV \l__my_type_seq \l__my_type_tl
}

\cs_new_protected:Npn \__my_set_fonts:n #1 {
  \cs_gset:cpn { __ my _ #1 _ fonts } {
    \seq_map_inline:Nn \l__my_type_seq {
      \cs_set:cpn { ####1default }
                  { my #1 _ ####1 _ nfss }
    }
    \normalfont
  }
  \msg_note:nnnnnn { my }
                   { font }
                   {
                     __ my _ #1 _ fonts
                   }
                   {
                     \l__my_font_print_tl
                   }
                   {
                     my
                     _ \l__my_field_tl
                     _ \l__my_type_tl
                     _ nfss
                   }
                   {
                     \l__my_font_options_print_tl
                   }
}

\clist_map_inline:nn {
  article,book
}{
  \protected \ekvdef { my-initial } { #1 } {
    \group_begin:
    \tl_set:Nn \l__my_meta_tl { #1 }
    \ekvset { my-initial } { ##1 }
    \group_end:
  }
}

\clist_map_inline:nn {
  title,
  subtitle
} {
  \protected \ekvdef { my-initial } { #1 } {
    \__my_seq_clear:
    \tl_if_empty:NTF \l__my_meta_tl {
      \tl_set:Nn \l__my_field_tl { #1 }
    } {
      \tl_set:Ne \l__my_field_tl {
        \l__my_meta_tl _ #1
      }
    }
    \ekvset { my-vital } { ##1 }
    \exp_args:Ne \__my_set_fonts:n { \l__my_field_tl }
  }
}

\clist_map_inline:nn {
  rm,
  sf,
  tt
} {
  \protected \ekvdef { my-vital } { #1 } {
    \tl_set:Nn \l__my_type_tl { #1 }
    \__my_process_font:n { ##1 }
  }
}

\cs_new:Nn \__my_seq_clear: {
  \seq_clear:N \l__my_mathrm_seq
  \seq_clear:N \l__my_font_options_seq
  \seq_clear:N \l__my_type_seq
}
\ExplSyntaxOff
\NewDocumentCommand \setup { m } {%
  \ekvset{my-initial}{#1}
}

\begin{document}
\setup{
  article           = {
    title             = {
      rm                = {
        KpRoman-Regular.otf;
        Color             = {blue}
      }
    }
  },
  subtitle          = {
    sf                = {
      KpSans-Regular.otf;
      Color             = {red}
    }
  }
}
\ExplSyntaxOn
\__my_article_title_fonts
\ExplSyntaxOff
abcd
\end{document}
```

Connected to this, I also want a general advise on whether I should expand the font-options like this in public packages? Do you see any risks in it? As a side note: The `<font>;<font-opts>` syntax is not for any public releases. I myself don't like it much, but for a privately collaborated project, I need it. But the other question regarding the expansion of font options is generic.
Top Answer
Skillmon
You have the same issue you had last time: `\seq_map_inline:Nn \l__my_type_seq` is only executed when `\l__my_type_seq` is empty due to grouping (I switched to `\seq_map_function:NN` and expansion where it is used by using `\cs_gset:cpx`). Also you got inconsistent grouping problems (I removed the groups and instead manually clear `\l__my_meta_tl`). If you're using either `article` or `book` as the top level in your setup command you get groups, if you directly pick either `title` or `subtitle` there are no groups. Even if `\l__my_type_seq` wasn't empty you would have an `_` missing after `my`. And you mixed up the sequence items of `\l__my_font_print_tl` and `\l__my_font_options_print_tl`.

I tried copying your indentation style, I hope I got it right everywhere...

```
\documentclass{article}

\usepackage{fontspec}
\usepackage{expkv}
\usepackage{xcolor}

\ExplSyntaxOn
\seq_new:N \l__my_font_options_seq
\seq_new:N \l__my_type_seq
\tl_new:N \l__my_field_tl
\tl_new:N \l__my_type_tl
\tl_new:N \l__my_meta_tl
\tl_new:N \l__my_font_print_tl
\tl_new:N \l__my_font_options_print_tl

% sorry I inserted a bunch of spaces here, I found it easier to spot the
% alignment this way since every space takes two characters as well.
\msg_new:nnn { my } { font } {
  A~ font~ has~ been~ successfully~ set:\\
  \tl_if_empty:NF  \l__my_meta_tl {
    m e t a : \ \ \ \ \   \l__my_meta_tl\\
  }                    
  c s : \ \ \ \ \ \ \   \c_backslash_str #1\\
  f i e l d : \ \ \ \   \l__my_field_tl\\
  t y p e : \ \ \ \ \   \l__my_type_tl\\
  f o n t : \ \ \ \ \   #2\\
  n f s s : \ \ \ \ \   #3\\
  o p t i o n s : \ \   #4
}

\cs_new_protected:Npn \__my_new_font_family:Nnn #1#2#3 {
  \newfontfamily {#1} [#2] {#3}
}

\cs_generate_variant:Nn \__my_new_font_family:Nnn { ceV }

\cs_new_protected:Npn \__my_process_font:n #1 {
  \seq_set_split:Nnn \l__my_font_options_seq
                     { ;  }
                     { #1 }
  \tl_set:Ne \l__my_font_print_tl {
    \seq_item:Nn \l__my_font_options_seq { 1 }
  }
  \tl_set:Ne \l__my_font_options_print_tl {
    \seq_item:Nn \l__my_font_options_seq { 2 }
  }
  \__my_new_font_family:ceV {
    __ my
    _  \l__my_field_tl
    _  \l__my_type_tl
    _  font
  } {
    \exp_not:V \l__my_font_options_print_tl,
    NFSSFamily = {
        my
      _ \l__my_field_tl
      _ \l__my_type_tl
      _ nfss
    }
  }
  \l__my_font_print_tl

  \seq_put_right:NV \l__my_type_seq \l__my_type_tl
}

\cs_new:Npn \__my_prettyprint_font_options: {
  \tl_if_empty:NF \l__my_font_options_print_tl {
    % fully expand the _key:n and _pair:nn auxiliaries
    \exp_last_unbraced:Ne
    % remove the leading ^^J,<spaces> from the first item
    \use_iii:nnn {
      % expand \keyval_parse:nnV to a list of _key:n and _pair:nn calls
      \use:e {
        \keyval_parse:nnV \__my_prettyprint_font_options_key:n
                          \__my_prettyprint_font_options_pair:nn
                          \l__my_font_options_print_tl
      }
    }
  }
}
\cs_new:Npn \__my_prettyprint_font_options_key:n #1 {
  \__my_prettyprint_font_options_indent:
  \exp_not:n {#1}
}
\cs_new:Npn \__my_prettyprint_font_options_pair:nn #1#2 {
  \__my_prettyprint_font_options_indent:
  \exp_not:n { \exp_not:n {#1} } ~=~ { \exp_not:n { \exp_not:n {#2} } }
}
\cs_new:Npx \__my_prettyprint_font_options_indent: {
  ,^^J \prg_replicate:nn {10} { ~ }
}

\cs_new:Npn \__my_set_fonts_aux:n #1 {
  \cs_set:Npn \exp_not:c { #1 default }
    { my _ \exp_not:V \l__my_field_tl _ \exp_not:n {#1} _ nfss }
}
\cs_new_protected:Npn \__my_set_fonts:n #1 {
  \cs_gset:cpx { __ my _ \l__my_field_tl _ fonts } {
    \seq_map_function:NN \l__my_type_seq \__my_set_fonts_aux:n
    \exp_not:N \normalfont
  }
  \msg_note:nneeee { my }
                   { font }
                   { __ my _ \exp_not:n {#1} _ fonts }
                   { \l__my_font_print_tl }
                   {
                     my
                     _ \l__my_field_tl
                     _ \l__my_type_tl
                     _ nfss
                   }
                   { \__my_prettyprint_font_options: }
}

\clist_map_inline:nn {
  article,book
}{
  \protected \ekvdef { my-initial } { #1 } {
    \tl_set:Nn \l__my_meta_tl { #1 }
    \ekvset { my-initial } { ##1 }
    \tl_clear:N \l__my_meta_tl
  }
}

\clist_map_inline:nn {
  title,
  subtitle
} {
  \protected \ekvdef { my-initial } { #1 } {
    \__my_seq_clear:
    \tl_if_empty:NTF \l__my_meta_tl {
      \tl_set:Nn \l__my_field_tl { #1 }
    } {
      \tl_set:Ne \l__my_field_tl {
        \l__my_meta_tl _ #1
      }
    }
    \ekvset { my-vital } { ##1 }
    \exp_args:Ne \__my_set_fonts:n { \l__my_field_tl }
  }
}

\clist_map_inline:nn {
  rm,
  sf,
  tt
} {
  \protected \ekvdef { my-vital } { #1 } {
    \tl_set:Nn \l__my_type_tl { #1 }
    \__my_process_font:n { ##1 }
  }
}

\cs_new:Nn \__my_seq_clear: {
  \seq_clear:N \l__my_mathrm_seq
  \seq_clear:N \l__my_font_options_seq
  \seq_clear:N \l__my_type_seq
}
\NewDocumentCommand \setup { m } {
  \ekvset{my-initial}{#1}
}
\ExplSyntaxOff

\setup{
  article           = {
    title             = {
      rm                = {
        KpRoman-Regular.otf;
        Color             = {blue}
      }
    }
  },
  subtitle          = {
    sf                = {
      KpSans-Regular.otf;
      Color             = {red},
    }
  }
}

\begin{document}
\ExplSyntaxOn
\__my_subtitle_fonts
\ExplSyntaxOff
abcd
\end{document}
```

Enter question or answer id or url (and optionally further answer ids/urls from the same question) from

Separate each id/url with a space. No need to list your own answers; they will be imported automatically.