निरंजन
I am developing a code for a package. I will explain it by unbundling some of its chunks.
* Using [this](https://tex.stackexchange.com/a/300215/174620) SE answer (the `expl` method given at the end), I first added a command to repeat a token in the code. Thus I was able to achieve the following -
```
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\myrepeat}{O{}mm}
{
\int_compare:nT { #2 > 0 }
{
#3 \prg_replicate:nn { #2 - 1 } { #1#3 }
}
}
\ExplSyntaxOff
\begin{document}
\begin{tabular}{|\myrepeat{4}{c}|}
\hline
& & & \\
\hline
\end{tabular}
```
This code produces a table with 4 (center aligned) columns without any error.
* I further added a command (which I learnt from [this](https://tex.stackexchange.com/a/336295/174620) answer) to count a specific character and return the number. The minimal code will look like this -
```
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\CountSubStr}{ m m }{
\seq_set_split:Nnn \l_tmpa_seq { #1 } { #2 }
\int_eval:n {(\seq_count:N \l_tmpa_seq) - 1 }
}
\ExplSyntaxOff
\begin{document}
\CountSubStr{-}{---}
\end{document}
```
(This code shall print `3`.)
* Now I want to use the number returned by `\CountSubStr` in `\myrepeat` command. I have tried the following code.
```
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\myrepeat}{O{}mm}
{
\int_compare:nT { #2 > 0 }
{
#3 \prg_replicate:nn { #2 - 1 } { #1#3 }
}
}
\NewDocumentCommand{\CountSubStr}{ m m }{
\seq_set_split:Nnn \l_tmpa_seq { #1 } { #2 }
\int_eval:n {(\seq_count:N \l_tmpa_seq) - 1 }
}
\ExplSyntaxOff
\newcounter{algn}
\newenvironment{newtab}[1]{%
\setcounter{algn}{\numexpr\CountSubStr{-}{#1}}
\begin{tabular}{|\myrepeat{\thealgn}{c}|}
}%
{\end{tabular}}
\begin{document}
\begin{tabular}{|\myrepeat{4}{c}|}
\hline
& & & \\
\hline
\end{tabular}
%\begin{newtab}{----}
%\hline
% & & & \\
%\hline
%\end{newtab}
\end{document}
```
I want the commented code to work, but at the moment it isn't working. How to achieve that?
Top Answer
Skillmon
Just for fun (and to please Marmots) an `expl3`-free variant.
```tex
\documentclass{article}
\makeatletter
%% Use `\setupsubstrcounter` to define which substring should be searched for
%% afterwards you can use `\substrcounter` to count the number of substring
%% matches in the first argument with two steps of expansion.
\newcommand\setupsubstrcounter[1]
{%
\long\def\substrcounter@##1#1##2\substrcounter@a##3%
{##3##2\substrcounter@a{##3}}%
\long\def\substrcounter##1%
{%
\numexpr
\substrcounter@
##1\substrcounter@\substrcounter@a{+1\substrcounter@}%
#1\substrcounter@a\@gobbletwo
\relax
}%
}
\begingroup
\long\xdef\substrcounter#1%
{%
\unexpanded\expandafter
{\csname ! Error: uninitialised \string\substrcounter.\endcsname}%
}
\endgroup
\makeatother
\newcounter{algn}
\newenvironment{newtab}[1]{%
\setupsubstrcounter{-}%
\begin{tabular}{|*{\substrcounter{#1}}{c}|}
}%
{\end{tabular}}
\begin{document}
\begin{tabular}{|*{4}{c}|}
\hline
& & & \\
\hline
\end{tabular}
\begin{newtab}{----}
\hline
& & & \\
\hline
\end{newtab}
\end{document}
```
Answer #2
samcarter
Instead of reinventing the wheel, I suggest a new column type `-`:
```
\documentclass{article}
\usepackage{array}
\newcolumntype{-}{c}
\begin{document}
\begin{tabular}{----}
\hline
1 & 2 & 3 & 4 \\
\hline
\end{tabular}
\end{document}
```
Answer #3
Skillmon
Your problem is that you're using `\CountSubStr` as though it was expandable while it really isn't (since `\seq_set_split:Nnn` isn't). You can instead change the way you set your counter:
```tex
\NewDocumentCommand{\SetCounterToSubStrCount}{ m m m }{
\group_begin:
\seq_set_split:Nnn \l_tmpa_seq { #2 } { #3 }
\exp_args:NNnx
\group_end:
\setcounter { #1 } { \int_eval:n { \seq_count:N \l_tmpa_seq - 1 } }
}
```
Note that I keep the `\l_tmpa_seq` usage local by putting it in a group and using `\exp_args:NNnx` to expand the `\seq_count:N` before closing the group.
Complete code:
```tex
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\myrepeat}{O{}mm}
{
\int_compare:nT { #2 > 0 }
{
#3 \prg_replicate:nn { #2 - 1 } { #1#3 }
}
}
\NewDocumentCommand{\SetCounterToSubStrCount}{ m m m }{
\group_begin:
\seq_set_split:Nnn \l_tmpa_seq { #2 } { #3 }
\exp_args:NNnx
\group_end:
\setcounter { #1 } { \int_eval:n { \seq_count:N \l_tmpa_seq - 1 } }
}
\ExplSyntaxOff
\newcounter{algn}
\newenvironment{newtab}[1]{%
\SetCounterToSubStrCount{algn}{-}{#1}%
\begin{tabular}{|\myrepeat{\value{algn}}{c}|}
}%
{\end{tabular}}
\begin{document}
\begin{tabular}{|\myrepeat{4}{c}|}
\hline
& & & \\
\hline
\end{tabular}
\begin{newtab}{----}
\hline
& & & \\
\hline
\end{newtab}
\end{document}
```
One should also use `\value{<counter>}` instead of `\the<counter>` to access the value of a counter, since `\the<counter>` is for formatted output.
Answer #4
joulev
If I understand your question, a simple `regex` will do the replacing, literally.
```
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__yourmodule_tmp_tl % It is always better to declare for your own module
\NewDocumentEnvironment {newtab} {m}
{
\tl_set:Nn \l__yourmodule_tmp_tl {#1}
\regex_replace_all:nnN {-} {c} \l__yourmodule_tmp_tl
\begin{tabular} { \l__yourmodule_tmp_tl } }
{ \end{tabular} }
\ExplSyntaxOff
\begin{document}
\begin{newtab}{----}
1 & 2 & 3 & 4\\
\end{newtab}
\end{document}
```
Not sure if I am right, but I have always thought combining LaTeX2e commands with expl3 is not a good practice.