7

I am writing my thesis and I want to include pictures via a single command. I am fairly new to LaTeX, so I do not really get it. So far I tried this:

\newcommand{\pic}[4]{
\begin{figure}[h!]
\centering
\includegraphics[width=#1\textwidth]{#2}
\caption{#3}
\label{#4}
\end{figure}
}

But I get the error message "paragraph ended before gin@iii was complete". But when I use the commands without the \newcommand, it works without any problems. Has anybody an idea?

Andrew Swann
  • 95,762
modmoto
  • 173
  • If you prefer using a macro rather than environment for figures (and tables), consider taking a look at the boxhandler package (http://ctan.org/pkg/boxhandler). – Steven B. Segletes May 05 '15 at 13:50
  • Are you loading \usepackage{graphicx}? Your code works here. – Sigur May 05 '15 at 13:52
  • 1
    Welcome to TeX.SX! Can you post more code, showing how you call your command? – Andrew Swann May 05 '15 at 13:55
  • i am using the graphixc package, like i said, the command works without the newcommand. I am calling the command with \pic{0.8, 'pics/layering-osgi-eps-converted-to.pdf', 'OSGI Schichtenmodell', 'OSGILayer'} and tried a few variations (no comma, double quote etc.) But i actually do not know how to use my command, as it is a little unclear in the documentation and my first time ;) – modmoto May 05 '15 at 14:01
  • 2
    Put each argument in its own curly brackets \pic{}{}{}{} and set the graphics path so that you can just use {layering-osgi-eps-converted-to} (no extension, no full path needed). – cfr May 05 '15 at 14:06
  • thanks, that has been it =) did not even need to change the graphics path, it worked with the folder. Seems like, i can not upvote yet, so just go with my gratitude ;) – modmoto May 05 '15 at 14:20
  • @cfr That should be the answer. :P – Alenanno May 05 '15 at 14:49
  • don't use [h!] it usually generates a warning that it is being changed to [!ht] but it is better to use [htp] or no option at all. Routinely using ! is wrong, there is no point setting constraints then saying always ignore them. Either don't set them or usually follow them. ! is just for emergency use. – David Carlisle May 05 '15 at 14:51
  • also you need a % after the first { and after \end{figure} – David Carlisle May 05 '15 at 14:52
  • @DavidCarlisle Did you mean a % by any chance? – cfr May 05 '15 at 14:56
  • @Alenanno Not much of an answer :(. – cfr May 05 '15 at 15:02

2 Answers2

7

Be careful before applying this kind of “simplification”: it doesn't really simplify your life and makes the typescript harder to read and also to input, because you'll always be uncertain about the order of the arguments.

Here I propose a key-value interface; you just need to set up your editor to prepare input such as

\addpic{
  width=,
  image=,
  caption=,
  label=,
}

that you can then easily fill with data. For particular images you can add other keys, in order to specify different placement preferences, a short caption for the list of figures or additional keys to be passed to \includegraphics besides width=.

Note that with this interface the order of the keys is unimportant.

\documentclass{article}
\usepackage{xparse}
\usepackage{graphicx}

\ExplSyntaxOn

% the user level command
\NewDocumentCommand{\addpic}{m}
 {
  \group_begin: % localize the changes to the variables
  \simonson_pic:n { #1 }
  \group_end:
 }

% the key-value interface
\keys_define:nn { simonson/pic }
 {
  placement .tl_set:N = \l_simonson_pic_placement_tl,
  placement .initial:n = htp,
  width .tl_set:N = \l_simonson_pic_width_tl,
  width .initial:n = 1,
  options .tl_set:N = \l_simonson_pic_options_tl,
  image .tl_set:N = \l_simonson_pic_image_tl,
  caption .tl_set:N = \l_simonson_pic_caption_tl,
  shortcaption .tl_set:N = \l_simonson_pic_shortcaption_tl,
  label .tl_set:N = \l_simonson_pic_label_tl,
 }

% the main command
\cs_new_protected:Nn \simonson_pic:n
 {
  % set the keys from the argument
  \keys_set:nn { simonson/pic } { #1 }
  % start the figure environment
  \__simonson_start_figure:V \l_simonson_pic_placement_tl
  \centering
  % include the image
  \__simonson_pic_image:VVV
    \l_simonson_pic_width_tl % the text width fraction
    \l_simonson_pic_options_tl % other options
    \l_simonson_pic_image_tl % the image name
  % the caption
  \tl_if_empty:NTF \l_simonson_pic_shortcaption_tl
   {
    \caption{\l_simonson_pic_caption_tl}
   }
   {
    \caption[\l_simonson_pic_shortcaption_tl]{\l_simonson_pic_caption_tl}
   }
   % the label
   \tl_if_empty:NF \l_simonson_pic_label_tl
    {
     \label{\l_simonson_pic_label_tl}
    }
   % end the figure environment
   \end{figure}
}

% syntactic sugar: we want some token lists to be expanded before usage
\cs_new_protected:Nn \__simonson_start_figure:n
 {
  \begin{figure}[#1]
 }
\cs_generate_variant:Nn \__simonson_start_figure:n { V }

\cs_new_protected:Nn \__simonson_pic_image:nnn
 {
  \includegraphics[width=#1\textwidth,#2]{#3}
 }
\cs_generate_variant:Nn \__simonson_pic_image:nnn { VVV }

\ExplSyntaxOff

\begin{document}

\listoffigures

\pic{
  width=0.3,
  image=example-image,
  caption={This is an example image, and a comma in the caption},
  label=one,
}

\pic{
  placement=bp,
  width=0.2,
  options={angle=90},
  image=example-image-a,
  caption=Rotated image,
  shortcaption=In the text the image is rotated!,
}

\end{document}

enter image description here

As Zarko rightly comments, \pic is not a good name if you plan to use TikZ, so I changed it to \addpic.

egreg
  • 1,121,712
5

If you define a command with 4 arguments and they are all required, you have something like this:

\newcommand\mycommand[4]{% these comment signs will prevent the introduction of spurious spaces
  ... #1... #4%
}

Then to use that command in your document you need to say

\mycommand{}{}{}{}

Also, use \graphicspath{{path/to/graphics/}} rather than adding the path to each image, and do not use the file extension: it is better to let graphicx figure it out.

So you'd need something like this:

\graphicspath{{pics/}}
...
\pic{0.8}{layering-osgi-eps-converted-to}{OSGI Schichtenmodell}{OSGILayer}

Note that graphicx can probably auto-convert EPS images if needed - you don't need to pre-convert them. (It will then use the PDF if that's available - it won't keep converting them every time.)

cfr
  • 198,882