遍历 LaTeX 中的字符/字符串数组

Posted

技术标签:

【中文标题】遍历 LaTeX 中的字符/字符串数组【英文标题】:Iterating through a character/string array in LaTeX 【发布时间】:2015-09-09 14:38:53 【问题描述】:

这是我之前发布的问题 (Outputting character string elements neatly in Sweave in R) 的延续。我有一个字符串数组,并试图将每个元素输出到 LaTeX 中。我可以使用以下代码来实现:

\documentclass[12pt,english,nohyper]tufte-handout
\usepackage[T1]fontenc
\usepackage[utf8]inputenc
\usepackagelongtable
\usepackagewrapfig
\usepackaagehyperref
\usepackagegraphicx
\usepackage[space]grffile
\usepackagegeometry
\usepackageenumitem
\usepackagepgffor

\makeatletter
\makeatother

\begindocument

<<include=FALSE>>=
library(ggplot2)
library(reshape2)
library(xtable)
@

\centerline\Large\bf This is a test
\vspace1cm

\noindent
My List:
\vspace2mm

.

<<echo=FALSE,results='asis'>>=
myList = c("A. This is the first item in my list.", "B. This is the second item in my list, and it will span across two lines because it is so long. This is the second item in my list, and it will span across two lines because it is so long.", "C. This is the third item in my list")
@

\beginenumerate[label=\Alph*., itemsep=-1ex]
  \item \Sexprstr_trim(unlist(strsplit(chapter_outcomes[1], "[.]"))[2])
  \item \Sexprstr_trim(unlist(strsplit(chapter_outcomes[2], "[.]"))[2])
  \item \Sexprstr_trim(unlist(strsplit(chapter_outcomes[3], "[.]"))[2])
\endenumerate

\enddocument

这为我提供了我希望实现的正确输出:

然而,我现在正试图让这个迭代发生在一个 for 循环中,因为我的 chapter_outcomes 字符串数组中可能并不总是正好有三个元素。我尝试了以下变体:

\beginenumerate[label=\Alph*., itemsep=-1ex]
  \foreach \i in \Sexprlength(chapter_outcomes) 
  \item \Sexprstr_trim(unlist(strsplit(chapter_outcomes[\i], "[.]"))[2])
  
\endenumerate

但是,这会在上面的 chapter_outcomes[\i] 语法中导致“意外输入”错误。

我曾尝试查看类似的帖子(Iteration in LaTeX、http://www.bytemining.com/2010/04/some-latex-gems-part-1-tikz-loops-and-more/),但它们的重点不同,我无法在这里解决我的问题。

感谢您的建议。

【问题讨论】:

你试过tex.stackexchange吗? 谢谢,我刚刚在那儿发帖。 【参考方案1】:

我手边没有Latex,也好久没弄了,但是:

1) \foreach 不需要范围吗?如果我正确理解您的代码,\Sexpr 只计算长度(例如 6),而 \foreach 应该有 1..6

2) 另一个典型错误是运行 0..[length-1] 而不是 1..[length] 的索引,这可能导致“意外输入”,因为解释器试图移过最后一个元素.

【讨论】:

【参考方案2】:

听起来你应该看看 expl3。我不使用 R/Sweave,但这里有一个示例应该可以帮助您。

\documentclassarticle
\usepackagexparse,enumitem

\ExplSyntaxOn

\cs_new_protected:Nn \lanner_sweave_wrap:n
   \item \Sexpr  str_trim(unlist(strsplit(#1, "[.]"))[2])  

\cs_new_protected:Nn \lanner_sweave_enumlist:nn
  
    \beginenumerate[#2]
      \seq_set_split:Nnn \l_tmpa_seq  ;;;   #1 
      \seq_map:NN \l_tmpa_seq \lanner_sweave_wrap:n
    \endenumerate
  
\cs_generate_variant:Nn \lanner_sweave_enumlist:nn  f 

\NewDocumentCommand \EnumerateIt  Olabel=\Alph*., itemsep=-1ex m 
   \lanner_sweave_enumlist:fn #1 #2 

\ExplSyntaxOff

\begindocument

<<echo=FALSE,results='asis'>>=
myList = c("A. This is the first item in my list.", "B. This is the second item in my list, and it will span across two lines because it is so long. This is the second item in my list, and it will span across two lines because it is so long.", "C. This is the third item in my list")
@

\EnumerateIt\Sexprjoin(myList,";;;") % join myList with ";;;" -- I don't know the exact syntax

\enddocument

当然,这可以用纯expl3来完成:

\documentclassarticle
\usepackagexparse,enumitem

\ExplSyntaxOn

\tl_new:N \l_lanner_tmp_tl
\seq_new:N \l_lanner_tmp_seq
\cs_new_protected:Nn \lanner_sweave_enumlist:nn
  
    \beginenumerate[#2]
      \tl_map_inline:nn #1
        
          \seq_set_split:Nnn \l_lanner_tmp_seq  .~  ##1
          \seq_pop_left:NN \l_lanner_tmp_seq \l_lanner_tmp_tl

          \tl_set:Nf \l_lanner_tmp_tl
             \seq_use:Nn \l_lanner_tmp_seq  .~  

          \tl_trim_spaces:N \l_lanner_tmp_tl

          \item \l_lanner_tmp_tl
        
    \endenumerate
  
\cs_generate_variant:Nn \lanner_sweave_enumlist:nn  f 

\NewDocumentCommand \EnumerateIt  Olabel=\Alph*., itemsep=-1ex > \SplitList  ;;   m 
  
    \tl_show:n#2
    \lanner_sweave_enumlist:fn #2 #1 

\ExplSyntaxOff

\begindocument

\EnumerateIt
  A. This is the first item in my list. ;;
  B. This is the second item in my list, and it will span across two lines because it is so long,
     This is the second item in my list, and it will span across two lines because it is so long. ;;
  C. This is the third item in my list

\enddocument

【讨论】:

以上是关于遍历 LaTeX 中的字符/字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

遍历Java中的字符串数组

循环遍历 Bash 中的字符串数组?

如何遍历数组中的多个字符串

Ruby - 遍历数组中的每个字符串并删除重复的字符

如何遍历数组中的数组?

循环遍历数组并附加到objective-C中的字符串