TransWikia.com

Why does this regex_split:nnN results in error and insertion of `{`?

TeX - LaTeX Asked by Fabian Schneider on June 10, 2021

I am playing around with expl3 and wanted to try some higher order programming.
In this example I define an environment and then perform an action on this environment:

documentclass{article}
usepackage[T1]{fontenc}
usepackage{expl3}
usepackage{amsmath, amssymb}

begin{document}

ExplSyntaxOn
prop_new:N l_files_prop
newcommand{addConfig}[2]{
    prop_put:Nnn l_files_prop {#1} {{#2}}
}
newcommand{printConfig}[2]{
    prop_get:NnN l_files_prop {#1} l__files
    cs_generate_variant:Nn {regex_split:nnN} {nVN}
    regex_split:nVN {;} {l__files} {l__files_split_tl}
    %seq_set_split:NnV l__files_split_tl {o} {l__files}
  
    %seq_set_split:Nnn l__cmd_tl {textbackslash} {tl_to_str:n #2}
    seq_map_inline:Nn l__files_split_tl {
        use:c {cs_to_str:N #2} {##1}
    } 
}

ExplSyntaxOff

addConfig{config1}{hello; world}
addConfig{config2}{bye; world}
addConfig{config3}{testFile.tex; testFile2.tex}

noindent
printConfig{config1}{textit}
printConfig{config2}{textbf}
%printConfig{config3}{input}

end{document}

which correctly results in

result1

however, I get the following error along with the correct output:

! LaTeX3 Error: Missing brace inserted when splitting or extracting
(LaTeX3)        submatches.

For immediate help type H <return>.
 ...                                              
                                                  
l.75 printConfig{config1}{textit}
                                   

LaTeX was asked to do some regular expression operation, and the resulting
token list would not have the same number of begin-group and end-group tokens.
Braces were inserted: 1 left, 1 right.

and I don’t really understand why;
I try to follow this guide and work with the documentation but I also couldn’t find any information why this is occurring.

How can I rewrite the code to remove this error? And (more importantly), why does it appear?

One Answer

You are adding a spurious set of braces in your prop_put:Nnn command:

prop_put:Nnn l_files_prop {#1} {{#2}}

Changing that to

prop_put:Nnn l_files_prop {#1} {#2}

solves the problem. The error happens because with a token list {hello;world}, splitting it at the ; will leave unbalanced braces in each item ({hello and world}), which is illegal, so l3regex inserts some to balance the token lists.

I also changed some things to conform better with expl3 standards:

  • All variables should be declared, so you need a tl_new:N l__files_split_tl and a tl_new:N l__files (see next item about this one);
  • Variables should be named ⟨scope⟩_⟨module⟩_⟨name⟩_⟨type⟩ so l__files is a terrible name. Something like l__fabian_files_tl is better, assuming fabian is the module;
  • cs_generate_variant:Nn can be done only once per variant, so you can move it outside the command;
  • Assuming #2 is a control sequence, use:c {cs_to_str:N #2} has the same effect as just #2, so you can simplify;
  • The output of regex_split:nnN is a seq variable, not a tl, so you should use that instead;
  • [bonus] If you just want to split at a ; you don't need regex at all. Instead of the regex_split:nVN line you can use seq_set_split:NnV l__fabian_files_split_seq { ; } l__fabian_files_tl (the main difference is that regex_split:nVN will preserve spaces around items, but seq_set_split:NnV will trim spaces).

Here's the code:

documentclass{article}
usepackage[T1]{fontenc}
usepackage{xparse}
usepackage{amsmath, amssymb}

begin{document}

ExplSyntaxOn
prop_new:N l_fabian_files_prop
tl_new:N l__fabian_files_tl
seq_new:N l__fabian_files_split_seq
% cs_generate_variant:Nn regex_split:nnN { nV }

NewDocumentCommand addConfig { mm }
  { prop_put:Nnn l_fabian_files_prop {#1} {#2} }
NewDocumentCommand printConfig { mm }
  {
    prop_get:NnN l_fabian_files_prop {#1} l__fabian_files_tl
    % regex_split:nVN { ; } l__fabian_files_tl l__fabian_files_split_seq
    seq_set_split:NnV l__fabian_files_split_seq { ; } l__fabian_files_tl
    seq_map_inline:Nn l__fabian_files_split_seq { #2 {##1}  }
  }

ExplSyntaxOff

addConfig{config1}{hello; world}
addConfig{config2}{bye; world}
addConfig{config3}{testFile.tex; testFile2.tex}

noindent
printConfig{config1}{textit}
printConfig{config2}{textbf}
%printConfig{config3}{input}

end{document}

Correct answer by Phelype Oleinik on June 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP