Skip to content

Instantly share code, notes, and snippets.

@db4rr
Created May 24, 2018 04:46
Show Gist options
  • Save db4rr/f3f88aa6cd5c4ffd84c2c0344b9a7dd2 to your computer and use it in GitHub Desktop.
Save db4rr/f3f88aa6cd5c4ffd84c2c0344b9a7dd2 to your computer and use it in GitHub Desktop.
This XSL applies "text-anchor: middle" to strings within an SVG and recalculates the text element coordinates, reducing the need to manually edit the layout of localised SVG files.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/"
exclude-result-prefixes="xs"
version="2.0">
<!-- Identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<!-- discard all Visio SVG Extension nodes. This makes for cleaner svg -->
<xsl:template match="v:*" mode="#all"/>
<!-- discard attributes that are in the SVG extensions namespace -->
<xsl:template match="@*[namespace-uri() eq 'http://schemas.microsoft.com/visio/2003/SVGExtensions/']" mode="#all"/>
<!--More specific template for svg:style that provides custom behavior -->
<xsl:variable name="allSTs" select="g/text/@class"/>
<xsl:template match="svg:style">
<xsl:copy>
<xsl:copy-of select="@*"/>
<!-- we know that style only has one text node as child -->
<xsl:analyze-string select="." regex="(\.st[0-9]+\s)+\{{(.*)\}}">
<xsl:matching-substring><xsl:value-of select="concat(regex-group(1),'{',regex-group(2),';text-anchor: middle','}')"/></xsl:matching-substring>
<xsl:non-matching-substring><xsl:value-of select="."/></xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
<!-- treat text elements specially -->
<xsl:template match="svg:text[parent::svg:g]|svg:tspan[parent::svg:text[parent::svg:g]]">
<xsl:copy>
<xsl:apply-templates select="@*" mode="textAttr"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<!-- copy all arguments -->
<xsl:template match="@*" mode="textAttr">
<xsl:copy/>
</xsl:template>
<!-- special rule for x attributes, to center the text -->
<xsl:template match="@x" mode="textAttr">
<xsl:variable name="rect" select="ancestor::svg:g/svg:rect[1]"/>
<xsl:variable name="offset" select="$rect/@width div 2 - 0*$rect/@rx"/>
<xsl:attribute name="x"><xsl:value-of select="$offset"/></xsl:attribute>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment