710

I'm making all my diagrams in SVG format using Inkscape and then I export them to some other format (e.g. PDF, EPS or PNG). I wrote a short script that does this for me automatically, but I'd like to avoid this step, if possible --- sometimes the conversion from SVG converts the text labels into vectors, and that's annoying. Hence the question:

Is there a way to include SVG diagrams directly without conversion to an intermediate format?

Package suggestions, or instructions for specific LaTeX distribution are welcome. Tips and personal experience on which tools you have found to be working reliably would be also appreciated.

9
  • 4
    What types of diagrams are you creating with Inkscape? Maybe you could do them via TikZ or gnuplot. The latter offers a special LaTeX-export, thereby allowing you to use mathmode for labels etc. Aug 20, 2010 at 18:09
  • 2
    TBH, I've never used TikZ so far, but I guess it's time to give it a try for the next paper. I make all kinds of diagrams, mostly engineering-oriented (e.g. free-body diagrams, component loads and such), but sometimes more generic boxes-and-arrows stuff. Aug 20, 2010 at 18:19
  • Good question. But is exporting text labels as vectors is always annoying?
    – Orion
    Nov 4, 2013 at 11:57
  • 1
    SVG to PDF conversion using document.online-convert.com/convert-to-pdf is something I would recommend. Nothing to install and platform-agnostic!
    – pengu1n
    Dec 28, 2018 at 5:07
  • 1
    To save you the effort of going through all of the old answers: The modern solution to this is the svg package, described in detail in this answer. While you do need to install Inkscape, it comes very close to feeling like native support, as all of the conversion is done automatically in the background.
    – schtandard
    Sep 19, 2021 at 10:41

23 Answers 23

188

There is now (at time of writing for about a month) a package svg on CTAN and also included into the big TeX distributions. MWE:

\documentclass{article}

\usepackage{svg}

\begin{document}
\includesvg{some_svg_file}
\end{document}

This package makes use of pdfTeX primitives. Not all of these are defined in LuaTeX, so you would get errors on compiling. See answer of Heiko Oberdiek for a solution.

Every SVG file given by the command \includesvg will under the hood be converted with the help of some additional programs, which at least on Windows are not installed by default (the package claims, it wouldn’t run in Windows, but see below):

  • Inkscape (for using the technique already mentioned in other answers)
  • ImageMagick (actually the included convert)
  • only MiKTeX users: Xpdf (actually the included pdftops)

Notes:

  1. For compilation pdflatex needs the command line switch --shell-escape.

  2. All executables/binaries must be located in the search path. In Windows only the “ImageMagick” installer does this by default. For inkscape and pstopdf one needs to add the paths oneself, or I would recommend for each a batch file in the binary path of your local texmf tree (which anyway should be itself in the search path). Additonal hint for MiKTeX users: Create a local texmf tree in MiKTeX.

`inkscape.cmd` _(it **must** get this name!)_:

<!-- language: lang-none -->

    @echo off
    <path-to-inkscape>\inkscape.exe %*

`pdftops.cmd` _(it also **must** be named this way!), not needed for Users of TeX Live_:

<!-- language: lang-none -->

    @echo off
    <path-to-Xpdf>\pdftops.exe %*

<sub>Of course, adjust the paths to your local settings.</sub>
  1. The package uses the *nix specific commands mv and rm. In Windows we can emulate them once more with batch scripts, which again must get the names given here and should be put into the bin folder of the local texmf tree:
`mv.cmd`:

<!-- language: lang-none -->

    @echo off
    move /Y %*

The switch `/Y` overwrites existing files without any question! I introduced it here for the use with TeX editors.

`rm.cmd`:

<!-- language: lang-none -->

    @echo off
    del /Q %*

The switch `/Q` also suppresses any question!
18
  • 2
    I'd love it more if it could externalise the conversion (similar to TikZ) so I'd not need --shell-escape.
    – Raphael
    Jan 17, 2014 at 13:27
  • 28
    This should actually be the top answer because answer actually answers the question of "how to include SVG without converting". Aug 4, 2014 at 11:30
  • 7
    @user1271772: Thank you for this implicit compliment, but in fact also with this package the svg files are converted, but this happens under the hood during the compilation process.
    – Speravir
    Aug 4, 2014 at 15:29
  • 1
    @cfr Nope, there are other modes. You can have a make file to run afterwards, or a list of figures.
    – Raphael
    Apr 30, 2015 at 10:14
  • 7
    Any chance an example tex-file could be added to this answer? I have the texlive-recommended package on ubuntu but pdflatex errors out on \includepackage{svg}
    – PureW
    Sep 20, 2016 at 17:41
365

The latest version of Inkscape supports PDF+LaTeX export. The graphic itself is exported as PDF, but all text can be put into a .tex file. This way all the text appears in your document font.

The latest Inkscape version can be found on the official site.

There is a free article about the export on CTAN: How to include an SVG image in LaTeX.

In May 2015, you could read from that article, that the quickest way to get this done was:

inkscape -D -z --file=image.svg --export-pdf=image.pdf --export-latex

But as Peter Mukhachev pointed out in his comment, the inkscape command has changed, it is now (as of EDIT July 2020) on more recent versions of inkscape correct like this:

inkscape -D image.svg  -o image.pdf --export-latex

In Jan 2020 and Inkscape 1.0beta2, this command is correct for macOS Catalina (thanks to moazzem's comment):

/Applications/Inkscape.app/Contents/MacOS/inkscape -D -z image.svg --export-type="pdf" --export-file=image.pdf --export-latex

Then include the generated TeX file, which will automatically import the image:

\begin{figure}
    \centering
    \def\svgwidth{\columnwidth}
    \input{image.pdf_tex}
\end{figure}

Be aware that this uses \includegraphics to insert the graphic, so you need to include graphics or graphicx in your document.

Notice that using \input you lose the resizing functionality of \includegraphics[]{}. Instead, you can use something like \scalebox{}{}. For instance:

\begin{figure}
    \centering
    \def\svgwidth{\columnwidth}
    \scalebox{0.5}{\input{image.pdf_tex}}
\end{figure}

Further, here are two good things that I found over time of using this feature. Both are mentioned in the linked pdf, but I missed those hints for quite some time.

When you insert text, there is a little square in the textbox which shows you the alignment of the text. For example if you want to have an arrow pointing from your text to an object, make sure the justification is correct. enter image description here

For some time I was thinking, that text could not handle line breaks, but it is possible if you flow text into a shape. Draw a rectangular shape, write some text, select both and then go in the text menu to "Flow into frame". The shortcut for this is Alt + W.

11
  • 2
    This tool is really nice, but you do need to be careful about scaling - you can set \svgwidth but the text is then positioned correctly but not scaled, or you can wrap the whole \input in a \resizebox which scales the text correctly - often to too small.
    – Chris H
    Sep 10, 2013 at 10:48
  • True @ChrisH, what I did is to adjust my font in inkscape to have the correct width (compared to my LaTeX font) and I create my graphics at nearly the correct size (-> textwidth from latex). That way you avoid surprises later on. You can also just write \small or \footnotesize in front of the import or input command to scale the font if necessary.
    – Martin H
    Sep 10, 2013 at 13:33
  • @MartinH I had to do something similar, but I was caught out at first - hence the warning to anyone as unwary as I was.
    – Chris H
    Sep 10, 2013 at 14:04
  • 43
    This is clearly not an answer to the question. If the SVG file is originating from any programme other than Inkskape the extra conversion is still required. Moreover, there is nothing in this solution concerning direct inclusion of SVG files in tex documents. Dec 10, 2014 at 19:35
  • 2
    While this still works, the workflow has been greatly simplified in the deacade since this answer was posted. This answer gives a step-by-step guide on setting up the svg package for virtually direct inclusion of svg drawings into LaTeX.
    – schtandard
    Sep 10, 2021 at 21:02
86

As the other answers already mention, the TeX backends do not support the SVG file format. That means there is no other way than to convert the SVG images.

However, ConTeXt provides transparent conversion (complete list: ConTeXt Dependencies) of several file formats that are not natively supported by LuaTeX, e.g.:

  • converting PostScript images to PDF
  • converting GIF and TIFF images
  • converting SVG and compressed SVG

The SVG conversion is done in the background using inkscape. This means from the users' point of view there is no difference if a PNG or a SVG file is included. Example:

\starttext
  \externalfigure [image.svg]
\stoptext

A single compilation run with context file creates the temporary image m_k_i_v_image.pdf which is inkscapes output and is transparently included.

Result of the code above (a file only containing the SVG image image.svg):

result

3
  • 35
    ohhh... +1 for the fancy graphics.
    – naught101
    Apr 29, 2012 at 6:31
  • 4
    "... there is no difference if a PNG or a SVG file is included." Is'nt PNG rasterized? Shouldn't it be PDF? Otherwise that would be a shame.
    – Fictional
    Jan 28, 2015 at 11:17
  • @fictional: There is no difference from the user's point of view. That means you can include an SVG in the same way you'd include a PNG, and there's no special command that only works with SVG but not with PNG, assuming you use ConTeXt.
    – Zak
    Jul 30, 2018 at 8:39
50

If you figures are sufficiently simple TikZ 2.0 provides the SVG path operation:

\path . . . svg[<options>] "<path data>" ... ;

See the pgfmanual section 14.12. Only SVG 1.1 path data is supported.

46

This question is now almost ten years old and a lot has changed since it was asked. The canonical – and easiest – way to include svg drawings in LaTeX nowadays is the svg package. This has been mentioned in previous answers, but the information there is outdated or incomplete. I will try to give a concise summary of the necessary setup and process here.

The svg package

The svg package relies on Inkscape as a backend to convert the svg drawing into a pdf file containing everything but text and a tex file (with the file extension pdf_tex) with code to include all the pages in the pdf and place the omitted text on the picture. Instead of \includegraphics you use \includesvg to place the drawing in your document. When you do, the package checks if the pdf and pdf_tex files need to be (re)generated (if they don't exist or if the drawing has been modified since they were last generated). If so, it automatically calls Inkscape, generated the files and includes them. (In order not to clutter your directory, the svg package creates a folder called svg-inkscape for these files.) In effect, this places the current version of your drawing in the document.

There are two prerequisits for this to work:

  1. Inkscape needs to be installed and in the system path.
  2. LaTeX needs to be run with shell escape enabled.

Enabling shell escape

Enabling shell escape (also known as \write18) allows TeX to call external programs (cf. this question). You enable it by calling LaTeX with the option --shell-escape. If your editor calls LaTeX for you, you have to add this option in the editor's preferences. (Note that doing so comes with a certain risk if you run foreign documents on your machine.)

If you use TeXstudio, you can also enable shell escape for single documents (and mitigate the aforementioned risk) using magic comments. For example, insert

% !TeX TXS-program:compile = txs:///pdflatex/[--shell-escape]

at the top of your document in order to compile it with pdflatex and shell escape enabled. TeXstudio will prompt you the first time you compile after this and you can allow it for that document only.

Getting Inkscape into the search path

On Linux (and MacOS, I think), Inkscape is automatically added to the system's search path during installation. On Windows, you have to actively choose this during installation.

You can check if Inkscape is in the path by opening a command line (e.g. by right-clicking on the Windows button and selecting Windows PowerShell) and executing inkscape (type it and press enter). If Inkscape is in the path, it will open, otherwise you will get an error.

If you did not add Inkscape to the search path and want to do so retroactively, you can follow these steps (or just uninstall and reinstall Inkscape): First, you have to finde the directory where the Inkscape executable is located. By default, this is C:\Program Files\Inkscape\bin. Then you have to add this directory to the path variable. Open the Windows Settings and navigate to SystemAboutSystem infoAdvanced system settingsEnvironment Variables. Now double click on Path in the list of System variables (for all users) or User variables (just for you). Click New, paste the directory of the Inkscape executable and press enter. Then press OK on the three open dialogues. Done.

You may have to restart your LaTeX editor or command line for the change to take effect.

An MWE

You can test if your setup works with this MWE

% !TeX TXS-program:compile = txs:///pdflatex/[--shell-escape]
\begin{filecontents}[noheader]{drawing.svg}
<?xml version="1.0" encoding="UTF-8"?>
<svg width="96.725mm" height="50.327mm" version="1.1" viewBox="0 0 96.725 50.327" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
 <metadata>
  <rdf:RDF>
   <cc:Work rdf:about="">
    <dc:format>image/svg+xml</dc:format>
    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
    <dc:title/>
   </cc:Work>
  </rdf:RDF>
 </metadata>
 <g transform="translate(-27.689 -45.179)">
  <path d="m100.09 88.093-6.259-9.7729-10.235 5.4701 3.7384-10.987-10.658-4.5917 10.921-3.9274-3.0554-11.196 9.8795 6.0894 6.8483-9.3694 1.3988 11.521 11.595-0.48748-8.1351 8.2767 7.6106 8.7615-11.543-1.1998z" fill="#ff0808"/>
  <text x="83.593781" y="83.789787" fill="#000000" font-family="'CMU Serif'" font-size="12.7px" letter-spacing="0px" stroke-width=".26458" text-align="end" text-anchor="end" word-spacing="0px" style="line-height:1.25" xml:space="preserve"><tspan x="83.593781" y="83.789787" font-size="3.8806px" stroke-width=".26458" text-align="end" text-anchor="end">This is a test for testing.</tspan></text>
 </g>
</svg>
\end{filecontents}

\documentclass{article}

\usepackage[inkscapearea=page]{svg}

\begin{document}

\includesvg{drawing}

\end{document}

It creates a drawing.svg in your working directory and attempts to include it.

3
  • On my machine it shows Package svg Error: File `drawing_svg-tex.pdf_tex' is missing. \includesvg{drawing} What could be the problem?
    – dnth
    Apr 10, 2020 at 7:52
  • @dnth Probably you did not enable shell escape or Inkscape is not in your system path. Try running inkscape from the console and have a look at this question for testing if shell escape is enabled. If you can't find the problem, ask a new question and include an MWE and the log file.
    – schtandard
    Apr 11, 2020 at 17:13
  • As to why you would need to add inkscape to the path, you can consider this forum: inkscape.org/forums/questions/…
    – Cadoiz
    Feb 5, 2021 at 1:30
28

Inkscape has a(n experimental) tikz exporter: link. (I've never used it but perhaps someone who has will stop by and give a few more details.)

2
  • 1
    Isn't it only for paths? Aug 21, 2010 at 14:08
  • 2
    Most path frawn in inkscape are easily conerted to \draw, \fill or \filldraw. Nvertheless, it heavily use the cm (coordinates matrix) intead of applying it directly, resulting in not easily undesstandanle code and a lot of unneeded scopes. By the way, an additional yscale=-1 is not really user friendly,too.
    – Jhor
    Jul 22, 2019 at 15:50
28

You may also want to look at Ipe. It is a graphics editor similar to Inkscape, but integrates tightly with LaTeX, and exports eps and pdf files that are easy to include into TeX documents. It also comes with a svgtoipe script that converts many svg figures to the ipe format, so that they can be edited with Ipe. I'm not sure how well does the conversion handle text, but it is easy to add the necessary labels in Ipe, and since Ipe uses LaTeX to render text, you can have your labels match your text perfectly.

3
  • 9
    It not just exports to PDF, it saves the entire image as a PDF (or EPS). All Ipe data is inside that PDF, so you can just reload the PDF in Ipe and edit it if you want to change your drawing. Basically, the file you edit is the same file as you include in LaTeX, so no need to do an export each time you change the file. Nov 20, 2014 at 14:54
  • Never heard of this software, very interesting suggestion, thank's. The ability to save all data required to edit the image later directly inside the PDF/EPS is quite attractive and would remove the need to have duplicate files (one in the original editable format and one EPS output, like when working with Inkscape or Gimp).
    – gaborous
    May 31, 2016 at 17:17
  • Simple, elegant, effective. This piece of software which I never even heard of is the answer to all my problems. Beautiful! Just beautiful!
    – pbount
    Jul 24, 2018 at 13:28
27

For including the SVG in LaTeX, you can refer to Marin H answer. But as Latex does not natively support SVG, you may run in to font size and placement issues. During the conversion from SVG to LaTeX as Inkscape carries out, all the positions are changed to absolute X, Y values, thus your alignments are lost in the conversion, as it does not recognize it.

Unless you exactly use the same LaTeX font size/type in Inkscape you will get a different output from what you see in inkscape. I gave up this route due to these problems and went for the normal SVG->PDF inclusion.

The example below illustrates the problem. The file inkscape-pdf.pdf_tex is generated using the PDF+LaTeX option in Inkscape.

The original Inkscape figure: The image you see in Inkscape

\documentclass{article}
\usepackage{graphicx,xcolor}
\begin{document}

\begin{figure}
\centering
\def\svgwidth{\columnwidth}
\input{inkscape-pdf.pdf_tex}
\end{figure}

\begin{figure}
\centering
\def\svgwidth{0.5\columnwidth}
\input{inkscape-pdf.pdf_tex}
\end{figure}

\end{document}

LaTeX output:

enter image description here

0
21

Some additional information concerning Andrew's answer. As far as I know, LaTeX does not support including SVG files directly.

3
20

As this questions is still one of the first hits for "svg latex" I would like to add something to this topic.

  • You can't directly include svg vectorgraphics. You always have to convert them.
  • Conversion at the moment is easiest with inkscape, because it offers access to this functionality via command-line.

To make it short: use the svg-package by Phillip Ilten and see this blog post on laclaro.wordpress.com for examples and more features.

The longer story: It all started some time ago, when "Oni" wrote a python script, designed as inkscape extension to convert svg to tex+pdf (can still be found on the net). Today this plugin is a standard inkscape export option. The inkscape developers provided a document how to manually use this new feature from a latex document (called svg-inkscape).

Based on that I wrote about including SVG in LaTeX documents, and added some bits to the includesvg command and some months later there was the "svg" package published by Philip Ilten, which I recommend everyone to use. Some extended examples, merging my work and that of Philip can be found on http://laclaro.wordpress.com.

18

I find the following approach more convenient for my work. My figures are created via Inkscape and Python.

MWE

\documentclass[]{memoir}
\usepackage{svg}

\begin{document}

\begin{figure}[!ht]
 \centering
 \includesvg[width=0.5\columnwidth, svgpath = /yourPATHtoSVG/]{filename}
\end{figure}

\end{document}

One can compile MWE above with following command line

pdflatex -synctex=1 -interaction=nonstopmode --shell-escape %.tex

Note: filename is just the name of the figure, without .svg extension.

The svg package is here.

1
  • 2
    You need also to have Inkscape installed in your system, and findable in your PATH environment variable. If you encounter some compilation warnings like "PDF inclusion: multiple pdfs with page group included in a single page", you can safely silence them by including the command \pdfsuppresswarningpagegroup=1 after \usepackage{svg}, see this question. Dec 28, 2017 at 23:05
18

All the approaches presented so far rely on an external program creating an intermediate file which is then included as an image. One can actually do this inplace using the Cairo and Rsvg2 libraries via the FFI (Foreign Function Interface) of LuaJITTeX or LuaTeX ≥ 1.0.3. The FFI needs the --shell-escape option.

Is there a way to include SVG diagrams directly without conversion to an intermediate format?

Not to brag but I believe that my answer is the only one actually answering the question.

Below I show how to convert a sample SVG from Wikipedia using this approach. I saved https://en.wikipedia.org/wiki/File:Bitmap_VS_SVG.svg as test.svg in the working directory.

CAVEAT: Calling C code is inherently unsafe. Because C functions are called within the scope of the Lua interpreter, memory faults in the library calls may result in memory corruption which could lead to a segmentation fault, crashing LuaTeX.

\documentclass{article}
\usepackage{luacode}

\begin{luacode}
local ffi = require("ffi")

ffi.cdef[[
// Types
typedef struct FILE_tag FILE;
typedef struct RsvgHandle_tag RsvgHandle;
typedef struct cairo_surface_tag cairo_surface_t;
typedef enum cairo_status_tag cairo_status_t;
typedef struct cairo_tag cairo_t;
typedef int (*cairo_write_func_t)(void *, const unsigned char *, unsigned int);

typedef struct {
    int domain;
    int code;
    char *message;
} GError;

typedef struct {
    int width;
    int height;
    double em;
    double ex;
} RsvgDimensionData;

// Conversion functions
RsvgHandle * rsvg_handle_new_from_file(const char *, GError **);
void rsvg_handle_get_dimensions(RsvgHandle *, RsvgDimensionData *);
cairo_surface_t * cairo_pdf_surface_create_for_stream(cairo_write_func_t, FILE *, double, double);
cairo_status_t cairo_surface_status(cairo_surface_t *surface);
cairo_t * cairo_create(cairo_surface_t *);
cairo_status_t cairo_status(cairo_t *cr);
void cairo_scale(cairo_t *, double, double);
int rsvg_handle_render_cairo(RsvgHandle *, cairo_t *);

// Cleanup functions
void cairo_destroy(cairo_t *);
void cairo_surface_destroy(cairo_surface_t *);
void g_object_unref(void *);
]]

local lcairo = ffi.load("cairo")
local lrsvg = ffi.load("rsvg-2")

local CAIRO_STATUS_SUCCESS = 0

function svg_to_pdf(params, filename)
    -- Open input file
    local err = ffi.new("GError*[1]", ffi.NULL)
    local rsvg = lrsvg.rsvg_handle_new_from_file(filename, err)
    if rsvg == ffi.NULL then
        tex.error(ffi.string(err[0].message))
    end
    -- Get size of image
    local dimensions = ffi.new("RsvgDimensionData[1]")
    lrsvg.rsvg_handle_get_dimensions(rsvg, dimensions)

    local width = params.scale * dimensions[0].width
    local height = params.scale * dimensions[0].height

    -- Open cairo PDF canvas of same size and associate callback function
    local output = ""
    function rsvg_cairo_write_func(_, data, length)
       output = output .. ffi.string(data, length)
       return CAIRO_STATUS_SUCCESS
    end
    local surface = lcairo.cairo_pdf_surface_create_for_stream(
       rsvg_cairo_write_func, nil, width, height);
    local status = lcairo.cairo_surface_status(surface)
    if status ~= CAIRO_STATUS_SUCCESS then
        tex.error("Cairo surface error (code " .. status .. ")")
    end

    -- Render SVG on the canvas
    local cr = lcairo.cairo_create(surface)
    local status = lcairo.cairo_status(cr)
    if status ~= CAIRO_STATUS_SUCCESS then
        tex.error("Cairo error (code " .. status .. ")")
    end
    lcairo.cairo_scale(cr, params.scale, params.scale);
    local success = lrsvg.rsvg_handle_render_cairo(rsvg, cr)
    if success == 0 then
        tex.error("Rsvg rendering failed")
    end

    -- Clean up
    if (cr ~= ffi.NULL) then lcairo.cairo_destroy(cr) end
    if (surface ~= ffi.NULL) then lcairo.cairo_surface_destroy(surface) end
    if (rsvg ~= ffi.NULL) then lrsvg.g_object_unref(rsvg) end
    if (err[0] ~= ffi.NULL) then lrsvg.g_object_unref(err[0]) end

    return output
end
\end{luacode}

\newcommand\includesvg[2][scale=1]{%
  \leavevmode
  \luaexec{
    local stream = svg_to_pdf({#1},[[#2]])
    local identifier
    if status.luatex_version < 108 then
        _, identifier = epdf.openMemStream(stream,\#stream,[[#2]])
    else
        identifier = pdfe.new(stream,\#stream,[[#2]])
    end
    node.write(img.node { filename = identifier })
  }%
}

\begin{document}

\includesvg[scale=.3]{test.svg}

\end{document}

enter image description here

11

Having read your comment, maybe a combination of Inkscape and the overpic package may be helpful. This package allows you to write any LaTeX commands on top of an existing picture. A colleague of mine uses it to draw pictures of free-form curves, for example, and adds all labels and points of interests manually. The package allows you to display a grid, so it should not be too tedious---depending on the size of your picture, of course.

11

There are several SVG → PDF converters available, e.g. Apache Batik's rasterizer.

3
  • 37
    It's a shame they called it a rasterizer!
    – Joseph Wright
    Aug 21, 2010 at 12:24
  • 1
    Why is it a shame? I have ever used it therefore I asked.
    – lazyboy
    Oct 2, 2012 at 19:20
  • 14
    @lazyboy because rasterisation denotes the act of converting a vector graphic (where shapes are given by coordinates) into a raster format (typically described by its pixels or similarly lossy data), but pdf is able to contain vector graphics. So the rasterizer does more than just rasterize. May 22, 2013 at 16:48
11

With great thanks to the work of Philip Ilten (he wrote this package) and laclaro, I suggest the following alternative.

I want to do something just very slightly different - I don't want LaTeX to do the text for me, as the text in my figures is often rather tightly sized/positioned, and I have a preference (on the basis of readability, not aesthetics) for sans serif in figures, especially when there is vertical or very small text. So here's the code:

\newcommand{\executeiffilenewer}[3]{%
\ifnum\pdfstrcmp{\pdffilemoddate{#1}}%
{\pdffilemoddate{#2}}>0%
{\immediate\write18{#3}}\fi%
}
% includesvg[includegraphics args]{file} command (linux-version)
\newcommand{\includesvg}[2][]{%
\executeiffilenewer{#2.svg}{#2.pdf}{%
/usr/bin/inkscape -z -C --file="#2.svg" --export-pdf="#2.pdf" >temp.txt}%
\ifthenelse{\equal{#1}{}}{%
\includegraphics{#2}}{%
\includegraphics[#1]{#2}}%
}

It's directly based on laclaro's "old way" (in German, but the LaTeX is comprehensible combined with my rusty rudiments of German), but with the inkscape options changed.

I'm inclined to suggest this as an option to the really good svg package (with some upgrades to things like the scale specifier, which I may get round to putting in).

Edit: it can now pass arguments to the \includegraphics command

10

Although this is a bit of a late answer, I just noticed this question today. For quite some time, I've been using a small package which I wrote to do this (as well as including simple LyX files), which I've called cludein.sty -- it works well with POSIX operating-systems, and requires running pdflatex with the -shell-escape flag.

Not sure if I should post it here, but since I don't have it anywhere else on the internet at the moment, why not:

% cludein.sty: Include various file formats directly in a LaTeX file

% *****************************************************************************
% *******   NOTE: pdflatex must be run with the -shell-escape flag in order for
% *******         this package to work.
% *****************************************************************************

% This package provides the following commands:
%    \includesvg -- include an SVG image
%    \svgfig     -- create a Figure environment with an SVG image
%    \includelyx -- include a LyX image
%
% USAGE:
%   \includesvg[width]{path/to/dir/of/svg/file}{name-of-svg-file-without-extension}
%
%   \svgfig[placement][label][width]{figname}{caption-text}
%       -- default arguments can be used with an empty []:
%       for example, \svgfig[tb][][5cm]{myfigname}{Some caption text.}
%       uses the default label of fig:myfigname (in this example).
%
%   \includelyx{path/to/dir/of/lyx/file}{name-of-lyx-file-without-extension}

\NeedsTeXFormat{LaTeX2e} 
\RequirePackage[multidot]{grffile} % allow multiple dots in graphics filenames
\RequirePackage{xargs}
\RequirePackage{color}
\RequirePackage{graphicx}

\ProvidesPackage{cludein}[2011/01/17 v0.1
                          direct inclusion of various file formats]
\typeout{-> cludein.sty <- by Mark Edgington, 2011}
%
%%%%%%%%%%%% BEGIN: auto-include SVG / LyX files %%%%%%%%%%%%%

% usage: \includesvg[width]{path/to/dir/of/svg/file}{name-of-svg-file-without-extension}
% if source file doesn't exist, nothing is done...


\newcommand{\executeiffilenewer}[3]{%
\ifnum\pdfstrcmp{\pdffilemoddate{#1}}%
{\pdffilemoddate{#2}}>0%
{\immediate\write18{#3}}\fi%
}


\newcommand{\includesvg}[3][\undefined]{%
\IfFileExists{#2/#3.svg}{%
\executeiffilenewer{#2/#3.svg}{#2/output/#3.pdf}%
{mkdir -p #2/output ; %
inkscape -z -D --file=#2/#3.svg %
--export-pdf=#2/output/#3.pdf --export-latex}%
\graphicspath{{#2/output/}}% search here for output pdf
% set figure width
\ifx#1\undefined
    \let\svgwidth\undefined
\else
    \def\svgwidth{#1}
\fi
% properly center a potentially overwide image
\makebox[\textwidth][c]{%
  \input{#2/output/#3.pdf_tex}%
}%
}{\colorbox[rgb]{0.7,0.7,0.7}{\textcolor{black}{MISSING FIGURE}} }% end of IfFileExists
}


\newcommand{\includesvgnobox}[3][\undefined]{%
\IfFileExists{#2/#3.svg}{%
\executeiffilenewer{#2/#3.svg}{#2/output/#3.pdf}%
{mkdir -p #2/output ; %
inkscape -z -D --file=#2/#3.svg %
--export-pdf=#2/output/#3.pdf --export-latex}%
\graphicspath{{#2/output/}}% search here for output pdf
% set figure width
\ifx#1\undefined
    \let\svgwidth\undefined
\else
    \def\svgwidth{#1}
\fi
% properly center a potentially overwide image
\input{#2/output/#3.pdf_tex}%
}{\colorbox[rgb]{0.7,0.7,0.7}{\textcolor{black}{MISSING FIGURE}} }% end of IfFileExists
}

% TODO: make secondary \includesvg command which instead of directly exporting to PDF (which
% currently is uncompressed with inkscape), does something which results in a compressed PDF. (maybe
% postprocess the uncompressed pdf?)

% usage: \svgfig[placement][label][width]{figname}{caption-text}
% -- default arguments can be used with an empty []:
%    for example, \svgfig[tb][][5cm]{myfigname}{Some caption text.}
%    uses the default label of fig:myfigname (in this example).
\newcommandx{\svgfig}[5][1=tb, 2=\undefined, 3=\undefined, usedefault]{%
\begin{figure}[#1]%
\begin{center}%
  \includesvg[#3]{svg}{#4}%
  \caption{#5}%
\ifx#2\undefined%
    \label{fig:#4}%
\else%
    \label{#2}%
\fi%
\end{center}%
\end{figure}%
}

% export and include lyx files!
% sed is used to keep only the stuff inside the document-environment 
% sed command is: sed -i '0,/\\begin{document}/d; /\\end{document}/,$d' file-to-replace.tex
\newcommand{\includelyx}[2][lyx]{%
\executeiffilenewer{#1/#2.lyx}{#1/output/#2.lyx_tex}%
{
mkdir -p #1/output ; %
lyx -e pdflatex #1/#2.lyx ; %
mv #1/#2.tex #1/output/#2.lyx_tex ; %
/bin/sed -i '%
0,/\string\\begin{document}/d; /\string\\end{document}/,$d
' %
#1/output/#2.lyx_tex}
\input{#1/output/#2.lyx_tex}%
}

%%%%%%%%%%%% END: auto-include SVG / LyX files %%%%%%%%%%%%%
1
  • Note, that also the recently published package svg contains a command \includesvg, cf. my answer. Not that you need it with your own approach …
    – Speravir
    Sep 30, 2012 at 0:53
9

If you are using LyX, then it is simple; add the directory of Inkscape to the "Paths" in LyX's settings, reconfigure twice, and you can include SVG files just like any other files.

If you are writing LaTeX code, maybe the package svg-inkscape will help you. (I never tried)

5

Another alternative is to use svg2pdf, from the Gnome Librsvg library (which is available on Linux and OSX (via MacPorts/brew)), to convert the SVG file to PDF format and include it as a PDF in Latex. This appears to produce a vector version of the figure which looks good.

Here's an example of how to use it:

svg2pdf mydiagram.svg mydiagram.pdf
3
  • 6
    Note that the question explicitly asks for inclusion without conversion to an intermediate format. Jan 15, 2014 at 16:54
  • 1
    Installing various librsvg2-* packages on Debian Jessie doesn't make svg2pdf available. It does make rsvg-convert available though, which can be used as described here: superuser.com/a/381128/199930
    – 0 _
    Dec 21, 2016 at 13:12
  • I feel sure it must be possible to make a package that uses --shell-escape to call rsvg-convert or svg2pdf automatically whenever you pass an SVG to \includegraphics{}. That would be immensely useful.
    – richard
    Apr 11, 2022 at 1:26
5

If you have installed inkscape then you can run the following command that exports your svg image to PDF and LaTeX format.

inkscape -D -z --file=image.svg --export-pdf=image.pdf --export-latex

After that, you can include the image in LaTeX:

\begin{figure}[h]
    \centering      
    \def\svgwidth{\columnwidth}
    \input{images/image.pdf_tex}
    \caption{Your image caption}
    \label{fig:your image label}
\end{figure}

More detail: How to include an SVG image in LaTeX


EDIT 2020:

Inkscape command changed, now:

inkscape -D image.svg  -o image.pdf --export-latex
1
3

If you are in engineering or any of the sciences, I would check out Ngraph also:

http://sourceforge.net/projects/ngraph-gtk/

3

SVGLaTeX is a Python package to include SVG graphics in LaTeX documents, with the text typeset by LaTeX. The entry point (a script) installed by this Python package is called by the LaTeX package svglatex.sty.

% test integration of the Python package `svglatex` with
% the LaTeX style `svglatex.sty`.
\documentclass[10pt]{article}
\usepackage{svglatex}
\graphicspath{{./img/}}
\begin{document}
\begin{figure}
    \centering
    \includesvg[width=0.6\textwidth]{./img/beautiful}
\caption{Nice caption.}
\label{fig:label}
\end{figure}
\end{document}

These two packages provide a workflow similar to the Inkscape's native SVG to LaTeX export functionality, together with the LaTeX package svg. The difference is that the bugs of Inkscape's exporter are not included, in particular newlines (\n) within SVG text are ignored by SVGLaTeX, and spurious multi-page PDFs are avoided, as described here.

0

As of 2020 on Mac, Install Inkscape, then:

ln -s /Applications/Inkscape.app/Contents/MacOS/inkscape /usr/local/bin/inkscape
inkscape -D foo.svg -o bar.pdf --export-latex
0

As an alternative, I open a svg with Chrome browser and print it as a pdf (remove the page heads/tails). Now, the pdf has large margins. Then, I use Python to call "pdfcrop" subprocess to crop it.

import subprocess
subprocess.call(["pdfcrop"], svg_file, output_pdf_file)
1
  • 4
    Welcome to TeX.SX! This seems to be a complicated approach. You need to crop the pdf again, to make up for the mistakes of the first step (using Chrome). Why don't you call pdfcrop directly, why use python for that? I think here are many answers, that do this conversion with less effort in one step.
    – dexteritas
    Feb 9, 2023 at 10:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .