7

I want to create a bullet list from a string with delimiters in it.

The delimiter in my example is |

Example string:

This is|A bullet|List from|A string

I want to get that to become a bulletlist like this:

  • This is
  • A bullet
  • List from
  • A string

What do I need to do this? Some extra packages or?

I can use any delimiter but , since the string comes from a CSV file that gets parsed with csvsimple if that makes it easier.

MWE (after suggestions in answer):

\documentclass{scrreprt}
\usepackage{csvsimple}
\usepackage{etoolbox}
  \csvreader[head to column names]{content/usecases.csv}{}{%
    \begin{table}
      \begin{tabular}{|l|l|}
        \hline
        Name             & \ucname \\ \hline
        Pre conditions   & 
          \begin{itemize}
            \renewcommand*{\do}[1]{\item #1}%
            \ListParser{\preconditions} %
          \end{itemize} \\ \hline
      \end{tabular}
    \end{table}
  }
\end{document}

CSV Example:

ucname,precondition
test,This is|A test
test2,Barely
test3,No List
test4,List|Again|Here

Follow-up posted here: Auto generate list-items within table from string with delimiter

9
  • Welcome to TeX.SX! Please help us to help you and add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{...} and ending with \end{document}.
    – user31729
    Aug 12 '14 at 21:51
  • Related: How to iterate over a comma separated list?
    – Werner
    Aug 12 '14 at 22:20
  • Note that in your instance (the MWE), you need to probably use \expandafter\ListParser\expandafter{\precondition}.
    – Werner
    Aug 12 '14 at 22:24
  • I assume that you can't have an itemize environment inside a tabular environment cell without providing a \parbox around it
    – user31729
    Aug 12 '14 at 22:27
  • @ChristianHupfer - That resolved some of it, however I still get some \do undefined. }. It is not all of the entries in my CSV that actually generates an output with multiple items for a list. Will add CSV example in a sec. Aug 12 '14 at 22:29
6

You can define you own list parser using the etoolbox package:

enter image description here

Notes:

  • You can have commas in the list elements, and still use a comma as a separator by applying an additional grouping as illustrated in the second MWE below.

Code: Using | as a separator

\documentclass{article}
\usepackage{etoolbox}

\DeclareListParser{\MyListParser}{|}

\begin{document}
\begin{itemize}
    \renewcommand*{\do}[1]{\item #1}%
    \MyListParser{This, has a comma in it|A bullet, and also a comma|List from|A string}%
\end{itemize}
\end{document}

Code: Using , as a separator

\documentclass{article}
\usepackage{etoolbox}

\DeclareListParser{\MyListParser}{,}

\begin{document}
\begin{itemize}
    \renewcommand*{\do}[1]{\item #1}%
    \MyListParser{{This, has a comma in it},{A bullet, and also a comma},{List from},{A string}}%
\end{itemize}
5
  • Hmm, I get a bunch of errors thrown at me.. I get some \do undefined. } and some Something's wrong--perhaps a missing \item. }. I only get the last errors when using it inside a table environment inside the csvreader. Any wise words? Aug 12 '14 at 22:15
  • @FrederikNielsen: I thought the question was about a list, not a _table? I'd recommend you either update the question with a test case, or perhaps ask a separate question. Aug 12 '14 at 22:23
  • Well, it is a combination of a list inside a table. The question has been updated with more info Aug 12 '14 at 22:32
  • How would I use ^^J as my separator? Jan 3 '17 at 8:14
  • @macmadness86: I think it needs to be a single character. I'd recommend you post a new question and include a refernece this one as it is related. Jan 3 '17 at 8:21
2

Here's an approach with xparse and expl3. The command \parselist has an optional argument (the delimiter, default |) and two mandatory ones

  1. the column name or, in general, the control sequence containing the delimited data and

  2. the code to be executed, where #1 stands for the current item (after splitting).

In the example below, the marker is ##1 because \parselist is in the argument to \csvreader.

\documentclass{scrreprt}
\usepackage{csvsimple,array}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\parselist}{O{|}mm}
 {% #1 is the delimiter, #2 is the column name, #3 is the code to use
  \nielsen_parselist:nnn { #1 } { #2 } { #3 }
 }

\seq_new:N \l__nielsen_data_seq

\cs_new_protected:Npn \nielsen_parselist:nnn #1 #2 #3
 {
  \seq_set_split:Nnf \l__nielsen_data_seq { #1 } { #2 }
  \seq_map_inline:Nn \l__nielsen_data_seq { #3 }
 }

\cs_generate_variant:Nn \seq_set_split:Nnn { Nnf }
\ExplSyntaxOff

\begin{document}

\csvreader[head to column names]{\jobname.csv}{}{%
  \begin{table}
  \centering
  \begin{tabular}{|l|l|}
  \hline
  Name             & \ucname \\ \hline
  Pre conditions   &
    \begin{minipage}[t]{.3\textwidth}
    \begin{itemize}
    \parselist{\preconditions}{\item ##1}
    \vspace{\smallskipamount}
    \end{itemize}
    \end{minipage} \\
  \hline
  \end{tabular}
  \end{table}
}
\end{document}

enter image description here

2
  • Why the f in \seq_set_split:Nnf? I still don't understand where should one use f vs. x
    – Manuel
    Aug 14 '14 at 16:34
  • @Manuel It wasn't sufficient to expand \preconditions once, because it's defined to another internal macro of csvsimple; I preferred f expansion, because x expansion might give wrong results depending on the data in the CSV file (it might contain “dangerous” macros such as accented characters).
    – egreg
    Aug 14 '14 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.