# How to split a string to figure float with figure name, label and caption?

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
• @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