latex3 tables add tag
Girish
I am trying to write a macro that generates a table using expl3. In the following code if `&` and `\multicolumn` are removed then it gives some output without errors. But I am not able to figure out what's wrong otherwise. This is my first attempt to use expl3, please bear with my silly mistakes.

Here is m(not)wc.

```
% !TeX program = xelatex
\documentclass{article}
\usepackage{xparse}
\usepackage{fontspec}
\setmainfont[Script=Devanagari,Mapping=devanagarinumerals]{Shobhika}

\ExplSyntaxOn
\int_new:N \l_swar_counter_int
\clist_new:N \l_swarbol_clist
\clist_new:N \l_swarlist_clist
\tl_new:N \l_antara_body_tl

\cs_new:Npn \extract_swar:n #1 {
	
	\clist_set:Nn \l_swarbol_clist {#1} 
 	\regex_replace_all:nnN {)} {,),} \l_swarbol_clist
    \regex_replace_all:nnN {\[[\x{0900}-\x{097F}\w,\{ \}]+ \]} {} \l_swarbol_clist
    \regex_replace_all:nnN {[(]} {} \l_swarbol_clist
    \clist_set_eq:NN \l_swarlist_clist \l_swarbol_clist
    \fill_body:n
}   
\cs_generate_variant:Nn \extract_swar:n { f }  
    
\cs_new_protected:Npn \fill_body:n
{    
    \tl_put_right:Nn \l_antara_body_tl 
	{
    	\int_set:Nn \l_swar_counter_int {1}
        
    	\int_while_do:nNnn {\l_swar_counter_int}<{20}
		{
    		 \str_if_eq:eeTF {\clist_item:Nn \l_swarlist_clist {\l_swar_counter_int+1}} {)} 
     		{     	
     			&\multicolumn{1}{c}{ \clist_item:Nn \l_swarlist_clist {\l_swar_counter_int}\int_add:Nn \l_swar_counter_int {2} }
     		} 
    		{
    			& \clist_item:Nn \l_swarlist_clist {\l_swar_counter_int}\int_incr:N \l_swar_counter_int
    		} 
		}	
	}
% \use_tl:N \l_antara_body_tl
}   
\cs_new_protected:Npn \antara_print:n
{
\begin{tabular}{*{20}{c}}
\l_antara_body_tl
\end{tabular}
}

\NewDocumentCommand \antara { m }
{	\extract_swar:f { #1 }
	\antara_print:n
}
\ExplSyntaxOff

\begin{document}
\antara{(प,{धंध},j,नीं)[a,b,c,d](प,{धंध},j,d)[a,b,c,d](प,{धंध},j,d)[a,b,c,d](प,{धंध},n,k)[a,b,c,d]}\\
\end{document}
```    
The expected output.

[![enter image description here][1]][1]


  [1]: https://i.stack.imgur.com/NsY14.png
  
  
  
 I have posted this question on SE also, link: [https://tex.stackexchange.com/questions/547924/table-macro-with-expl3](https://tex.stackexchange.com/questions/547924/table-macro-with-expl3) 
Top Answer
Skillmon
# Original answer (with small changes)

**EDIT:** I've changed `\fill_body:` to use `\clist_map_variable:NNn` instead of `\int_while_do:nNnn`, so that each `\clist_item:Nn` doesn't have to be grabbed twice. The result is a 6 times faster `\fill_body:`.

I hope the following does what you want, but I'm not sure.


Note that you have to build the token list inside the loop, not the other way around, and have to expand the value of `\l_swar_counter_int` before putting it in the token list variable (otherwise you'll just try to access the last element during output as that will be the current value of the integer variable). But I changed your `\fill_body:` even more using `\clist_map_variable:NNn`.

Also your code doesn't conform with the expl3 naming conventions (and I didn't fix this). The names of your functions and variables should start with the module name like this:

Function:
```
\<module>_<name>:<args>
```

Variable:

```
\<l/g>_<module>_<name>_<type>
```

Here is the code that should work (hopefully):

```
% !TeX program = xelatex
\documentclass{article}
\usepackage{xparse}
\usepackage{fontspec}
\setmainfont[Script=Devanagari,Mapping=devanagarinumerals]{Shobhika}

\ExplSyntaxOn
\int_new:N \l_swar_counter_int
\clist_new:N \l_swarbol_clist
\clist_new:N \l_swarlist_clist
\tl_new:N \l_swarbol_tl
\tl_new:N \l_antara_body_tl

\cs_new:Npn \extract_swar:n #1
  {
    \tl_set:Nn \l_swarbol_tl {#1} 
    \regex_replace_all:nnN {)} {,),} \l_swarbol_tl
    \regex_replace_all:nnN
      { \[[\x{0900}-\x{097F}\w,\{ \}]+ \] } {} \l_swarbol_tl
    \regex_replace_all:nnN {[(]} {} \l_swarbol_tl
    \clist_set:NV \l_swarbol_clist \l_swarbol_tl
    \clist_set_eq:NN \l_swarlist_clist \l_swarbol_clist
    \fill_body:
  }   
\cs_generate_variant:Nn \extract_swar:n { f }  
    
\cs_new_protected:Npn \fill_body:
  {
    \tl_clear:N \l_antara_body_tl
    \cs_set_eq:NN \l_swarlist_tmpa_tl \q_nil
    \clist_map_variable:NNn \l_swarlist_clist \l_swarlist_tmpb_tl
      {
        \quark_if_nil:NTF \l_swarlist_tmpa_tl
          {
            \tl_set_eq:NN \l_swarlist_tmpa_tl \l_swarlist_tmpb_tl
          }
          {
            \str_if_eq:eeTF { \l_swarlist_tmpb_tl } { ) }
              {
                \tl_put_right:Nx \l_antara_body_tl
                  {
                    & \exp_not:n { \multicolumn { 1 } { c } }
                    { \exp_not:o \l_swarlist_tmpa_tl }
                  }
                \cs_set_eq:NN \l_swarlist_tmpa_tl \q_nil
              }
              {
                \tl_put_right:Nx \l_antara_body_tl
                  {
                    & \exp_not:o \l_swarlist_tmpa_tl
                  }
                \tl_set_eq:NN \l_swarlist_tmpa_tl \l_swarlist_tmpb_tl
              }
          }
      }
    \quark_if_nil:NF \l_swarlist_tmpa_tl
      {
        \tl_put_right:Nx \l_antara_body_tl { & \exp_not:o \l_swarlist_tmpa_tl }
      }
  }
\cs_new_protected:Npn \antara_print:
  {
    \begin{tabular}{*{20}{c}}
      \l_antara_body_tl
    \end{tabular}
  }

\NewDocumentCommand \antara { m }
  {
    \extract_swar:f { #1 }
    \antara_print:
  }
\ExplSyntaxOff

\begin{document}
\antara{(प,{धंध},j,नीं)[a,b,c,d](प,{धंध},j,d)[a,b,c,d](प,{धंध},j,d)[a,b,c,d](प,{धंध},n,k)[a,b,c,d]}\\
\end{document}
```


# New answer with faster code (still not matching naming conventions)

If you want to replace fixed symbols and not a real regular expression and don't need to replace tokens which are inside of braces, you can use `\tl_replace_all:Nnn` or `\tl_remove_all:Nn`, which are a lot faster than `\regex_replace_all:nnN`. Also you can get a slight speed enhancement by using `\regex_const:Nn` and `\regex_replace_all:NnN` if the regular expression is always the same and you intend to use it often. Also by using a `\q_nil` instead of `)` to mark a closing parenthesis you can use the way faster test `\quark_if_nil:NTF` instead of `\str_if_eq:eeTF`.

```
% !TeX program = xelatex
\documentclass{article}
\usepackage{xparse}
\usepackage{fontspec}
\setmainfont[Script=Devanagari,Mapping=devanagarinumerals]{Shobhika}

\ExplSyntaxOn
\clist_new:N \l_swarbol_clist
\clist_new:N \l_swarlist_clist
\tl_new:N \l_swarbol_tl
\tl_new:N \l_swarlist_tmpa_tl
\tl_new:N \l_swarlist_tmpb_tl
\tl_new:N \l_antara_body_tl
\regex_const:Nn \c_swarbol_regex { \[[\x{0900}-\x{097F}\w,\{ \}]+ \] }

\cs_new:Npn \extract_swar:n #1
  {
    \tl_set:Nn \l_swarbol_tl { #1 }
    \tl_remove_all:Nn \l_swarbol_tl { ( }
    \tl_replace_all:Nnn \l_swarbol_tl { ) } { , \q_nil , }
    \regex_replace_all:NnN \c_swarbol_regex {} \l_swarbol_tl
    \clist_set:NV \l_swarbol_clist \l_swarbol_tl
    \clist_set_eq:NN \l_swarlist_clist \l_swarbol_clist
    \fill_body:
  }
\cs_generate_variant:Nn \extract_swar:n { f }

\cs_new_protected:Npn \fill_body:
  {
    \tl_clear:N \l_antara_body_tl
    \cs_set_eq:NN \l_swarlist_tmpa_tl \q_nil
    \clist_map_variable:NNn \l_swarlist_clist \l_swarlist_tmpb_tl
      {
        \quark_if_nil:NF \l_swarlist_tmpa_tl
          {
            \quark_if_nil:NTF \l_swarlist_tmpb_tl
              {
                \tl_put_right:Nx \l_antara_body_tl
                  {
                    & \exp_not:n { \multicolumn { 1 } { c } }
                    { \exp_not:o \l_swarlist_tmpa_tl }
                  }
              }
              {
                \tl_put_right:Nx \l_antara_body_tl
                  { & \exp_not:o \l_swarlist_tmpa_tl }
              }
          }
        \tl_set_eq:NN \l_swarlist_tmpa_tl \l_swarlist_tmpb_tl
      }
    \quark_if_nil:NF \l_swarlist_tmpa_tl
      {
        \tl_put_right:Nx \l_antara_body_tl { & \exp_not:o \l_swarlist_tmpa_tl }
      }
  }
\cs_new_protected:Npn \antara_print:
  {
    \begin{tabular}{*{20}{c}}
      \l_antara_body_tl
    \end{tabular}
  }

\NewDocumentCommand \antara { m }
  {
    \extract_swar:f { #1 }
    \antara_print:
  }
\ExplSyntaxOff

\begin{document}
\antara{(प,{धंध},j,नीं)[a,b,c,d](प,{धंध},j,d)[a,b,c,d](प,{धंध},j,d)[a,b,c,d](प,{धंध},n,k)[a,b,c,d]}\\
\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.