Prevent xparse from stripping braces?
You can trick this by inserting another token after the opening bracket if there is one (proof of concept like answer). Replace \Wisperwind_Sum_original_code:nnn
with your original code to typeset the sum (including the handling of the optional star with \IfBooleanTF
).
\documentclass[]{article}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \l_Wisperwind_clist
\NewDocumentCommand \Sum { s t[ }
{
\IfBooleanTF { #2 }
{ \Sum_two { #1 } [ \use_none:n {} }
{ \Sum_two { #1 } }
}
\NewDocumentCommand \Sum_two { m O{ \use_none:n {} } m }
{
\Wisperwind_Sum_original_code:non { #1 } { #2 } { #3 }
}
\cs_new:Npn \Wisperwind_Sum_original_code:nnn #1 #2 #3
{
\sum
\clist_set:Nn \l_Wisperwind_clist { #2 }
\int_case:nn { \clist_count:N \l_Wisperwind_clist }
{
{ 1 } { \sb { \clist_item:Nn \l_Wisperwind_clist { \c_one_int } } }
{ 2 }
{
\sb { \clist_item:Nn \l_Wisperwind_clist { \c_one_int } }
\sp { \clist_item:Nn \l_Wisperwind_clist { 2 } }
}
{ 3 }
{
\sb
{
\clist_item:Nn \l_Wisperwind_clist { \c_one_int }
=
\clist_item:Nn \l_Wisperwind_clist { 2 }
}
\sp { \clist_item:Nn \l_Wisperwind_clist { 3 } }
}
}
#3
}
\cs_generate_variant:Nn \Wisperwind_Sum_original_code:nnn { non }
\ExplSyntaxOff
\begin{document}
$\Sum{\ldots}$ % -> \sum \ldots
$\Sum[i]{\ldots}$ % -> \sum_{i} \ldots
$\Sum[i \in I]{\ldots}$ % -> \sum_{i \in I} \ldots
$\Sum[i, 0, N]{\ldots}$ % -> \sum_{i=0}^{N} \ldots
$\Sum[{i,j}, 0, N]{\ldots}$ % -> \sum_{i,j=0}^{N} \ldots
$\Sum[{i,j,k}]{\ldots}$ % -> \sum_{i,j,k} \ldots
\end{document}
Here using LaTeX2e (see below for Plain TeX):
\documentclass{article}
\usepackage{listofitems}
\makeatletter
\newcommand\Sum{\@ifnextchar[{\Sumaux[\@gobble}{\sum}}
\makeatother
\def\Sumaux[#1]#2{
\sum
\setsepchar{,}
\readlist\sumargs{#1}
\ifnum\listlen\sumargs[]>1\relax
_{\sumargs[1]=\sumargs[2]}
\ifnum\listlen\sumargs[]>2\relax^\sumargs[3]\fi
\else
_{\sumargs[1]}
\fi
#2
}
\begin{document}
\[\Sum{\ldots} \]% -> \sum \ldots
\[\Sum[i]{\ldots} \]% -> \sum_{i} \ldots
\[\Sum[i \in I]{\ldots} \]% -> \sum_{i \in I} \ldots
\[\Sum[i, 0, N]{\ldots} \]% -> \sum_{i=0}^{N} \ldots
\[\Sum[{i,j}, 0, N]{\ldots} \]% -> \sum_{i,j=0}^{N} \ldots
\[\Sum[{i,j,k}]{\ldots} \]% -> \sum_{i,j,k} \ldots
\end{document}
This approach can also be implemented in Plain TeX:
\input listofitems
\def\gobble#1{}
\def\Sum{\futurelet\next\doSum}
\def\doSum{\ifx[\next%
\expandafter\Sumaux\expandafter[\expandafter\gobble\else\sum\fi}
\def\Sumaux[#1]#2{
\sum
\setsepchar{,}
\readlist\sumargs{#1}
\ifnum\listlen\sumargs[]>1\relax
_{\sumargs[1]=\sumargs[2]}
\ifnum\listlen\sumargs[]>2\relax^\sumargs[3]\fi
\else
_{\sumargs[1]}
\fi
#2
}
$$\Sum{\dots} $$% -> \sum \ldots
$$\Sum[i]{\ldots} $$% -> \sum_{i} \ldots
$$\Sum[i \in I]{\ldots} $$% -> \sum_{i \in I} \ldots
$$\Sum[i, 0, N]{\ldots} $$% -> \sum_{i=0}^{N} \ldots
$$\Sum[{i,j}, 0, N]{\ldots} $$% -> \sum_{i,j=0}^{N} \ldots
$$\Sum[{i,j,k}]{\ldots} $$% -> \sum_{i,j,k} \ldots
\bye
The brace stripping is quite deliberate as \newcommand
-generated commands requires braces for the case
\foo[{]}]{bar}
whereas xparse
-generated ones do not. Without brace stripping,
\foo[{bar}]
and
\foo[bar]
could be treated differently.
In your case, you have a comma list with one entry. The obvious solution is to provide a second, empty, entry
\Sum[{i,j},]{\ldots}
as this is a no-op.