2

I am trying to automate the following layout to place images and tables using the minipage environment. The width of the minipage environment is calculated automatically, and the design is almost automatic, output looks like this:

current-output

With the following code (MWE):

\documentclass{article}
\usepackage{graphicx}
% Conter and style
\newcounter{ctr}
\renewcommand\thectr{(\Alph{ctr})}
% Macro to put * on the left, no need scope (used in other parts)
\newcommand{\fake}{\par\hspace*{-\labelsep}\makebox[0pt][r]{\makebox[\labelwidth][r]{\textasteriskcentered}}\hskip\labelsep}

\ExplSyntaxOn \tl_new:N \l_myenv_label_below_tl \tl_set:Nn \l_myenv_label_below_tl { \thectr } % fake label \int_new:N \l_myenv_layout_above_int \int_new:N \l_myenv_layout_below_int \dim_new:N \l_enumext_mini_page_width_dim \dim_new:N \l_enumext_mini_page_width_below_dim \clist_new:N \l_myenv_layout_clist

% Calc width for minipage \cs_new_protected:Npn __myenv_minipage_width:n #1 { \clist_set:Nn \l_myenv_layout_clist {#1} \bool_if:nT { \int_compare_p:n { \clist_count:n {#1} = 1 } } { \int_set:Nn \l_myenv_layout_above_int { \clist_item:Nn \l_myenv_layout_clist {1} } \dim_set:Nn \l_enumext_mini_page_width_dim { \dim_use:c { linewidth } / \l_myenv_layout_above_int } } \bool_if:nT { \int_compare_p:n { \clist_count:n {#1} = 2 } } { \int_set:Nn \l_myenv_layout_above_int { \clist_item:Nn \l_myenv_layout_clist {1} } \dim_set:Nn \l_enumext_mini_page_width_dim { \dim_use:c { linewidth } / \l_myenv_layout_above_int } \int_set:Nn \l_myenv_layout_below_int { \clist_item:Nn \l_myenv_layout_clist {2} } \dim_set:Nn \l_enumext_mini_page_width_below_dim { \dim_use:c { linewidth } / \l_myenv_layout_below_int } % Adjusts the minipage width for the below part, scope \startbelow \NewDocumentCommand\startbelow{} { \dim_set_eq:NN \l_enumext_mini_page_width_dim \l_enumext_mini_page_width_below_dim \par } } }

% Create a environment, #1 = layout [above,below] \NewDocumentEnvironment{picandtables}{ O{5} } { __myenv_minipage_width:n {#1} % Scope \Item[...]{...} \NewDocumentCommand\Item{ s O{} +m } { \refstepcounter{ctr} \noindent \begin{minipage}[b]{ \l_enumext_mini_page_width_dim } \centering ##3% picture or table \par \IfBooleanTF{##1} { ##2 \fake \tl_use:N \l_myenv_label_below_tl }% on left { ##2 \par \tl_use:N \l_myenv_label_below_tl } \end{minipage} \ignorespaces } } { \setcounter{ctr}{0} } \ExplSyntaxOff \begin{document} % Common layout for images or tables \begin{enumerate} \item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables}[3,2] \Item[note]{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.10]{example-image-a}} \Item*{\includegraphics[scale=0.15]{example-image-a}} \startbelow \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables}

\item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables}[2,3] \Item{\includegraphics[scale=0.15]{example-image-a}} \Item[note]{\includegraphics[scale=0.15]{example-image-a}} \startbelow \Item{\includegraphics[scale=0.15]{example-image-a}} \Item*[note]{\includegraphics[scale=0.25]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables}

\item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item[Note]{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables} \end{enumerate} \end{document}

I would like to automate it a little more, at the moment the optional argument of the environment has the value 5, but I don't always have that amount of times the command \Item inside the environment, besides I must place the command \startbelow to divide the above and below part of the layout.

My idea would be to leave the default value of the optional argument equal to the number of times \Item appears (here I don't need just the below), process the environment with the argument +b, count the number of times \Item appears and divide it when the optional argument is present [above, below], that is, don't use \startbelow.

I think the answer given by @egreg on Macro to capture until end-of-line as argument is in line with what I want, but, I don't know if it will be possible.

1 Answers1

2

I define the \Item command to just add the relevant contents to a sequence.

Then, based on the optional argument or, if missing, the number of items, the appropriate number of items is selected by doing a mapping on the list.

So, if the optional argument is [2,3], first the available width is divided by two and two items from the sequence are typeset in a minipage of the chosen size; then other three items, after dividing the available width by three.

The last example uses twelve items.

\documentclass{article}
\usepackage[top=1cm,bottom=2cm]{geometry} % smaller picture
\usepackage{graphicx}

\ExplSyntaxOn

\NewDocumentCommand{\Item}{som} { \seq_put_right:Nn \l_pablo_pictab_body_seq { __pablo_pictab_item:nnn { #1 } { #2 } { #3 } } }

\NewDocumentEnvironment{picandtables}{o} { \par \centering } { \IfNoValueTF { #1 } { \pablo_pictab_do:e { \seq_count:N \l_pablo_pictab_body_seq } } { \pablo_pictab_do:n { #1 } } \par }

\seq_new:N \l_pablo_pictab_body_seq \dim_new:N \l_pablo_pictab_width_dim \int_new:N \l_pablo_pictab_label_int \int_new:N \l_pablo_pictab_counta_int \int_new:N \l_pablo_pictab_countb_int

\cs_new_protected:Nn \pablo_pictab_do:n { \clist_map_function:nN { #1 } __pablo_pictab_row:n } \cs_generate_variant:Nn \pablo_pictab_do:n { e }

\cs_new_protected:Nn __pablo_pictab_row:n { \dim_set:Nn \l_pablo_pictab_width_dim { \linewidth/#1 } \int_set:Nn \l_pablo_pictab_counta_int { \l_pablo_pictab_countb_int } \int_set:Nn \l_pablo_pictab_countb_int { \l_pablo_pictab_counta_int + #1 } \int_step_inline:nnn { \l_pablo_pictab_counta_int + 1 } { \l_pablo_pictab_countb_int } { \int_incr:N \l_pablo_pictab_label_int \begin{minipage}[b]{\l_pablo_pictab_width_dim} \centering \seq_item:Nn \l_pablo_pictab_body_seq { ##1 } \end{minipage} } \par }

\cs_new_protected:Nn __pablo_pictab_item:nnn { #3 \ \tl_if_novalue:nF { #2 } { #2 \ } \bool_if:nT { #1 } { \makebox[0pt][r]{\textasteriskcentered\space} } (\int_to_Alph:n { \l_pablo_pictab_label_int }) }

\ExplSyntaxOff \begin{document} % Common layout for images or tables \begin{enumerate} \item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables}[3,2] \Item[note]{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.10]{example-image-a}} \Item*{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables}

\item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables}[2,3] \Item{\includegraphics[scale=0.15]{example-image-a}} \Item[note]{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item*[note]{\includegraphics[scale=0.25]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables}

\item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item[Note]{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables}

\item Type of questions (these need manual tuning for alternatives, usually carrying pictures or tables)

\begin{picandtables} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item*{\includegraphics[scale=0.15]{example-image-a}} \Item[Note]{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables} \end{enumerate}

\clearpage

\begin{picandtables}[3,4,2,3] \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \Item{\includegraphics[scale=0.15]{example-image-a}} \end{picandtables}

\end{document}

enter image description here

enter image description here

egreg
  • 1,121,712
  • Wow...it's exactly as I saw it in my mind, but, much simpler :) except for the position of * in 2. (D) where the output should be * (D). You can explain ...variant:Nn .. { e } and why the center environment adds an unwanted line to me? – Pablo González L Jan 05 '21 at 19:12
  • 1
    @PabloGonzálezL I fixed the position of the asterisk and removed center, opting for \centering that doesn't add vertical space. The e variant means that the argument is fully expanded before being passed to the main function. A central concept in expl3. – egreg Jan 05 '21 at 20:36