How to make a command to automate creation of prime factorization-like products?

My attempt with expl3 using l3regex:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\replaceproduct
  { 
    O { i }
    m
    O { \cdots }
    m
  }
  {
    \seq_set_from_clist:Nn \l_tmpa_seq { #4 }
    \seq_map_inline:Nn \l_tmpa_seq
      {
        \tl_set:Nn \l_tmpa_tl { #2 }
        \tl_if_blank:nTF { ##1 }
        { #3 }
        {
          \regex_replace_all:nnN { #1 } { \cB\{ ##1 \cE\} } \l_tmpa_tl
          \tl_use:N \l_tmpa_tl
        }
      }
  }
\ExplSyntaxOff

\begin{document}

\(\replaceproduct{p_i^{\epsilon_i}}{1,2,3,{},n}\)

\end{document}

I used a slightly different syntax than the one you asked. Since there wont be too many terms (I guess), then I preferred to make it like:

\replaceproduct[<what-to-replace>]{<where-to-replace>}[<empty-item>]{<list-of-things>}

the optional arguments default to i and \cdots, respectively. Your can be typeset with:

\( \replaceproduct{p_i^{\epsilon_i}}{1,2,3,{},n} \)

The macro will iterate through the <list-of-things> and will replace every occurrence of <what-to-replace> found in <where-to-replace> by one item of the <list-of-things>. If it finds a {}, it uses <empty-item> instead.


Edit:

With the syntax you asked:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand\replaceproduct
  { 
    O { i }
    m
    m
    O { \cdots }
    m
  }
  {
    \int_zero:N \l_tmpa_int
    \seq_set_from_clist:Nn \l_tmpa_seq { #5 }
    \int_do_until:nNnn { \l_tmpa_int } = { #3 }
      {
        \int_incr:N \l_tmpa_int
        \tl_set:Nn \l_tmpa_tl { #2 }
        \regex_replace_all:nnN { #1 } { \cB\{ \c { \int_use:N } \c { \l_tmpa_int } \cE\} } \l_tmpa_tl
        \tl_use:N \l_tmpa_tl
      }
      #4
      \tl_set:Nn \l_tmpa_tl { #2 }
      \regex_replace_all:nnN { #1 } { \cB\{ #5 \cE\} } \l_tmpa_tl
      \tl_use:N \l_tmpa_tl
  }
\ExplSyntaxOff

\begin{document}

\( \replaceproduct{p_i^{\epsilon_i}}{3}{n} \)

\end{document}

Use with:

\replaceproduct[<what-to-replace>]{<where-to-replace>}{<from-one-to->}[<dots-thingy>]{<last-item>}

This should do it:

\newcommand{\replaceproduct}[4]{%
    \saveexploremode%
    \exploregroups%
    \foreach \i in {1,...,#2}{\StrSubstitute{#1}{#3}{\i}} \ldots \StrSubstitute{#1}{#3}{#4}%
    \restoreexploremode%
}

You'll have to use the pgffor and the xstring package in order for this to work

Use-example:

\replaceproduct{p_i^{\epsilon_z}}{5}{z}{n}

The first argument is the general term followed by the amount of repetitions, followed by the index-placeholder (must be a unique character sequence inside the general term) and finally followed by the final index.


A couple of interesting expl3 tricks:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\replaceproduct}{mmmm}
 {% #1 = main terms
  % #2 = exponent
  % #3 = first terms
  % #4 = last term
  \int_step_inline:nn { #3 } { #1\sb{##1}^{#2\sb{##1}} }
  \cdots
  #1\sb{#4}^{#2\sb{#4}}
 }
\NewDocumentCommand{\rp}{O{i}mmm}
 {% #1 = item to substitute
  % #2 = main terms
  % #3 = first terms
  % #4 = last term
  \group_begin:
  \tl_set:Nn \l__cid_rp_term_tl { #2 }
  \regex_replace_all:nnN { #1 } { \cB\{\cP\#1\cE\} } \l__cid_rp_term_tl
  \cs_set:NV \__cid_rp_term:n \l__cid_rp_term_tl
  \int_step_function:nN { #3 } \__cid_rp_term:n
  \cdots
  \__cid_rp_term:n { #4 }
  \group_end:
 }
\tl_new:N \l__cid_rp_term_tl
\cs_generate_variant:Nn \cs_set:Nn { NV }
\ExplSyntaxOff

\begin{document}

\begin{gather}
N = \replaceproduct{p}{\varepsilon}{3}{m} = \replaceproduct{q}{\eta}{3}{n}
\\
N = \rp{p_i^{\varepsilon_i}}{3}{m} = \rp[j]{q_j^{\eta_j}}{3}{m}
\end{gather}

\end{document}

I find the first macro easier to type. In the second macro, the optional argument is the dummy variable to substitute, the second instance uses j just by way of example.

enter image description here

How does the second macro work? The regular expression part changes the dummy variable into #1; the token list is then passed as the replacement text for \__cid_rp_term:n, which in turn is used for \int_step_function:nN, which will do the cases from 1 up to what's stated in the second argument. Then \cdots and the last case.

Tags:

Macros