I'm trying to generate a template for exporting figures and plots in a consistent way that will allow easy editing in any vector based drawing software (such as illustrator). My problem is that exported figures in vector format have an (apparently) unnecessarily cumbersome structure. For instance
p = Plot[x, {x, 0, 1}
, Frame -> True
, FrameLabel -> {"Abscissa [unit]", "Ordinate [a.u]"}
, BaseStyle -> {FontSize -> 11, FontFamily -> "Helvetica",
FontTracking -> "Plain", TextJustification -> 0,
PrivateFontOptions -> {"OperatorSubstitution" -> False}}
]
Export["test.svg",p,"SVG"]
will generate an SVG file which code look like this:
<g transform='matrix(1.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000)' clip-path='url(#cp98)'>
<clipPath id='cp98'><polygon points='74,13 74,252 434,252 434,13 ' /></clipPath>
<polyline fill='none' stroke-opacity='1' stroke-width='0.2px' stroke='rgb(0%,0%,0%)' points='431.898,20 428.122,20 ' />
</g>
<g transform='matrix(1.000000, 0.000000, 0.000000, 1.000000, 235.948980, 236.753659)' clip-path='url(#cp99)'>
<clipPath id='cp99'><polygon points='-1.94898,-1.75366 -1.94898,15.2463 73.051,15.2463 73.051,-1.75366 ' /></clipPath>
<text x='0' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>Abscissa</text>
<text x='49' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>[</text>
<text x='52' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>unit</text>
<text x='69' y='11' font-family='Arial' font-size='11px' fill='rgb(0%,0%,0%)'>]</text>
</g>
See how each piece of text, and tick stroke has a group, a clipping mask and the text is split in several text instances. That code also is cumbersome to manipulate when opened in Illustrator
The described problem also exists in PDF and EPS formats, but is easier to see in the SVG code.
Is it possible to control this behaviour?
At least I would like to remove any clipping masks AND groups, and force all the text in a label to be a single object. Ideally I would like to have a group for traces, another for axis and another for labels
I tried making TextJustification -> 0,FontTracking -> "Plain"
hoping at least the text split could be solved, but with no consequence.
Edit
Based on this question one strategy would be to parse back the SVG file (that is XML mark-up) , join all text that is in the same group. and then remove groups and clipping paths. That was not the kind of solution I was expecting, but it may work.
Any help on how to do this string or XML translation?
<g (random options 1)>
<clipPath (random options 2) /></clipPath>
<text (random options 3)> A</text>
<text (random options 3)> B</text>
<text (random options 3)> C</text>
</g>
into
<text (same options 3)> ABC</text>
Edit 2
A very preliminary and partially failed solution is to create the SVG and parse it back as XML, and take what is inside the groups (g) and clips (clipPath), and export it back as text.
p = Plot[x, {x, 0, 1}
, Frame -> True
, FrameLabel -> {"Abscissa [unit]", "Ordinate [a.u]"}
, BaseStyle -> {FontSize -> 11, FontFamily -> "Helvetica",
FontTracking -> "Plain", TextJustification -> 0,
PrivateFontOptions -> {"OperatorSubstitution" -> False}}
]
Export["test2.svg",
ExportString[
ImportString[ExportString[p, "SVG"], "XML"] /.
XMLElement["g", __, {XMLElement["clipPath", __], x_}] -> x,
"XML"], "Text"]
But the problem is that some groups have transform definitions that redefine the coordinate system and that information is currently lost. Also not all the groups are removed, i don't understand why. I would appreciate some help on this XML substitution rules and data parsing.