2

I am trying to iterate through a list of data. The data has sections mixed between the items.

When a section appears, I need to typeset it with \section, then I need to create a itemize environment to hold the next set of items. However, that is where things break. For some reason, I can't create the environment in the middle of the compilation of the list. I tried with \begin{itemize} and \end{itemize}, as well with \itemize and \enditemize. But I get errors regarding the items.

\documentclass{article}
\usepackage{pgffor,pgfkeys}

\def\myenvir{document}
\pgfkeys{/test/.cd,
  section/.code = {%
    \def\tempa{document}% if current_environment=document
    \ifx\tempa\myenvir%
      \section{#1}\gdef\myenvir{itemize}\itemize%
    \else%
      \enditemize\section{#1}\itemize%
    \fi%
  },
  question/.code = {%
    \item #1
  },
  style/.estyle={#1}
}

\def\questions{
  section = section 1,
  question=question 1,
  question=question 2,
  section = section 2,
  question=question 1,
  question=question 2,
  section = section 3
}

\pagestyle{empty}
\begin{document}

%\itemize
\foreach \x in \questions {\pgfkeys{/test/.cd,style/.expanded=\x}}
\enditemize

\end{document}

What is the correct way of approaching this? I thought that I can close and open the environments any time, but it seems that is not possible. Also, is there a way to check if the next item is a section and then close it then? But probably that will lead to the same problem of not having the opening and closing explicitly.

adn
  • 11,233
  • This seems related: http://tex.stackexchange.com/questions/237551/indent-text-without-using-trivlist, in terms of starting sections in the middle of a list. – Steven B. Segletes Apr 08 '15 at 19:46
  • Can you elaborate? I can't see the relation, I am new to exploring these complexities of LaTeX. – adn Apr 08 '15 at 21:14
  • If you see no connection, then I'm sure there is none. It just seemed to me that, from your description, you were creating sections in the midst of an itemize environment (which is what the cited question gave as an example). But as I look a little deeper at your code (and I don't pretend to understand pgf), it seems instead that you want to exit the itemize, perform a new section, and re-enter a new itemize. In that case, there probably is no direct connection. – Steven B. Segletes Apr 09 '15 at 00:12
  • Yes, exactly what you said in the latter. – adn Apr 09 '15 at 12:54

1 Answers1

3

It is not a proper answer however I think this is a case of misautomation. The main problem here is that the foreach spins first by creating a group around the foreach code body. Hence each time the group closes and the stack is lost (recovered to its previous state to be unnecessarily precise). The second problem is that you open \begin{itemize} and if nothing else follows before \end{itemize} you will get a missing \item error which would be for the first time in TeX history for the right reason.

For example a code that should not work (but does) : Here I manually hack the foreach body group opening and closing macros to deactivate

\documentclass{article}
\usepackage{pgffor,pgfkeys}
\def\myenvir{document}
\pgfkeys{
  /test/section/.code = {%
    \def\tempa{document}% if current_environment=document
    \ifx\tempa\myenvir%
      \section{#1}\gdef\myenvir{itemize}\begin{itemize}%
    \else%
      \end{itemize}\section{#1}\begin{itemize}%
    \fi%
  },
  /test/question/.code = {\item #1},
}

\def\questions{section = section 1,question=question 1,question=question 2,
  section = section 2,question=question 1,question=question 2,section = section 3
}
\makeatletter
\def\deactgroup{%
\let\pgffor@begingroup=\relax%
\let\pgffor@endgroup=\relax}
\def\reactgroup{%
\let\pgffor@begingroup=\pgffor@default@begingroup%
\let\pgffor@endgroup=\pgffor@default@endgroup%
}
\makeatother
\begin{document}

%Notice that there is no terminating \end{itemize}
\deactgroup%
\foreach\x in \questions{\edef\temp{\noexpand\pgfkeys{/test/\x}}\temp}%\end{itemize}
\reactgroup%

\end{document}

I would suggest that you automate in a different way such that the environment creation is done by the content that key points to. Otherwise you have to hack foreach macros. There is already a very nice one in pgfplots that removes the grouping (and if we add the empty \item):

\documentclass{article}
\usepackage{pgfplots}

\def\myenvir{document}
\pgfkeys{
  /test/section/.code = {%
    \def\tempa{document}% if current_environment=document
    \ifx\tempa\myenvir%
      \section{#1}\gdef\myenvir{itemize}\begin{itemize}%
    \else%
      \end{itemize}\section{#1}\begin{itemize}%
    \fi%
  },
  /test/question/.code = {\item #1},
}

\begin{document}
\pgfplotsforeachungrouped\x in{  
  section = section 1,
  question=question 1,
  question=question 2,
  section = section 2,
  question=question 1,
  question=question 2,
  section = section 3
}{\edef\temp{\noexpand\pgfkeys{/test/\x}}\temp}
\item{}
\end{itemize}

\end{document}

which works pretty OK. But then it has its own limitations of less flexible argument parsing etc.

percusse
  • 157,807