1

I am struggling with a shorthand macro that converts a string to a figure. At the end is a working, but unstable version what I am trying to do. The goal is to parse make a command (or macro) like this:

\fig{figure_name.png fig:figure_label
This is the figure caption with a reference \ref{fig:another_figure}.  
}

that corresponds to traditional version of this:

\begin{figure}
  \includegraphicx[width=\columnwidth]{figure_name.png}
  \caption{This is the figure caption with a reference \ref{fig:another_figure}.}
  \label{fig:figure_label}
\end{figure}

Or better yet, the macro format could have key-value pairs in the beginning and caption at the end. This is my final target. Like this:

\fig{(figure_name.png, label=fig:figure_label, width=\columnwidth)
    This is the figure caption with a reference \ref{fig:another_figure}.  
 }

The problem that I have is that the code below gets stuck in a forever loop when references change or when I compile once with an error. When I add a new label I have to comment all lines containing \ref{} and compile the a few times to get references correct. Then uncomment all \refs and compile to get the correct version.

What's wrong or how should do this? I would appreciate a well commented code. I have trouble understanding lines like this: \tl_remove_all:Nn \l_tmpa_tl {-}. A lua solution is also fine.

\usepackage{xparse}

\NewDocumentCommand\fig{>{\SplitList{ }}m}
{%
  \xdef\captionWords{}
    \ProcessList{#1}{\myitem}%
    \firstitemtrue
    \seconditemfalse
    \caption{\captionWords \label{\thisLabel}}
  \end{figure}

}

\newif\iffirstitem
\firstitemtrue  
\newif\ifseconditem
\seconditemtrue
\newcommand\myitem[1]{%
  \iffirstitem

    \begin{figure}[ht]
    \includegraphics[width=\columnwidth]{figures/#1}\\
    \firstitemfalse
    \seconditemtrue
  \else  
    \ifseconditem 
      \xdef\thisLabel{#1}
      \seconditemfalse
    \else 
      \xdef\captionWords{\captionWords\  #1}
    \fi
  \fi
}
  • can't help with most of this, but you do need \protect before \ref when it's in a caption (or other "movable" argument, like a section heading). – barbara beeton May 22 '15 at 17:33
  • How about something even more verbose: \fig{filename=.., label=.., width=.., caption=..} – Werner May 22 '15 at 17:46
  • @barbarabeeton Thanks, I'll look into \protect – Juha May 22 '15 at 18:00
  • @Werner Good idea, also it could be something like: first unnamed argument is a shorthand for filename=... if it exists, second unnamed argument is a shorthand for label=... if it exists. and the named arguments override unnamed arguments. Then you could use both verbose and less verbose versions as you see fit. This is a complicated function, but once you get it working... – Juha May 22 '15 at 18:04
  • 1
    @Juha Your proposed input is very error prone. It's much better to have keys explaining what the following input is for. – egreg May 22 '15 at 23:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.