Environment to stack a word and a number

You need delimited arguments for such things:

\def\nam#1{\nami #1 {} {}}
\def\nami #1 #2 {%
  \if\relax\detokenize{#1}\relax\else
    \stackunder{\uline{#1}}{\tiny{#2}} \expandafter\nami
  \fi
}

Then a call of \nam{foo 1 bar 2 baz 3} would alredy do what you need. Hence, there is no need to have an interface that uses an environment. Here is the complete code:

\documentclass[12pt]{memoir}    
\usepackage{stackengine,ulem}

\def\numberedwords#1{\numberedwordsaux #1 {} {}}
\def\numberedwordsaux #1 #2 {%
  \if\relax\detokenize{#1}\relax\else
    \stackunder{\uline{#1}}{\tiny{#2}} \expandafter\numberedwordsaux
  \fi
}

\begin{document}
\numberedwords{%
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
}
\end{document}

output


Regarding your request to allow blank lines inside the argument of \numberedwords you need a \long definition that grabs every paragraph and applies the processing via \stackunder to them:

\long\def\numberedwords#1{\numberedwordsaux#1\par\nil\par}
\def\numberedwordsaux#1\par{%
  \ifx#1\nil\else
    \numberedwordsprocess{#1}\par\vskip 1em plus 4pt minus 4pt
    \expandafter\numberedwordsaux\fi
}

Note that \numberedwordsprocess now is what \numberedwords was in the original solution and that I put some glue inbetween the paragraphs.

output_long

\documentclass[12pt]{memoir}
\usepackage{stackengine,ulem}

\makeatletter
\long\def\numberedwords#1{%
  \expandafter\numberedwordsaux\trim@pre@space#1\par\nil\par
}
\def\numberedwordsaux#1\par{%
  \ifx#1\nil\else
    \numberedwordsprocess{#1}\par\vskip 1em plus 4pt minus 4pt
    \expandafter\numberedwordsaux\fi
}
\def\numberedwordsprocess#1{\numberedwordsprocessaux #1 {} {}}
\def\numberedwordsprocessaux #1 #2 {%
  \if\relax\detokenize{#1}\relax\else
    \stackunder{\uline{#1}}{\tiny{#2}}
    \expandafter\numberedwordsprocessaux\fi
}
\makeatother

\begin{document}
\numberedwords{%
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18

  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18

  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18 
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
  hello 25 world 35 this 12 would 39 great 92
  environ 21 typesetting 19 exercise 18
}
\end{document}

To use the syntax change that @egreg proposed in his answer in LaTeX2e you can define:

\long\def\numberedwords#1{%
  \expandafter\numberedwordsaux\trim@pre@space#1\par\@nil\par}
\def\numberedwordsaux#1\par{%
  \ifx#1\@nil\else
    \numberedwordsprocess{#1}\par\vskip 1em plus 4pt minus 4pt
    \expandafter\numberedwordsaux\fi
}
\def\numberedwordsprocess#1{\numberedwordsprocessaux #1\@nil| }
\def\numberedwordsprocessaux#1|#2 {%
  \ifx#1\@nil\else
    \stackunder{\uline{#1}}{\tiny{#2}}
    \expandafter\numberedwordsprocessaux\fi
}

and then write \numberedwords{hello|25 ...}. As only the input parsing changed all properties of the final original solution are, of course, preserved.


I'd prefer a different syntax:

\documentclass[12pt]{memoir}

\usepackage{environ,xparse}

\ExplSyntaxOn
\NewEnviron{numberedEnviron}
 {
  \par
  \rama_numbered_environ:V \BODY
  \par
 }

\cs_new_protected:Nn \rama_numbered_environ:n
 {
  \seq_set_split:Nnn \l_rama_numbered_words_seq { ~ } { #1 }
  \seq_map_inline:Nn \l_rama_numbered_words_seq
   {
    \SplitWord{##1}
   }
 }
\cs_generate_variant:Nn \rama_numbered_environ:n { V }

\NewDocumentCommand{\SplitWord}{>{\SplitArgument{1}{|}}m}
 {
  \rama_word_number:nn #1
 }

\cs_new_protected:Nn \rama_word_number:nn
 {
  \group_begin:
  \renewcommand \arraystretch { 0 }
  \begin{tabular}[t]{@{}c@{}}
  \strut #1 \\[1pt] \hline \tiny\strut #2
  \end{tabular}
  \c_space_tl
  \group_end:
 }
\ExplSyntaxOff


\begin{document}

\begin{numberedEnviron}
hello|25 world|35 this|12 would|39 great|92
environ|21 typesetting|19 exercise|18
hello|25 world|35 this|12 would|39 great|92
environ|21 typesetting|19 exercise|18
hello|25 world|35 this|12 would|39 great|92
environ|21 typesetting|19 exercise|18
hello|25 world|35 this|12 would|39 great|92
environ|21 typesetting|19 exercise|18
\end{numberedEnviron}


\end{document}

There's a problem with punctuation, of course.

enter image description here


Not the full solution, but some kind of automatization:

I'll tried with expl3 features to split the input hello 25 etc. for example into items and loop over the items, to provide for \nam{}{}. The input has to be converted first with \Converttolist{} and later \DisplayList{} shows this list according to the \nam definition.

The environment numberedEnvironment uses this automatically by capturing the environment body within \BODY and automatically displaying this.

It's not failsafe:

\documentclass[12pt]{memoir}

\usepackage{stackengine,ulem}
\newcommand{\nam}[2]{\stackunder{\uline{#1}}{\tiny{#2}}}

\usepackage{environ}




\usepackage{xparse}
\usepackage{xstring}
\usepackage{forloop}

\newcounter{loopcounter}
\setcounter{loopcounter}{1}


\ExplSyntaxOn
\NewDocumentCommand{\converttolist}{m}{%
  \clist_clear_new:N \l_mylist
  \clist_gset:Nx{\l_mylist}{#1}
}

\NewDocumentCommand{\getlistitem}{m}{%
  \clist_item:Nn{\l_mylist}{#1}
}

\NewDocumentCommand{\getlistcounter}{m}{%
  \clist_count:N{\l_mylist}
}
\ExplSyntaxOff

\NewDocumentCommand{\ConvertToList}{m}{%
  \edef\mystrcpy{}%
  \StrSubstitute{#1}{ }{,}[\mystrcpy]%
  \converttolist{\mystrcpy}%
}



\NewDocumentCommand{\DisplayList}{m}{%
%  Should be replaced later on with a `expl3` loop!
  \forloop[2]{loopcounter}{1}{\value{loopcounter} < #1}{%
    \nam{\getlistitem{\number\value{loopcounter}}}{\getlistitem{\numexpr\value{loopcounter}+1}} 
  }%
}

\NewEnviron{numberedEnviron}{\ConvertToList{\BODY}\DisplayList{\getlistcounter{}}}

\begin{document}


\def\mynumbers{hello 25 world 35 this 12 would 39 great 92
environ 21 typesetting 19 exercise 18}


\ConvertToList{\mynumbers}
\DisplayList{\getlistcounter{}}


\ConvertToList{This 42 is 45 just 7 another 8 list 1000}
\DisplayList{\getlistcounter{}}

Now with the environment:

\begin{numberedEnviron}
hello 25 world 35 this 12 would 39 great 92
environ 21 typesetting 19 exercise 18
\end{numberedEnviron}


\end{document}

enter image description here

Note: Please bear me, I am a expl3 newbie ;-)

Here's an output with replicated sequences, all entered to the numberedEnviron environment:

enter image description here