6

I got provided with the following code to define a macro for an image composed of any number of subfigures:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{expl3,xparse}
\usepackage{subcaption}
\usepackage{graphicx}

\ExplSyntaxOn
\clist_new:N \l__gerry_mycl
\cs_new:Npn \__gerry_customfiggg:n #1#2#3#4 {
    \includegraphics[width=#1\textwidth]{#2}
% caption produces tex capacity exceeded.
    \caption[#3]{#4}
    \label{fig:#2}
}
\NewDocumentCommand{\multifig}{m}{
\begin{figure}
\clist_set:Nn \l__gerry_mycl {#1}
\clist_map_inline:Nn \l__gerry_mycl {
        \clist_set:Nn \l_tmpa_clist {##1}
        \begin{subfigure}{{\clist_item:Nn \l_tmpa_clist {1}}\textwidth}
        \exp_args:Nx \__gerry_customfiggg:n {0.95}{\clist_item:Nn \l_tmpa_clist {2}}{\clist_item:Nn \l_tmpa_clist {3}\clist_item:Nn \l_tmpa_clist {4}}
        \end{subfigure}
}
\end{figure}
}
\ExplSyntaxOff



\begin{document}

% size, file name, caption, caption
\multifig{{.2, fig_1, small caption 1, big caption 1}, {.1, fig_2, small caption 2, big caption 2}}

\end{document}

(source: Accessing a list at a certain index)

The command \caption[]{} produces the following error:

TeX capacity exceeded, sorry [input stack size=5000].
\caption@ifstrut #1#2->#1

When defining figures explicitly the problem does not appear. I would really like to define the macro though. Is there a way to get it working?

Thank you.

  • 1
    Well, that's probably a problem of expansion. – TeXnician Jun 3 '17 at 10:47
  • I don't understand. Do you mean the line \exp_args:Nx \__gerry_customfiggg:n {0.95}{\clist_item:Nn \l_tmpa_clist {2}}{\clist_item:Nn \l_tmpa_clist {3}\clist_item:Nn \l_tmpa_clist {4}}? – Gerry Jun 3 '17 at 10:49
  • No, the part with the subfigure and it's integer is the first problem, then the part with the \exp_args. – TeXnician Jun 3 '17 at 10:53
  • Why \__gerry_custom_figgg:n and not __gerry_custom_figgg:nnnn, then defining an nxxx` variant? – user31729 Jun 3 '17 at 10:54
  • @TeXnician: The {\clist_item:Nn ... }\textwidth} is wrong, in my opinion, yes – user31729 Jun 3 '17 at 10:58
7

The problem is the {\clist_item:Nn \l_tmpa_clist {1}}\textwidth in my point of view, it does not expand to the correct dimension (multiple).

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}
\usepackage{subcaption}
\usepackage{graphicx}

\ExplSyntaxOn
\clist_new:N \l__gerry_mycl


\cs_new:Nn \__gerry_customfiggg:nnnn {
  \includegraphics[width=#1\textwidth]{#2}
  % caption produces tex capacity exceeded.
  \caption[#3]{#4}
  \label{fig:#2}
}

\NewDocumentCommand{\multifig}{m}{
  \begin{figure}
    \clist_set:Nn \l__gerry_mycl {#1}
    \clist_map_inline:Nn \l__gerry_mycl {
      \clist_set:Nn \l_tmpa_clist {##1}
      \begin{subfigure}{\clist_item:Nn \l_tmpa_clist {1}\textwidth}
        \__gerry_customfiggg:nnnn {0.95}{\clist_item:Nn \l_tmpa_clist {2}}{\clist_item:Nn \l_tmpa_clist {3}}{\clist_item:Nn \l_tmpa_clist {4}}
      \end{subfigure}
    }
  \end{figure}
}
\ExplSyntaxOff



\begin{document}

% size, file name, caption, caption
\multifig{{.2, ente, small caption 1, big caption 1}, {.1, ente1, small caption 2, big caption 2}}

\end{document}

enter image description here

  • Perfect. Thank you. You are completely right to believe that I have no idea about expl3. In my defense, it looks nothing like any language I have ever seen. – Gerry Jun 3 '17 at 11:06
  • @Gerry: Compared to TeX or LaTeX(2e) the syntax of expl3 might look weird at first -- but speaking with Darth Vader: Don't underestimate the Power of Expl3 ;-) – user31729 Jun 3 '17 at 11:10
  • I will update with a solution with respects the naming conventions of expl3 later on – user31729 Jun 3 '17 at 11:11
4

Your internal function should be named differently, as it has four arguments.

Also, \exp_args:Nx will not do what you expect, because it just expands the contents of the first braced group after the next token. Actually, this is not really needed, but I left it just by way of example.

You should define a variant that expands all arguments. By the way, you need no clist variable.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{expl3,xparse}
\usepackage{subcaption}
\usepackage{graphicx}

\ExplSyntaxOn
\cs_new:Npn \__gerry_customfiggg:nnnn #1#2#3#4
 {
    \includegraphics[width=#1\textwidth]{#2}
    \caption[#3]{#4}
    \label{fig:#2}
 }
\cs_generate_variant:Nn \__gerry_customfiggg:nnnn { xxxx }

\NewDocumentCommand{\multifig}{m}
 {
    \begin{figure}
    \clist_map_inline:nn { #1 }
     {
        \begin{subfigure}{\clist_item:nn {##1}{1}\textwidth}
        \__gerry_customfiggg:xxxx % \__gerry_customfiggg:nnnn would do as well
          {0.95}
          {\clist_item:nn {##1}{2}}
          {\clist_item:nn {##1}{3}}
          {\clist_item:nn {##1}{4}}
        \end{subfigure}
}
\end{figure}
}
\ExplSyntaxOff



\begin{document}

% size, file name, caption, caption
\multifig{
  {.2, example-image-a, small caption 1, big caption 1},
  {.1, example-image-b, small caption 2, big caption 2}
}

\end{document}

enter image description here

On the other hand, I'd favor a completely different and much more flexible approach:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{expl3,xparse}
\usepackage{subcaption}
\usepackage{graphicx}

\ExplSyntaxOn
\keys_define:nn { gerry/multifig }
 {
  align .tl_set:N        = \l_gerry_multifig_align_tl,
  scale .tl_set:N        = \l_gerry_multifig_scale_tl,
  innerscale .tl_set:N   = \l_gerry_multifig_innerscale_tl,
  caption .tl_set:N      = \l_gerry_multifig_caption_tl,
  shortcaption .tl_set:N = \l_gerry_multifig_shortcaption_tl,
  label .tl_set:N        = \l_gerry_multifig_label_tl,
  align .initial:n       = c,
  scale .initial:n       = 1,
  innerscale .initial:n  = 0.95,
 }
\NewDocumentEnvironment{multifig}{O{htp}}
 {
  \begin{figure}[#1]
 }
 {
  \end{figure}
 }

\NewDocumentCommand{\shortfig}{mm}
 {
  \group_begin:
  \keys_set:nn { gerry/multifig } { #2 }
  \begin{subfigure}[\l_gerry_multifig_align_tl]{\l_gerry_multifig_scale_tl\textwidth}
  \centering
  \includegraphics[width=\l_gerry_multifig_innerscale_tl\textwidth]{#1}
  \tl_if_empty:NTF \l_gerry_multifig_shortcaption_tl
   {
    \caption{\l_gerry_multifig_caption_tl}
   }
   {
    \caption[\l_gerry_multifig_shortcaption_tl]{\l_gerry_multifig_caption_tl}
   }
  \tl_if_empty:NF \l_gerry_multifig_label_tl { \label{\l_gerry_multifig_label_tl} }
  \end{subfigure}
  \group_end:
 }
\ExplSyntaxOff



\begin{document}

\ref{examplelabel}

\begin{multifig}
\shortfig{example-image-a}{
  scale=.2,
  shortcaption=small caption 1,
  caption=big caption 1,
  label=examplelabel,
}\qquad
\shortfig{example-image-b}{
  align=t,
  scale=.2,
  innerscale=.5,
  caption=caption 2,
 }
\end{multifig}

\begin{multifig}
\shortfig{example-image-a}{
  align=t,
  scale=.2,
  shortcaption=small caption 1,
  caption=big caption 1,
}\qquad
\shortfig{example-image-b}{
  align=t,
  scale=.2,
  innerscale=.5,
  caption=caption 2,
 }
\end{multifig}

\end{document}

enter image description here

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.