GitBucket
4.21.2
Toggle navigation
Snippets
Sign in
Files
Branches
1
Releases
1
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
nigel.stanger
/
XML
Browse code
- Added omitted lower-case calls in layer exclusion code.
master
1 parent
0d07c0c
commit
655502a52f7f5d6177cc46e2f4641ff1a99546d4
nstanger
authored
on 29 Apr 2013
Patch
Showing
1 changed file
extract_svg_layers.xsl
Ignore Space
Show notes
View
extract_svg_layers.xsl
<?xml version="1.0" encoding="utf-8"?> <!-- Extract named layers of an SVG file into an new SVG file. This is particularly useful for images that have a base layer of objects with various different overlays. The entire image can be created as one file with each overlay on a separate layer, then only the required overlay layers plus the base layer are output. The base layer is assumed to be named "Base Layer" (case-insensitive). Arguments $base-layer: The case-insensitive name of the base layer, which will always be included. Omit if there is no base layer. $layers: A list of case-insensitive layer names. You can use any character as a separator, as long as it doesn't appear in any of the layer names. Comma would be usual. Pass "*" to include all layers (this obviously rules out "*" as an layer name!). $items: A list of case-insensitive SVG item IDs to extract from the base layer. ONLY these items are extracted from the base layer; everything else in the base layer is ignored. Pass "*" to include all items (this obviously rules out "*" as an item ID!). --> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:svg="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"> <xsl:output method="xml" encoding="UTF-8" standalone="no" /> <!-- The case-insensitive name of the base layer. Everything in the base layer will be included in the output, unless the $items parameter is set (see below). --> <xsl:param name="base-layer" /> <!-- The names of the layers to extract. Normally comma-separated, but any separator should work, as long as it doesn't appear in any of the layer names. Watch out for blanks in layer names when passing this from the command line! Note that the base layer is ALWAYS included in the output. Pass "*" to include all layers (default). --> <xsl:param name="layers">*</xsl:param> <!-- A list of the *base layer* item IDs to extract. ONLY items that appear in this list will be extracted. Pass "*" to include all items (default). --> <xsl:param name="items">*</xsl:param> <!-- Identity transformation. --> <xsl:template match="@*|node()"> <!-- Copy the current node --> <xsl:copy> <!-- Including any attributes it has and any child nodes --> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <!-- Always output the base layer. XPath explanation @inkscape:groupmode = 'layer' This is a layer. lower-case( @inkscape:label ) = lower-case( $base-layer ) This is the base layer. --> <xsl:template name="output-base-layer" match="svg:g[ ( @inkscape:groupmode = 'layer' ) and ( lower-case( @inkscape:label ) = lower-case( $base-layer ) ) ]" priority="10"> <!-- Copy the current node --> <xsl:copy> <!-- Including any attributes it has and any child nodes --> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <!-- Ignore base layer items not included in the items list. The basic list of item types appears to be svg:rect, svg:text, svg:path (anything other than a rect or text) and svg:g (group). We only consider "top-level" elements within the layer, otherwise the number of potential element IDs could explode massively. This could will be tricky if we ever decide that we want to omit an item that appears inside a group. XPath explanation @inkscape:groupmode = 'layer' See output-base-layer template above. ( lower-case( @inkscape:label ) = lower-case( $base-layer ) ) or ( $layers = '*' ) Either this is the base layer, or we're outputting all layers anyway. .../element()[...] All immediate child elements of the base layer. contains( 'svg:g|svg:path|svg:rect|svg:text', string( node-name ( . ) ) ) The current child element is one those listed. not( contains( lower-case( $items ), lower-case( @id ) ) ) The current child node's ID isn't in the items list. $items != '*' We're not outputting all items. --> <xsl:template name="ignore-items" match="svg:g[ ( @inkscape:groupmode = 'layer' ) and ( ( lower-case( @inkscape:label ) = lower-case( $base-layer ) ) or ( $layers = '*' ) ) ]/element()[ contains( 'svg:g|svg:path|svg:rect|svg:text', string( node-name ( . ) ) ) and not( contains( lower-case( $items ), lower-case( @id ) ) ) and ( $items != '*' ) ]" /> <!-- Ignore layers that aren't in the list of layers. XPath explanation @inkscape:groupmode = 'layer' See output-base-layer template above. $layers != '*' We're not outputting all layers not( contains ( $layers, @inkscape:label ) ) The layer's label isn't in the list of layers. --> <xsl:template name="ignore-layers" match="svg:g[ ( @inkscape:groupmode = 'layer' ) and ( $layers != '*') and not( contains ( lower-case( $layers ), lower-case( @inkscape:label ) ) ) ]" /> <!-- Ensure that extracted layers are always visible, regardless of their setting in the original file. XPath explanation @inkscape:groupmode = 'layer' See output-base-layer template above. @style[. = 'display:none'] This layer is invisible. --> <xsl:template name="make-layers-visible" match="svg:g[@inkscape:groupmode = 'layer']/@style[. = 'display:none']"> <xsl:attribute name="style"> <xsl:text>display:inline</xsl:text> </xsl:attribute> </xsl:template> </xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?> <!-- Extract named layers of an SVG file into an new SVG file. This is particularly useful for images that have a base layer of objects with various different overlays. The entire image can be created as one file with each overlay on a separate layer, then only the required overlay layers plus the base layer are output. The base layer is assumed to be named "Base Layer" (case-insensitive). Arguments $base-layer: The case-insensitive name of the base layer, which will always be included. Omit if there is no base layer. $layers: A list of case-insensitive layer names. You can use any character as a separator, as long as it doesn't appear in any of the layer names. Comma would be usual. Pass "*" to include all layers (this obviously rules out "*" as an layer name!). $items: A list of case-insensitive SVG item IDs to extract from the base layer. ONLY these items are extracted from the base layer; everything else in the base layer is ignored. Pass "*" to include all items (this obviously rules out "*" as an item ID!). --> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:svg="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"> <xsl:output method="xml" encoding="UTF-8" standalone="no" /> <!-- The case-insensitive name of the base layer. Everything in the base layer will be included in the output, unless the $items parameter is set (see below). --> <xsl:param name="base-layer" /> <!-- The names of the layers to extract. Normally comma-separated, but any separator should work, as long as it doesn't appear in any of the layer names. Watch out for blanks in layer names when passing this from the command line! Note that the base layer is ALWAYS included in the output. Pass "*" to include all layers (default). --> <xsl:param name="layers">*</xsl:param> <!-- A list of the *base layer* item IDs to extract. ONLY items that appear in this list will be extracted. Pass "*" to include all items (default). --> <xsl:param name="items">*</xsl:param> <!-- Identity transformation. --> <xsl:template match="@*|node()"> <!-- Copy the current node --> <xsl:copy> <!-- Including any attributes it has and any child nodes --> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <!-- Always output the base layer. XPath explanation @inkscape:groupmode = 'layer' This is a layer. lower-case( @inkscape:label ) = lower-case( $base-layer ) This is the base layer. --> <xsl:template name="output-base-layer" match="svg:g[ ( @inkscape:groupmode = 'layer' ) and ( lower-case( @inkscape:label ) = lower-case( $base-layer ) ) ]" priority="10"> <!-- Copy the current node --> <xsl:copy> <!-- Including any attributes it has and any child nodes --> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <!-- Ignore base layer items not included in the items list. The basic list of item types appears to be svg:rect, svg:text, svg:path (anything other than a rect or text) and svg:g (group). We only consider "top-level" elements within the layer, otherwise the number of potential element IDs could explode massively. This could will be tricky if we ever decide that we want to omit an item that appears inside a group. XPath explanation @inkscape:groupmode = 'layer' See output-base-layer template above. ( lower-case( @inkscape:label ) = lower-case( $base-layer ) ) or ( $layers = '*' ) Either this is the base layer, or we're outputting all layers anyway. .../element()[...] All immediate child elements of the base layer. contains( 'svg:g|svg:path|svg:rect|svg:text', string( node-name ( . ) ) ) The current child element is one those listed. not( contains( lower-case( $items ), lower-case( @id ) ) ) The current child node's ID isn't in the items list. $items != '*' We're not outputting all items. --> <xsl:template name="ignore-items" match="svg:g[ ( @inkscape:groupmode = 'layer' ) and ( ( lower-case( @inkscape:label ) = lower-case( $base-layer ) ) or ( $layers = '*' ) ) ]/element()[ contains( 'svg:g|svg:path|svg:rect|svg:text', string( node-name ( . ) ) ) and not( contains( lower-case( $items ), lower-case( @id ) ) ) and ( $items != '*' ) ]" /> <!-- Ignore layers that aren't in the list of layers. XPath explanation @inkscape:groupmode = 'layer' See output-base-layer template above. $layers != '*' We're not outputting all layers not( contains ( $layers, @inkscape:label ) ) The layer's label isn't in the list of layers. --> <xsl:template name="ignore-layers" match="svg:g[ ( @inkscape:groupmode = 'layer' ) and ( $layers != '*') and not( contains ( $layers, @inkscape:label ) ) ]" /> <!-- Ensure that extracted layers are always visible, regardless of their setting in the original file. XPath explanation @inkscape:groupmode = 'layer' See output-base-layer template above. @style[. = 'display:none'] This layer is invisible. --> <xsl:template name="make-layers-visible" match="svg:g[@inkscape:groupmode = 'layer']/@style[. = 'display:none']"> <xsl:attribute name="style"> <xsl:text>display:inline</xsl:text> </xsl:attribute> </xsl:template> </xsl:stylesheet>
Show line notes below