要求写一个单词列表,在每个单词下划线,并在下划线处居中放置一个数字。使用该stackengine
包,我准备了以下 MWE。
\documentclass[12pt]{memoir}
\usepackage{stackengine,ulem}
\newcommand{\nam}[2]{\stackunder{\uline{#1}}{\tiny{#2}}}
\begin{document}
\nam{First}{5} \nam{Second}{6} \nam{Third}{5} \nam{Fourth}{6} \nam{Fifth}{5}
\nam{sixth}{5} \nam{Seventh}{7} \nam{Eighth}{6}
\end{document}
我的问题是:
有没有更好的方法可以在一个环境中并排书写单词和数字,而不是\nam{word}{Number}
每次都打字。
界面看起来像
\begin{numberedEnviron}
hello 25 world 35 this 12 would 39 great 92
environ 21 typesetting 19 exercise 18
\end{numberedEnviron}
产生与上述类似的结果。感谢您花时间阅读我的请求并提供帮助。
答案1
对于这样的事情,你需要用分隔符来参数化:
\def\nam#1{\nami #1 {} {}}
\def\nami #1 #2 {%
\if\relax\detokenize{#1}\relax\else
\stackunder{\uline{#1}}{\tiny{#2}} \expandafter\nami
\fi
}
然后调用\nam{foo 1 bar 2 baz 3}
就可以满足您的需要。因此,无需使用环境的接口。以下是完整代码:
\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}
关于您允许在参数中使用空行的请求,\numberedwords
您需要一个\long
抓住每个段落并通过以下方式应用处理的定义\stackunder
:
\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
}
请注意,\numberedwordsprocess
现在是\numberedwords
原始解决方案中的内容,并且我在段落之间放了一些胶水。
\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}
要使用@egreg 在 LaTeX2e 中的回答中提出的语法更改,您可以定义:
\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
}
然后写入\numberedwords{hello|25 ...}
。由于只有输入解析发生了变化,因此最终原始解决方案的所有属性当然都会保留。
答案2
我更喜欢不同的语法:
\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}
当然,标点符号有问题。
答案3
虽然不是完整的解决方案,但具有某种自动化:
我将尝试使用expl3
功能将输入hello 25
等拆分为项目,然后循环遍历项目,以提供\nam{}{}
。首先必须将输入转换为,\Converttolist{}
然后\DisplayList{}
根据\nam
定义显示此列表。
环境numberedEnvironment
通过捕获其中的环境主体\BODY
并自动显示它来自动使用它。
它不是万无一失的:
\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}
注意:请容忍我,我是expl3
新手;-)
这是带有重复序列的输出,全部输入到numberedEnviron
环境中: