TransWikia.com

How to process the body of an environment and divide it by a macro?

TeX - LaTeX Asked by Pablo González L on March 22, 2021

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}
renewcommandthectr{(Alph{ctr})}
% Macro to put * on the left, no need scope (used in other parts)
newcommand{fake}{parhspace*{-labelsep}makebox[0pt][r]{makebox[labelwidth][r]{textasteriskcentered}}hskiplabelsep}

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
        NewDocumentCommandstartbelow{}
          {
            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*[...]{...}
    NewDocumentCommandItem{ 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.

One Answer

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]{textasteriskcenteredspace} }
  (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

Correct answer by egreg on March 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP