# Sorting items according to tags

what I basically want is writing a single list, e.g. itemize, tagging each item with one or more tags and then generating an output that creates multiple lists based on the tags, i.e. each tag should be a section or something:

\documentclass{article}
\usepackage{pgffor}
\usepackage{xstring}
\usepackage{environ}

\usepackage{filecontents}
\begin{filecontents*}{foo.tex}
\begin{pro}{Geometry}
Find the area of ...
\end{pro}

\begin{pro}{Trigonometry}
The angle ...
\end{pro}

\begin{pro}{Algebra}
Prove that $x^2+1=0$ has no real solution.
\end{pro}

\begin{pro}{Geometry}
\end{pro}
\end{filecontents*}

\NewEnviron{pro}[1]{%
\IfStrEq{#1}{\CurrentSubject}{\item \BODY}{}
}%

\newcommand*{\CurrentSubject}{}%

\begin{document}
\foreach \Title in {Algebra, Geometry, Trigonometry} {%
\renewcommand*{\CurrentSubject}{\Title}%
\section*{\CurrentSubject}
\begin{enumerate}
\input{foo}
\end{enumerate}
}%
\end{document}


But this appears not to be appropriate, can only use one tag per item.

Is there something that does this. I already thought about implementing my own package but I am not familiar with tex programming.

Update

I found a way to modify the posted code to achieve sorting with respect to multiple tags:

\documentclass{article}
\usepackage{pgffor}
\usepackage{xstring}
\usepackage{environ}

\usepackage{filecontents}
\begin{filecontents*}{foo.tex}
\begin{pro}{Geometry}{}{}{}{}
Find the area of ...
\end{pro}

\begin{pro}{Trigonometry}{}{}{}{}
The angle ...
\end{pro}

\begin{pro}{Algebra}{Trigonometry}{}{}{}
Prove that $x^2+1=0$ has no real solution.
\end{pro}

\begin{pro}{Geometry}{Algebra}{}{}{}
\end{pro}
\end{filecontents*}

\NewEnviron{pro}[5]{%
\IfStrEq{#1}{\CurrentSubject}{\item \BODY}{}
\IfStrEq{#2}{\CurrentSubject}{\item \BODY}{}
\IfStrEq{#3}{\CurrentSubject}{\item \BODY}{}
\IfStrEq{#4}{\CurrentSubject}{\item \BODY}{}
\IfStrEq{#5}{\CurrentSubject}{\item \BODY}{}
}%

\newcommand*{\CurrentSubject}{}%

\begin{document}
\foreach \Title in {Algebra, Geometry, Trigonometry} {%
\renewcommand*{\CurrentSubject}{\Title}%
\section*{\CurrentSubject}
\begin{enumerate}
\input{foo}
\end{enumerate}
}%
\end{document}


So, specifying a number of tags you want to use in advance. This works but is unhandy - would be great if somebody knows how to make this dynamic.

If somebody wants to use or contribute: https://github.com/maalaria/kite

• Welcome to TeX.SX! Have you checked out the tagging package on CTAN? – TeXnician Jun 29 '17 at 12:55
• Otherwise using the glossaries package with a multilevel glossary style might do what you want. – Timm Jun 29 '17 at 13:21
• Thank you for the recommendations! I case you can provide me with a MWE to produce the above example I am very thankful since I am not familiar with these packages. – maalaria Jun 29 '17 at 13:29
• You should realize that anything which uses tags (counters, environments, labels) are actually creating macros using \csname \endcsname (\c@page, \endminipage, \r@label). – John Kormylo Jun 29 '17 at 14:50
• On first sight don't see how the suggested packages can be used to achieve what I want. To specify: the original list in which items are tagged should not be compiled as such but rather be processed to generate individual lists according to the tags. Basically what the posted code does but with a modification to enable multiple tags per item. – maalaria Jun 29 '17 at 19:12

The following example provides the pro environment to take a single mandatory argument that can contain a comma-separated list of tags. For each tag, the environment \BODY is stored in a macro <tag>@<num>, which is then printable in sequence via \printlist{<tag>}.

\documentclass{article}

\usepackage{pgffor,environ}

\usepackage{filecontents}
\begin{filecontents*}{foo.tex}
\begin{pro}{Geometry}
Find the area of \ldots
\end{pro}

\begin{pro}{Trigonometry}
The angle \ldots
\end{pro}

\begin{pro}{Algebra,Trigonometry}
Prove that $x^2 + 1 = 0$ has no real solution.
\end{pro}

\begin{pro}{Geometry,Algebra}
\end{pro}
\end{filecontents*}

\makeatletter
\NewEnviron{pro}[1]{%
\foreach \Title in {#1} {%
\expandafter\ifcsname c@\Title\endcsname\else% If a counter doesn't exist...
\newcounter{\Title}%                         ... create it
\fi
\stepcounter{\Title}% Another element should be added to particular list
\edef\x{% Add element to particular list
\noexpand\expandafter\noexpand\protected@xdef
\noexpand\csname \Title @\csname the\Title\endcsname\noexpand\endcsname{\BODY}}\x

}
}
\makeatother

\newcommand{\processfile}[1]{\input{#1}}

\newcommand{\printlist}[2][itemize]{%
\expandafter\let\expandafter\listend\csname the#2\endcsname
\begin{#1}
\foreach \curitem in {1,...,\listend} {
\item \expandafter\csname #2@\curitem\endcsname
}
\end{#1}
}

\begin{document}

\processfile{foo}% Process file with pro environments

Algebra:

\printlist{Algebra}

Geometry:

\printlist{Geometry}

Trigonometry:

\printlist{Trigonometry}

\end{document}


Processing of the file is done using \processfile{<file>}.

No error checking is done to see whether the <tag> exists with a call to \processlist{<tag>}, but could be added.

• Little issue: it seems that one cannot use font styles like italic or bold in this implementation. Why is that? – maalaria Jul 18 '17 at 7:49
• @maalaria: Try with this version. I defined \proit and \probf to be \noexpand\textit and \noexpand\textbf to avoid expansion during collection of the pro environment \BODY. – Werner Jul 18 '17 at 15:39