# How do I make a script to make inkscape TikZ more human readable

When I export a svg file from inkscape to TikZ, the result is often huge, and not very human readable. I would like to write a perl script for post processing the output. The script should be able to:

1. identify what numbers is x-coordinates and y-coordinates
2. multiply the x-coordinates by a given constant
3. multiply the y-coordinates by a given constant
4. round the coordinates to the nearest multiple of an other constant

This can e.g. be used for getting rid of the four decimals, if they are not needed, and the yscale=-1 can be removed.

What regEx will pick coordinates and control points?

If coordinates and control points are multiplied by a constant, will the resulting picture be scaled (and/or stretched)? or will something by me unforeseen happen?

Other thoughts, and suggestions is appreciated.

Edits: Thank you for the answers, but despise the warnings about that I would need to parse TikZ, I still remain naive. I have not seen any output from inkscape that has coordinates in other forms than (12.3456,42.4242).

-
Is it possible to provide a small example of before and after? –  cmhughes Sep 1 '12 at 4:20
You might want to look at a python script called scour. It does what you want but for the svg output. It might give you some ideas on what optimisations there are to be had. –  Loop Space Sep 1 '12 at 6:25
It was not meant as a warning, more as a hint that postprocessing with a simple regex is very fragile and that it is much more robust and easier to change the export routine instead. It is already in the code, just commented out (line 740) coord_transformed.append("%.4fcm" % ((x-self.x_o)*self.x_scale)) instead of coord_transformed.append("%.4f" % x). –  Alexander Sep 3 '12 at 9:23

Postprocessing the output from the inkscape2tikz export is certainly possible in perl but it will be a complex task. You basically have to parse the TikZ code to a certain degree.

A different approach is to improve things in the export routine itself. It turns out that this is a priority for the author (Kjell Magne Fauske) and it is even partially implemented (inkscape2tikz issue 27). The export is done using a relatively simple python script, so an improvement here will be much easier and benefits everybody who uses the routine.

-

Regular expressions are certainly not sufficient to parse and manipulate arbitrary TikZ code. Thus you must have a look at what kind of constructs inkscape is producing. I guess, that is not documented well, so you may need to look at inkscape's source code.

If you give us example TikZ code, we could surely explain to you, what it means. But another good approach to your problem, is adding the functionality to inkscape's export mechanism itself. That's the beauty of free software. Of course I can not tell you how much effort this approach or your idea of post-processing would take, as that depends a lot on inkscape's export routine's internal built and the kind of TikZ code it produces.

-

My first attempt(command line options not yet implemented). Please tell me if you see something that can be improved.

Code:

#!/usr/bin/perl

#Default values
$startRegex = ".*begin\{tikzpicture\}.*";$endRegex   = ".*end\{tikzpicture\}.*";
$shift_x = 0;$shift_y    = 1000;
$scale_x = 1;$scale_y    = -1;
$precision = 1; #Insert code to accept command line arguments$process = 0;
while(<STDIN>)
{
if($_ =~$endRegex) { $process=0 }; if($process)
{
my @lines = split(';', $_); foreach my$line (@lines)
{
my $newline = ''; while($line =~ m/$$(-{0,1}\d*\.{0,1}\d+),(-{0,1}\d*\.{0,1}\d+)$$/)
{
$line =$';
my $x = int(($1*$scale_x+$shift_x)/$precision)*$precision;
my $y = int(($2*$scale_y+$shift_y)/$precision)*$precision;
$newline .= "$($x,$y)";
}
$newline .= "$line;";
print "$newline\n"; } } else { print; } if($_ =~ $startRegex) {$process=1 };

}


Usage:

./ink2TikZpost.pl <test.tex >newTest.tex

Test input:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}

\begin{document}

\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt]
\path[draw=black,miter limit=4.00,line width=2.835pt,rounded corners=0.0000cm] (100.0000,115.2193) rectangle (560.0000,483.7908);\path[draw=black,line join=miter,line cap=butt,miter limit=4.00,line width=2.835pt] (237.1429,303.7908) -- (468.5714,623.7908);\path[draw=black,miter limit=4.00,line width=2.835pt] (317.1429,696.6479)arc(0.000:180.000:90.000)arc(-180.000:0.000:90.000) -- cycle;\path[draw=black,miter limit=4.00,line width=2.835pt] (622.8571,789.5051)arc(0.000:180.000:100.000000 and 42.857)arc(-180.000:0.000:100.000000 and 42.857) -- cycle;\path[draw=black,miter limit=4.00,line width=2.835pt] (331.4286,939.5051)arc(0.000:100.000:77.142860 and 35.714);
\end{tikzpicture}
\end{document}


Output:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{tikz}

\usepackage[active,tightpage]{preview}
\PreviewEnvironment{tikzpicture}

\begin{document}

\begin{tikzpicture}[y=0.80pt,x=0.80pt,yscale=-1, inner sep=0pt, outer sep=0pt]
\path[draw=black,miter limit=4.00,line width=2.835pt,rounded corners=0.0000cm] (100,884) rectangle (560,516);
\path[draw=black,line join=miter,line cap=butt,miter limit=4.00,line width=2.835pt] (237,696) -- (468,376);
\path[draw=black,miter limit=4.00,line width=2.835pt] (317,303)arc(0.000:180.000:90.000)arc(-180.000:0.000:90.000) -- cycle;
\path[draw=black,miter limit=4.00,line width=2.835pt] (622,210)arc(0.000:180.000:100.000000 and 42.857)arc(-180.000:0.000:100.000000 and 42.857) -- cycle;
\path[draw=black,miter limit=4.00,line width=2.835pt] (331,60)arc(0.000:100.000:77.142860 and 35.714);

;
\end{tikzpicture}
\end{document}


Command line arguments can not yet be given. Extra line with ;` wronly added in output. Angles is not rounded.

-