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}
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.
\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.
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}
Note: Please bear me, I am a expl3
newbie ;-)
Here's an output with replicated sequences, all entered to the numberedEnviron
environment: