You can use \@tfor
. I provide also a better redefinition of the dot under according to your wish:
\documentclass{article}
\usepackage{graphicx}
\let\d\relax
\DeclareRobustCommand{\d}[1]{%
\oalign{#1\cr\hidewidth\scalebox{0.5}{\textbullet}\hidewidth\cr}%
}
\makeatletter
\newcommand{\ds}[1]{%
\@tfor\next:=#1\do{\d{\next}}%
}
\makeatother
\begin{document}
x\d{d}\d{s}\d{a}x
x\ds{dsa}x
\end{document}

What does \@tfor
do? Its syntax is
\@tfor<scratch macro>:=<tokens>\do{<code>}
The scratch macro is traditionally \next
, but it can be anything. The <tokens>
part is any (brace balanced) list of tokens. In the loop, LaTeX essentially does \def<scratch macro>{<next token>}
, so
\@tfor\next:=dsa\do{\d{\next}}
will perform
\def\next{d}\d{\next}\def\next{s}\d{\next}\def\next{a}\d{\next}
However, with \@tfor\next:=d {sa}\do{\d{\next}}
we will just obtain
\def\next{d}\d{\next}\def\next{sa}\d{\next}
Explicit space tokens are ignored and braced groups of tokens are treated as one.
The expl3
analog is \tl_map_inline:nn
:
\documentclass{article}
\usepackage{xparse}
\usepackage{graphicx}
\let\d\relax
\DeclareRobustCommand{\d}[1]{%
\oalign{#1\cr\hidewidth\scalebox{0.5}{\textbullet}\hidewidth\cr}%
}
\ExplSyntaxOn
\NewDocumentCommand{\ds}{m}
{
\tl_map_inline:n { #1 } { \d { ##1 } }
}
\ExplSyntaxOff
\begin{document}
x\d{d}\d{s}\d{a}x
x\ds{dsa}x
x\ds{d sa{bc}}x
\end{document}
No scratch macro is used: the current item in the loop is denoted by #1
(which becomes ##1
in the body of a definition, as usual).
In this particular case where just a single command is applied with the current item as argument, one can use \tl_map_function:nN
:
\NewDocumentCommand{\ds}{m}
{
\tl_map_function:n { #1 } \d
}
which has the same effect and is shorter. It can also appear in a full expansion context (not for this particular case, because of \d
).

\d
should do? Is this for LaTeX or Plain?\d{}
uses Latex maths inside it, if that matters).\d
definition?\renewcommand{\d}[1]{$\underaccent{\scalebox{0.5}{\textbullet}}{\textrm{#1}}$}