File: /home/frenchy/www/french-american.org/current/node_modules/svg-cleaner/docs/svg-cleaner.html
<!DOCTYPE html> <html> <head> <title>svg-cleaner.js</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" media="all" href="docco.css" /> </head> <body> <div id="container"> <div id="background"></div> <table cellpadding="0" cellspacing="0"> <thead> <tr> <th class="docs"> <h1> svg-cleaner.js </h1> </th> <th class="code"> </th> </tr> </thead> <tbody> <tr id="section-1"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-1">¶</a> </div> <h2>SVG Cleaner</h2>
<p>A tool for cleaning SVG Files - (yet partial) port of Scour to JavaScript.</p>
<p>Visit the original <a href="http://codedread.com/scour/">Scour - an SVG scrubber, http://codedread.com/scour/</a></p>
<p>Scour was created by Jeff Schiller.</p>
<p>Please note that this is a partial port, which means it is not finsihed at all.
For thoose who want to clean their SVG files and have them as clean as possible
as I highly recommend to use the original Scour.py.
(Please see the list of implemented and missing processing steps below.)</p>
<h2>License</h2>
<p>SVG Cleaner
Copyright 2012 Michael Schieben</p>
<p>Scour
Copyright 2010 Jeff Schiller
Copyright 2010 Louis Simard</p>
<p>Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at</p>
<p>http://www.apache.org/licenses/LICENSE-2.0</p>
<p>Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.</p>
<h2>About the port</h2>
<p>I needed a library to work with <a href="http://github.com/preciousforever/SVG-Stacker">SVG-Stacker</a>,
that could rename IDs and keep the references inside the SVG document structure intact.
SVG-Stacker merges different svg files and needs to make sure that the ids from different
files are unique in the merged version. If found that Scour implemented that feature.</p>
<p>The goal of the port was to bring the power of Scour to the JavaScript world, make it
available as commandline tool and usable as module for node.js.</p>
<p>I tried to keep the ideas and way how Scour cleans SVG files. I translated the processing steps
and copied most of the original comments from scour into the new source code, as they describe
the original ideas best. I marked all of these orginial comments by putting 'Scour:' in the first
line an used the markdown syntax for quotes (>). </p>
<ul>
<li>Missing processing steps are marked with an comment '@missing'.</li>
<li>Changed processing steps are marked with an comment containern '@extended' or '@changed'</li>
<li>Some functions and variable names are changed to (hopefully) be more descriptive.</li>
</ul> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-2"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-2">¶</a> </div> <h2>Implemented</h2>
<ul>
<li>Removal of namespaced elements and attributes</li>
<li>Removal of comments</li>
<li>Repairation of styles</li>
<li>Removal of unreferenced elements</li>
<li>Removal of empty elements</li>
<li>Removal of unused attributes</li>
<li>Shortening of id attribute values</li>
</ul> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-3"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-3">¶</a> </div> <h2>Missing</h2>
<ul>
<li>remove the xmlns: declarations now</li>
<li>ensure namespace for SVG is declared</li>
<li>check for redundant SVG namespace declaration</li>
<li>convert colors to #RRGGBB format</li>
<li>remove <metadata> if the user wants to</li>
<li>flattend defs elements into just one defs element</li>
<li>removeDuplicateGradientStops();</li>
<li>remove gradients that are only referenced by one other gradient</li>
<li>remove duplicate gradients</li>
<li>createGroupsForCommonAttributes()</li>
<li>move common attributes to parent group</li>
<li>remove unused attributes from parent</li>
<li>moveAttributesToParentGroup</li>
<li>remove unnecessary closing point of polygons and scour points</li>
<li>scour points of polyline</li>
<li>clean path data</li>
<li>scour lengths (including coordinates)</li>
<li>reducePrecision</li>
<li>removeDefaultAttributeValues</li>
<li>optimizeTransforms</li>
<li>convert rasters references to base64-encoded strings</li>
<li>properly size the SVG document</li>
</ul> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-4"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-4">¶</a> </div> <h2>Original Notes from Scour</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-5"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-5">¶</a> </div> <p>Scour:</p>
<blockquote>
<p>Notes:</p>
<p>rubys' path-crunching ideas here: <a href="">http://intertwingly.net/code/svgtidy/spec.rb</a>
(and implemented here: http://intertwingly.net/code/svgtidy/svgtidy.rb )</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-6"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-6">¶</a> </div> <blockquote>
<p>Yet more ideas here: <a href="http://wiki.inkscape.org/wiki/index.php/Save_Cleaned_SVG">Inkscape Wiki</a></p>
<ul>
<li>Process Transformations
<ul><li>Collapse all group based transformations</li></ul></li>
</ul>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-7"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-7">¶</a> </div> <blockquote>
<p>Even more ideas here: <a href="">http://esw.w3.org/topic/SvgTidy</a></p>
<ul>
<li>analysis of path elements to see if rect can be used instead? (must also need to look
at rounded corners)</li>
</ul>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-8"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-8">¶</a> </div> <blockquote>
<p>Next Up:</p>
<ul>
<li>why are marker-start, -end not removed from the style attribute?</li>
<li>why are only overflow style properties considered and not attributes?</li>
<li>only remove unreferenced elements if they are not children of a referenced element</li>
<li>add an option to remove ids if they match the Inkscape-style of IDs</li>
<li>investigate point-reducing algorithms</li>
<li>parse transform attribute</li>
<li>if a <g> has only one element in it, collapse the <g> (ensure transform, etc are carried down)</li>
</ul>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-9"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-9">¶</a> </div> <h2>Implementation</h2> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">_</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'underscore'</span><span class="p">)</span>
<span class="p">,</span> <span class="nx">fs</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'fs'</span><span class="p">)</span>
<span class="p">,</span> <span class="nx">cheerio</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'cheerio'</span><span class="p">)</span>
<span class="p">,</span> <span class="nx">CSSOM</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'cssom'</span><span class="p">)</span>
<span class="p">,</span> <span class="nx">$</span>
<span class="p">;</span></pre></div> </td> </tr> <tr id="section-10"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-10">¶</a> </div> <p>Namespace Prefixes that should be removed</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">namespacePrefixes</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'dc'</span><span class="p">,</span> <span class="s1">'rdf'</span><span class="p">,</span> <span class="s1">'sodipodi'</span><span class="p">,</span> <span class="s1">'cc'</span><span class="p">,</span> <span class="s1">'inkscape'</span><span class="p">];</span></pre></div> </td> </tr> <tr id="section-11"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-11">¶</a> </div> <hr />
<h2>Sanitize References</h2> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-12"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-12">¶</a> </div> <p>Scour:
Removes the unreferenced ID attributes.</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">removeUnreferencedIDs</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">identifiedElements</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'[id]'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">referencedIDs</span> <span class="o">=</span> <span class="nx">findReferencedElements</span><span class="p">();</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">identifiedElements</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span><span class="err"> </span><span class="p">{</span>
<span class="kd">var</span> <span class="nx">$node</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">referencedIDs</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">id</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">$node</span><span class="p">.</span><span class="nx">removeAttr</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span>
<span class="p">};</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-13"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-13">¶</a> </div> <p>Style-Properties and Element-Attributes that might contain an id, a reference to another object</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">referencingProperties</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'fill'</span><span class="p">,</span> <span class="s1">'stroke'</span><span class="p">,</span> <span class="s1">'filter'</span><span class="p">,</span> <span class="s1">'clip-path'</span><span class="p">,</span> <span class="s1">'mask'</span><span class="p">,</span> <span class="s1">'marker-start'</span><span class="p">,</span> <span class="s1">'marker-end'</span><span class="p">,</span> <span class="s1">'marker-mid'</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">REFERENCE_TYPE</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">STYLE_TAG</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
<span class="nx">XLINK</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span>
<span class="nx">STYLE_ATTRIBUTE</span><span class="o">:</span> <span class="mi">2</span><span class="p">,</span>
<span class="nx">ATTRIBUTE</span><span class="o">:</span> <span class="mi">4</span>
<span class="p">};</span>
<span class="kd">function</span> <span class="nx">addReferencingElement</span><span class="p">(</span><span class="nx">ids</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">referenceType</span><span class="p">,</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">additionalInfo</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">id</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/#/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">ids</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">id</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">ids</span><span class="p">[</span><span class="nx">id</span><span class="p">]</span> <span class="o">=</span> <span class="p">[];</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">additionalInfo</span><span class="p">).</span><span class="nx">isUndefined</span><span class="p">())</span> <span class="p">{</span>
<span class="nx">additionalInfo</span> <span class="o">=</span> <span class="p">[];</span>
<span class="p">}</span>
<span class="nx">ids</span><span class="p">[</span><span class="nx">id</span><span class="p">].</span><span class="nx">push</span><span class="p">([</span><span class="nx">referenceType</span><span class="p">,</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">additionalInfo</span><span class="p">]);</span>
<span class="k">return</span> <span class="nx">ids</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-14"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-14">¶</a> </div> <p>extracts #id out of CSS url('#id')</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">extractReferencedId</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">v</span> <span class="o">=</span> <span class="nx">value</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/[\s]/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">v</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="s1">'url'</span><span class="p">)</span> <span class="o">!==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">value</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/[\s]/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">).</span><span class="nx">slice</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">).</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/["']/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-15"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-15">¶</a> </div> <p>replaced #fromid in CSS url('#fromid') to url('#toid')</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">replaceReferencedId</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">idFrom</span><span class="p">,</span> <span class="nx">idTo</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">re</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">'url\\([\'"]?#'</span> <span class="o">+</span> <span class="nx">idFrom</span> <span class="o">+</span> <span class="s1">'[\'"]?\\)'</span><span class="p">,</span> <span class="s1">'g'</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">value</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">re</span><span class="p">,</span> <span class="s2">"url(#"</span> <span class="o">+</span> <span class="nx">idTo</span> <span class="o">+</span> <span class="s2">")"</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-16"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-16">¶</a> </div> <p>Scour:</p>
<blockquote>
<p>Returns the number of times an ID is referenced as well as all elements
that reference it. node is the node at which to start the search. The
return value is a map which has the id as key and each value is an array
where the first value is a count and the second value is a list of nodes
that referenced it.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">findReferencedElements</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">ids</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'*'</span><span class="p">)).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$node</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">==</span> <span class="s1">'style'</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">styles</span> <span class="o">=</span> <span class="nx">CSSOM</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">$node</span><span class="p">.</span><span class="nx">text</span><span class="p">());</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">.</span><span class="nx">cssRules</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">rule</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">referencingProperties</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">referencingProperty</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">rule</span><span class="p">.</span><span class="nx">style</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">referencingProperty</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">extractReferencedId</span><span class="p">(</span><span class="nx">rule</span><span class="p">.</span><span class="nx">style</span><span class="p">[</span><span class="nx">referencingProperty</span><span class="p">]);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">addReferencingElement</span><span class="p">(</span><span class="nx">ids</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">STYLE_TAG</span><span class="p">,</span> <span class="nx">node</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-17"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-17">¶</a> </div> <p>if xlink:href is set, then grab the id</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">href</span> <span class="o">=</span> <span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'xlink:href'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">href</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">addReferencingElement</span><span class="p">(</span><span class="nx">ids</span><span class="p">,</span> <span class="nx">href</span><span class="p">,</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">XLINK</span><span class="p">,</span> <span class="nx">node</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-18"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-18">¶</a> </div> <p>now get all style properties</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">styles</span> <span class="o">=</span> <span class="nx">parseStyles</span><span class="p">(</span><span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'style'</span><span class="p">));</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">referencingProperties</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">referencingProperty</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-19"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-19">¶</a> </div> <p>first check attributes</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="nx">referencingProperty</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">value</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">extractReferencedId</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">addReferencingElement</span><span class="p">(</span><span class="nx">ids</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">ATTRIBUTE</span><span class="p">,</span> <span class="nx">node</span><span class="p">,</span> <span class="nx">referencingProperty</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-20"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-20">¶</a> </div> <p>then inline styles</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">referencingProperty</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">extractReferencedId</span><span class="p">(</span><span class="nx">styles</span><span class="p">[</span><span class="nx">referencingProperty</span><span class="p">]);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">addReferencingElement</span><span class="p">(</span><span class="nx">ids</span><span class="p">,</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">STYLE_ATTRIBUTE</span><span class="p">,</span> <span class="nx">node</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">ids</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-21"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-21">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Shortens ID names used in the document. ID names referenced the most often are assigned the
shortest ID names.
@missing scour:
If the list unprotectedElements is provided, only IDs from this list will be shortened.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">shortenIDs</span><span class="p">(</span><span class="nx">startNumber</span><span class="p">)</span><span class="err"> </span><span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">startNumber</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">startNumber</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">$identifiedElements</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'[id]'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">referencedIDs</span> <span class="o">=</span> <span class="nx">findReferencedElements</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-22"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-22">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Make idList (list of idnames) sorted by reference count
descending, so the highest reference count is first.
First check that there's actually a defining element for the current ID name.
(Cyn: I've seen documents with #id references but no element with that ID!)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">idList</span> <span class="o">=</span> <span class="nx">_</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">referencedIDs</span><span class="p">).</span><span class="nx">keys</span><span class="p">()).</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">$identifiedElements</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">'#'</span> <span class="o">+</span> <span class="nx">id</span><span class="p">).</span><span class="nx">size</span><span class="p">()</span> <span class="o">></span> <span class="mi">0</span><span class="p">);</span>
<span class="p">});</span>
<span class="nx">idList</span> <span class="o">=</span> <span class="nx">_</span><span class="p">(</span><span class="nx">idList</span><span class="p">).</span><span class="nx">sortBy</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">referencedIDs</span><span class="p">[</span><span class="nx">id</span><span class="p">].</span><span class="nx">length</span><span class="p">;</span>
<span class="p">}).</span><span class="nx">reverse</span><span class="p">();</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">idList</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">shortendID</span> <span class="o">=</span> <span class="nx">intToID</span><span class="p">(</span><span class="nx">startNumber</span><span class="o">++</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-23"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-23">¶</a> </div> <p>scour:</p>
<blockquote>
<p>First make sure that <em>this</em> element isn't already using
the ID name we want to give it.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">id</span> <span class="o">==</span> <span class="nx">shortendID</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-24"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-24">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Then, skip ahead if the new ID is already in identifiedElement</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="k">while</span><span class="p">(</span><span class="nx">$identifiedElements</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">'#'</span> <span class="o">+</span> <span class="nx">shortendID</span><span class="p">).</span><span class="nx">size</span><span class="p">()</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">shortendID</span> <span class="o">=</span> <span class="nx">intToID</span><span class="p">(</span><span class="nx">startNumber</span><span class="o">++</span><span class="p">);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-25"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-25">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Then go rename it.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">renameID</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">shortendID</span><span class="p">,</span> <span class="nx">$identifiedElements</span><span class="p">,</span> <span class="nx">referencedIDs</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-26"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-26">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Returns the ID name for the given ID number, spreadsheet-style, i.e. from a to z,
then from aa to az, ba to bz, etc., until zz.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">intToID</span><span class="p">(</span><span class="nx">num</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">idName</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="nx">num</span> <span class="o">></span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">num</span><span class="o">--</span><span class="p">;</span>
<span class="nx">idName</span> <span class="o">=</span> <span class="nb">String</span><span class="p">.</span><span class="nx">fromCharCode</span><span class="p">((</span><span class="nx">num</span> <span class="o">%</span> <span class="mi">26</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'a'</span><span class="p">.</span><span class="nx">charCodeAt</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span> <span class="o">+</span> <span class="nx">idName</span><span class="p">;</span>
<span class="nx">num</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nx">num</span> <span class="o">/</span> <span class="mi">26</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">idName</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-27"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-27">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Changes the ID name from idFrom to idTo, on the declaring element
as well as all references in the document doc.</p>
<p>Updates identifiedElements and referencedIDs.
Does not handle the case where idTo is already the ID name
of another element in doc.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">renameID</span><span class="p">(</span><span class="nx">idFrom</span><span class="p">,</span> <span class="nx">idTo</span><span class="p">,</span> <span class="nx">$identifiedElements</span><span class="p">,</span> <span class="nx">referencedIDs</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$definingNode</span> <span class="o">=</span> <span class="nx">$identifiedElements</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="s1">'#'</span> <span class="o">+</span> <span class="nx">idFrom</span><span class="p">);</span>
<span class="nx">$definingNode</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'id'</span><span class="p">,</span> <span class="nx">idTo</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">referringNodes</span> <span class="o">=</span> <span class="nx">referencedIDs</span><span class="p">[</span><span class="nx">idFrom</span><span class="p">];</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">referringNodes</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">referenceTypeNodeAndAdditionalInfos</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">property</span> <span class="o">=</span> <span class="nx">referenceTypeNodeAndAdditionalInfos</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">node</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">referenceTypeNodeAndAdditionalInfos</span><span class="p">[</span><span class="mi">1</span><span class="p">]);</span>
<span class="k">switch</span><span class="p">(</span><span class="nx">property</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">STYLE_TAG</span><span class="o">:</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">text</span><span class="p">(</span><span class="nx">replaceReferencedId</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">text</span><span class="p">(),</span> <span class="nx">idFrom</span><span class="p">,</span> <span class="nx">idTo</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">XLINK</span><span class="o">:</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'xlink:href'</span><span class="p">,</span> <span class="s1">'#'</span> <span class="o">+</span> <span class="nx">idTo</span><span class="p">);</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">STYLE_ATTRIBUTE</span><span class="o">:</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'style'</span><span class="p">,</span> <span class="nx">replaceReferencedId</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'style'</span><span class="p">),</span> <span class="nx">idFrom</span><span class="p">,</span> <span class="nx">idTo</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">case</span> <span class="nx">REFERENCE_TYPE</span><span class="p">.</span><span class="nx">ATTRIBUTE</span><span class="o">:</span>
<span class="kd">var</span> <span class="nx">attributeName</span> <span class="o">=</span> <span class="nx">referenceTypeNodeAndAdditionalInfos</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="nx">node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="nx">attributeName</span><span class="p">,</span> <span class="nx">replaceReferencedId</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="nx">attributeName</span><span class="p">),</span> <span class="nx">idFrom</span><span class="p">,</span> <span class="nx">idTo</span><span class="p">));</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">default</span><span class="o">:</span></pre></div> </td> </tr> <tr id="section-28"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-28">¶</a> </div> <p>unkonw reference_type</p> </td> <td class="code"> <div class="highlight"><pre> <span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-29"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-29">¶</a> </div> <p>scour:</p>
<blockquote>
<p>removes all unreferenced elements except for <code><svg>, <font>, <metadata>, <title>, and <desc></code>.
Also vacuums the defs of any non-referenced renderable elements.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">removeUnreferencedElements</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">referencedIDs</span> <span class="o">=</span> <span class="nx">findReferencedElements</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">alwaysKeepTags</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'font'</span><span class="p">,</span> <span class="s1">'style'</span><span class="p">,</span> <span class="s1">'metadata'</span><span class="p">,</span> <span class="s1">'script'</span><span class="p">,</span> <span class="s1">'title'</span><span class="p">,</span> <span class="s1">'desc'</span><span class="p">];</span>
<span class="kd">function</span> <span class="nx">removeUnreferencedElementsInTag</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">children</span><span class="p">()).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
</pre></div> </td> </tr> <tr id="section-30"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-30">¶</a> </div> <p>scour:</p>
<blockquote>
<p>we only remove if it is not one of our tags we always keep (see above)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">alwaysKeepTags</span><span class="p">).</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span><span class="p">)</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">$node</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">referencedIDs</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">id</span><span class="p">))</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span> <span class="o">==</span> <span class="s1">'g'</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-31"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-31">¶</a> </div> <p>scour:</p>
<blockquote>
<p>we only inspect the children of a group in a defs if the group
is not referenced anywhere else</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">removeUnreferencedElementsInTag</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span><span class="err"> </span><span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">remove</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-32"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-32">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Remove most unreferenced elements inside defs</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'defs'</span><span class="p">)).</span><span class="nx">each</span><span class="p">(</span><span class="nx">removeUnreferencedElementsInTag</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-33"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-33">¶</a> </div> <p>scour:</p>
<blockquote>
<p>Remove certain unreferenced elements outside of defs</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">identifiedElements</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'* > linearGradient[id], * > radialGradient[id], * > pattern[id]'</span><span class="p">);</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">identifiedElements</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">id</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'id'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">referencedIDs</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">id</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">remove</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-34"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-34">¶</a> </div> <hr /> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-35"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-35">¶</a> </div> <h2>Namspace</h2> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">removeNamespacedElements</span><span class="p">(</span><span class="nx">namespacesToRemove</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">namespacedElements</span> <span class="o">=</span> <span class="nx">_</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'*'</span><span class="p">)).</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">$node</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="k">if</span><span class="p">(</span><span class="nx">$node</span><span class="p">.</span><span class="nx">type</span> <span class="o">!==</span> <span class="s1">'tag'</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">namespaceTagName</span> <span class="o">=</span> <span class="nx">$node</span><span class="p">.</span><span class="nx">name</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">':'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">namespaceTagName</span><span class="p">.</span><span class="nx">length</span> <span class="o"><</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">namespacesToRemove</span><span class="p">,</span> <span class="nx">namespaceTagName</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">namespacedElements</span><span class="p">).</span><span class="nx">remove</span><span class="p">();</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">removeNamespacedAttributes</span><span class="p">(</span><span class="nx">namespacesToRemove</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'*'</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">ix</span><span class="p">,</span> <span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">attribs</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">namespaceAtrributeName</span> <span class="o">=</span> <span class="nx">key</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">':'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">namespaceAtrributeName</span><span class="p">.</span><span class="nx">length</span> <span class="o"><</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">namespacesToRemove</span><span class="p">,</span> <span class="nx">namespaceAtrributeName</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">!==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">removeAttr</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-36"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-36">¶</a> </div> <hr /> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-37"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-37">¶</a> </div> <h2>Comments</h2> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">removeComments</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">commentNodes</span> <span class="o">=</span> <span class="p">[];</span></pre></div> </td> </tr> <tr id="section-38"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-38">¶</a> </div> <p>process on NODE level</p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">function</span> <span class="nx">searchForComment</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">==</span> <span class="s1">'comment'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">commentNodes</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">node</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="p">).</span><span class="nx">isUndefined</span><span class="p">())</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="p">,</span> <span class="nx">searchForComment</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">searchForComment</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">_root</span><span class="p">);</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">commentNodes</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">remove</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-39"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-39">¶</a> </div> <hr /> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-40"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-40">¶</a> </div> <h2>Repair Style</h2> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">mayContainTextNode</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">elementsThatDontContainText</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'rect'</span><span class="p">,</span> <span class="s1">'circle'</span><span class="p">,</span> <span class="s1">'ellipse'</span><span class="p">,</span> <span class="s1">'line'</span><span class="p">,</span> <span class="s1">'polygon'</span><span class="p">,</span> <span class="s1">'polyline'</span><span class="p">,</span> <span class="s1">'path'</span><span class="p">,</span> <span class="s1">'image'</span><span class="p">,</span> <span class="s1">'stop'</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">elementsThatCouldContainText</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'g'</span><span class="p">,</span> <span class="s1">'clipPath'</span><span class="p">,</span> <span class="s1">'marker'</span><span class="p">,</span> <span class="s1">'mask'</span><span class="p">,</span> <span class="s1">'pattern'</span><span class="p">,</span> <span class="s1">'linearGradient'</span><span class="p">,</span> <span class="s1">'radialGradient'</span><span class="p">,</span> <span class="s1">'symbol'</span><span class="p">];</span>
<span class="k">if</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">type</span> <span class="o">==</span> <span class="s1">'comment'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">result</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">elementsThatDontContainText</span><span class="p">).</span><span class="nx">include</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">result</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">elementsThatCouldContainText</span><span class="p">).</span><span class="nx">include</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">name</span><span class="p">))</span> <span class="p">{</span>
<span class="nx">result</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="p">).</span><span class="nx">isUndefined</span><span class="p">()</span> <span class="o">&&</span> <span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">result</span> <span class="o">=</span> <span class="nx">_</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="p">).</span><span class="nx">any</span><span class="p">(</span><span class="nx">mayContainTextNode</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-41"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-41">¶</a> </div> <p>returns a float without the unit</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">styleValue</span><span class="p">(</span><span class="nx">string</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">string</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/[^-\d\.]/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-42"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-42">¶</a> </div> <p>removes properties, by a given list of keys</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">properties</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">properties</span><span class="p">).</span><span class="nx">include</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
<span class="k">delete</span> <span class="nx">styles</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">styles</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-43"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-43">¶</a> </div> <p>a simple CSS parser, returns object with {property: value}</p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">parseStyles</span><span class="p">(</span><span class="nx">inlineStyles</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">styles</span> <span class="o">=</span> <span class="p">{};</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">.</span><span class="nx">isUndefined</span><span class="p">(</span><span class="nx">inlineStyles</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">styles</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">styleRules</span> <span class="o">=</span> <span class="nx">inlineStyles</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">';'</span><span class="p">);</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">styleRules</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">style</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">keyValue</span> <span class="o">=</span> <span class="nx">style</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">':'</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">keyValue</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">styles</span><span class="p">[</span><span class="nx">keyValue</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/[\s]/g</span><span class="p">,</span> <span class="s1">''</span><span class="p">)]</span> <span class="o">=</span> <span class="nx">keyValue</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">styles</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">renderStyles</span><span class="p">(</span><span class="nx">styles</span><span class="p">)</span> <span class="p">{</span></pre></div> </td> </tr> <tr id="section-44"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-44">¶</a> </div> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">size</span><span class="p">())</span> <span class="p">{</span>
<span class="k">return</span> <span class="s1">''</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">inlineStyles</span> <span class="o">=</span> <span class="s1">''</span><span class="p">;</span>
<span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">property</span><span class="p">,</span> <span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">inlineStyles</span> <span class="o">+=</span> <span class="nx">value</span> <span class="o">+</span> <span class="s1">':'</span> <span class="o">+</span> <span class="nx">property</span> <span class="o">+</span> <span class="s1">';'</span><span class="p">;</span>
<span class="p">});</span>
<span class="k">return</span> <span class="nx">inlineStyles</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">repairStyles</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'*'</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">ix</span><span class="p">,</span> <span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">repairStyle</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">));</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">repairStyle</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span><span class="err"> </span><span class="p">{</span>
<span class="kd">var</span> <span class="nx">$node</span> <span class="o">=</span> <span class="nx">node</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">styles</span> <span class="o">=</span> <span class="nx">parseStyles</span><span class="p">(</span><span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'style'</span><span class="p">));</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">size</span><span class="p">())</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-45"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-45">¶</a> </div> <p>scour:</p>
<blockquote>
<p>I've seen this enough to know that I need to correct it:
<code>fill: url(#linearGradient4918) rgb(0, 0, 0);</code></p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">_</span><span class="p">.</span><span class="nx">each</span><span class="p">([</span><span class="s1">'fill'</span><span class="p">,</span> <span class="s1">'stroke'</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">property</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="nx">property</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">chunk</span> <span class="o">=</span> <span class="nx">styles</span><span class="p">[</span><span class="nx">property</span><span class="p">].</span><span class="nx">split</span><span class="p">(</span><span class="s1">') '</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">chunk</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">2</span> <span class="o">&&</span> <span class="nx">chunk</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">substr</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">==</span> <span class="s1">'url(#'</span> <span class="o">||</span> <span class="nx">chunk</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">substr</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="o">==</span> <span class="s1">'url("#'</span> <span class="o">||</span> <span class="nx">chunk</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">substr</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="o">==</span> <span class="s2">"url('#"</span> <span class="o">&&</span> <span class="nx">chunk</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'rgb(0, 0, 0)'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">styles</span><span class="p">[</span><span class="nx">property</span><span class="p">]</span> <span class="o">=</span> <span class="nx">chunk</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="s1">')'</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">var</span> <span class="nx">STYLE_PROPERTIES</span> <span class="o">=</span> <span class="p">[];</span>
<span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'stroke'</span><span class="p">,</span> <span class="s1">'stroke-width'</span><span class="p">,</span> <span class="s1">'stroke-linejoin'</span><span class="p">,</span> <span class="s1">'stroke-opacity'</span><span class="p">,</span> <span class="s1">'stroke-miterlimit'</span><span class="p">,</span> <span class="s1">'stroke-linecap'</span><span class="p">,</span> <span class="s1">'stroke-dasharray'</span><span class="p">,</span> <span class="s1">'stroke-dashoffset'</span><span class="p">,</span> <span class="s1">'stroke-opacity'</span><span class="p">];</span>
<span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'fill'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'fill'</span><span class="p">,</span> <span class="s1">'fill-opacity'</span><span class="p">,</span> <span class="s1">'fill-rule'</span><span class="p">];</span>
<span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'text'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">'font-family'</span><span class="p">,</span> <span class="s1">'font-size'</span><span class="p">,</span> <span class="s1">'font-stretch'</span><span class="p">,</span> <span class="s1">'font-size-adjust'</span><span class="p">,</span> <span class="s1">'font-style'</span><span class="p">,</span> <span class="s1">'font-variant'</span><span class="p">,</span> <span class="s1">'font-weight'</span><span class="p">,</span> <span class="s1">'letter-spacing'</span><span class="p">,</span> <span class="s1">'line-height'</span><span class="p">,</span> <span class="s1">'kerning'</span><span class="p">,</span> <span class="s1">'text-align'</span><span class="p">,</span> <span class="s1">'text-anchor'</span><span class="p">,</span> <span class="s1">'text-decoration'</span><span class="p">,</span> <span class="s1">'text-rendering'</span><span class="p">,</span> <span class="s1">'unicode-bidi'</span><span class="p">,</span> <span class="s1">'word-spacing'</span><span class="p">,</span> <span class="s1">'writing-mode'</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">VENDOR_PREFIXES</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'-inkscape'</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">SVG_ATTRIBUTES</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'clip-rule'</span><span class="p">,</span> <span class="s1">'display'</span><span class="p">,</span> <span class="s1">'fill'</span><span class="p">,</span> <span class="s1">'fill-opacity'</span><span class="p">,</span> <span class="s1">'fill-rule'</span><span class="p">,</span> <span class="s1">'filter'</span><span class="p">,</span> <span class="s1">'font-family'</span><span class="p">,</span> <span class="s1">'font-size'</span><span class="p">,</span> <span class="s1">'font-stretch'</span><span class="p">,</span> <span class="s1">'font-style'</span><span class="p">,</span> <span class="s1">'font-variant'</span><span class="p">,</span> <span class="s1">'font-weight'</span><span class="p">,</span> <span class="s1">'line-height'</span><span class="p">,</span> <span class="s1">'marker'</span><span class="p">,</span> <span class="s1">'marker-end'</span><span class="p">,</span> <span class="s1">'marker-mid'</span><span class="p">,</span> <span class="s1">'marker-start'</span><span class="p">,</span> <span class="s1">'opacity'</span><span class="p">,</span> <span class="s1">'overflow'</span><span class="p">,</span> <span class="s1">'stop-color'</span><span class="p">,</span> <span class="s1">'stop-opacity'</span><span class="p">,</span> <span class="s1">'stroke'</span><span class="p">,</span> <span class="s1">'stroke-dasharray'</span><span class="p">,</span> <span class="s1">'stroke-dashoffset'</span><span class="p">,</span> <span class="s1">'stroke-linecap'</span><span class="p">,</span> <span class="s1">'stroke-linejoin'</span><span class="p">,</span> <span class="s1">'stroke-miterlimit'</span><span class="p">,</span> <span class="s1">'stroke-opacity'</span><span class="p">,</span> <span class="s1">'stroke-width'</span><span class="p">,</span> <span class="s1">'visibility'</span><span class="p">];</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'opacity'</span><span class="p">))</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">opacity</span> <span class="o">=</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">styles</span><span class="p">[</span><span class="s1">'opacity'</span><span class="p">]);</span>
<span class="k">if</span><span class="p">(</span><span class="nx">opacity</span> <span class="o">!=</span> <span class="mf">0.0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-46"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-46">¶</a> </div> <p>if opacity='0' then all fill and stroke properties are useless, remove them</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">_</span><span class="p">.</span><span class="nx">union</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">],</span> <span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'fill'</span><span class="p">]));</span>
<span class="p">}</span>
</pre></div> </td> </tr> <tr id="section-47"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-47">¶</a> </div> <p>if stroke:none, then remove all stroke-related properties (stroke-width, etc)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'stroke'</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">styles</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'none'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">]).</span><span class="nx">without</span><span class="p">(</span><span class="s1">'stroke'</span><span class="p">);</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">_</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">]).</span><span class="nx">without</span><span class="p">(</span><span class="s1">'stroke'</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-48"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-48">¶</a> </div> <p>if fill:none, then remove all fill-related properties (fill-rule, etc)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'fill'</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">styles</span><span class="p">[</span><span class="s1">'fill'</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'none'</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">_</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'fill'</span><span class="p">]).</span><span class="nx">without</span><span class="p">(</span><span class="s1">'fill'</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'fill-opacity'</span><span class="p">)</span> <span class="o">&&</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">styles</span><span class="p">[</span><span class="s1">'fill-opacity'</span><span class="p">])</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">_</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'fill'</span><span class="p">]).</span><span class="nx">without</span><span class="p">(</span><span class="s1">'fill-opacity'</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'stroke-opacity'</span><span class="p">)</span> <span class="o">&&</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">styles</span><span class="p">[</span><span class="s1">'stroke-opacity'</span><span class="p">])</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">_</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">]).</span><span class="nx">without</span><span class="p">(</span><span class="s1">'stroke-opacity'</span><span class="p">));</span>
<span class="p">}</span>
<span class="k">if</span><span class="p">(</span><span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">has</span><span class="p">(</span><span class="s1">'stroke-width'</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">styleValue</span><span class="p">(</span><span class="nx">styles</span><span class="p">[</span><span class="s1">'stroke-width'</span><span class="p">])</span> <span class="o">==</span> <span class="mf">0.0</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">_</span><span class="p">(</span><span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'stroke'</span><span class="p">]).</span><span class="nx">without</span><span class="p">(</span><span class="s1">'stroke-width'</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-49"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-49">¶</a> </div> <p>scour:</p>
<blockquote>
<p>remove font properties for non-text elements
I've actually observed this in real SVG content</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-50"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-50">¶</a> </div> <p>removes all text styles, if node does not contain text</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">mayContainTextNode</span><span class="p">(</span><span class="nx">node</span><span class="p">[</span><span class="mi">0</span><span class="p">]))</span> <span class="p">{</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">STYLE_PROPERTIES</span><span class="p">[</span><span class="s1">'text'</span><span class="p">]);</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-51"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-51">¶</a> </div> <p>changed: removed style properties with a vendor prefix, like
<code>-inkscape-font-specification</code></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">stylesWithVendorPrefixes</span> <span class="o">=</span> <span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">keys</span><span class="p">().</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nx">_</span><span class="p">(</span><span class="nx">VENDOR_PREFIXES</span><span class="p">).</span><span class="nx">any</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">prefix</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">(</span><span class="nx">key</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">prefix</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="nx">styles</span> <span class="o">=</span> <span class="nx">removeStyleProperties</span><span class="p">(</span><span class="nx">styles</span><span class="p">,</span> <span class="nx">stylesWithVendorPrefixes</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-52"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-52">¶</a> </div> <p>@missing: scour also cleans overflow property</p>
<p>scour:</p>
<blockquote>
<p>overflow specified on element other than svg, marker, pattern
it is a marker, pattern or svg
as long as this node is not the document <svg>, then only
remove overflow='hidden'. See
http://www.w3.org/TR/2010/WD-SVG11-20100622/masking.html#OverflowProperty</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-53"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-53">¶</a> </div> <p>scour:</p>
<blockquote>
<p>now if any of the properties match known SVG attributes we prefer attributes
over style so emit them and remove them from the style map</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="k">if</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">styleToAttributes</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">styles</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">value</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">_</span><span class="p">(</span><span class="nx">SVG_ATTRIBUTES</span><span class="p">).</span><span class="nx">include</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">value</span><span class="p">);</span>
<span class="k">delete</span> <span class="nx">styles</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">$node</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'style'</span><span class="p">,</span> <span class="nx">renderStyles</span><span class="p">(</span><span class="nx">styles</span><span class="p">));</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-54"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-54">¶</a> </div> <hr /> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-55"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-55">¶</a> </div> <h2>Interface</h2> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">defaultOptions</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">styleToAttributes</span><span class="o">:</span> <span class="kc">true</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="p">{};</span></pre></div> </td> </tr> <tr id="section-56"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-56">¶</a> </div> <p>scour:</p>
<blockquote>
<p>this is the main method
input is a string representation of the input XML
returns a string representation of the output XML</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-57"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-57">¶</a> </div> <p>Main processing steps are implemented in SVGCleaner.prototype.clean()</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-58"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-58">¶</a> </div> <p>This method is to provide a simple interface so one could call
<code>var cleanedSvgString = require('svg-cleaner').clean(svgString, options)</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">clean</span><span class="p">(</span><span class="nx">svgString</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">aSVGCleaner</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SVGCleaner</span><span class="p">(</span><span class="nx">options</span><span class="p">);</span>
<span class="nx">aSVGCleaner</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="nx">svgString</span><span class="p">);</span>
<span class="k">return</span> <span class="nx">aSVGCleaner</span><span class="p">.</span><span class="nx">clean</span><span class="p">().</span><span class="nx">svgString</span><span class="p">();</span>
<span class="p">}</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">clean</span> <span class="o">=</span> <span class="nx">clean</span><span class="p">;</span></pre></div> </td> </tr> <tr id="section-59"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-59">¶</a> </div> <p>simple interface
<code>var cleanedSvgString = require('svg-cleaner').cleanFile(srcFilename, targetFilename, options)</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">function</span> <span class="nx">cleanFileSync</span><span class="p">(</span><span class="nx">srcFilename</span><span class="p">,</span> <span class="nx">targetFilename</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">SVGCleaner</span><span class="p">(</span><span class="nx">options</span><span class="p">)</span>
<span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">srcFilename</span><span class="p">)</span>
<span class="p">.</span><span class="nx">writeFileSync</span><span class="p">(</span><span class="nx">targetFilename</span><span class="p">)</span>
<span class="p">.</span><span class="nx">svgString</span><span class="p">()</span>
<span class="p">;</span>
<span class="p">}</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">cleanFile</span> <span class="o">=</span> <span class="nx">cleanFileSync</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">SVGCleaner</span><span class="p">(</span><span class="nx">_options</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">options</span><span class="p">).</span><span class="nx">extend</span><span class="p">(</span><span class="nx">defaultOptions</span><span class="p">,</span> <span class="nx">_options</span><span class="p">);</span>
<span class="k">this</span><span class="p">.</span><span class="nx">$</span> <span class="o">=</span> <span class="nx">cheerio</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">module</span><span class="p">.</span><span class="nx">exports</span><span class="p">.</span><span class="nx">createCleaner</span> <span class="o">=</span> <span class="nx">SVGCleaner</span><span class="p">;</span>
<span class="nx">SVGCleaner</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">load</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">svgString</span><span class="p">)</span><span class="err"> </span><span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="nx">$</span> <span class="o">=</span> <span class="nx">cheerio</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="nx">svgString</span><span class="p">,</span> <span class="p">{</span> <span class="nx">ignoreWhitespace</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">xmlMode</span><span class="o">:</span> <span class="kc">true</span> <span class="p">});</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">SVGCleaner</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">readFileSync</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">srcFilename</span><span class="p">)</span><span class="err"> </span><span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="nx">fs</span><span class="p">.</span><span class="nx">readFileSync</span><span class="p">(</span><span class="nx">srcFilename</span><span class="p">,</span> <span class="s1">'utf-8'</span><span class="p">));</span>
<span class="p">}</span>
<span class="nx">SVGCleaner</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">writeFileSync</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">targetFilename</span><span class="p">)</span><span class="err"> </span><span class="p">{</span>
<span class="nx">fs</span><span class="p">.</span><span class="nx">writeFileSync</span><span class="p">(</span><span class="nx">targetFilename</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">svgString</span><span class="p">(),</span> <span class="s1">'utf-8'</span><span class="p">);</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="nx">SVGCleaner</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">svgString</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span><span class="err"> </span><span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">$</span><span class="p">.</span><span class="nx">html</span><span class="p">();</span>
<span class="p">}</span></pre></div> </td> </tr> <tr id="section-60"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-60">¶</a> </div> <p>chainable interface, to perform specific processing steps on an svg object
<code>var svgStringWithShortIDs = new require('svg-cleaner').SVGCleaner().load(svgString).shortenIDs().svgString();</code></p> </td> <td class="code"> <div class="highlight"><pre><span class="kd">var</span> <span class="nx">exposed</span> <span class="o">=</span> <span class="p">{</span>
<span class="s1">'shortenIDs'</span><span class="o">:</span> <span class="nx">shortenIDs</span><span class="p">,</span>
<span class="s1">'removeComments'</span><span class="o">:</span> <span class="nx">removeComments</span><span class="p">,</span>
<span class="s1">'repairStyles'</span><span class="o">:</span> <span class="nx">repairStyles</span><span class="p">,</span>
<span class="s1">'removeNSElements'</span><span class="o">:</span> <span class="nx">removeNamespacedElements</span><span class="p">,</span>
<span class="s1">'removeNSAttributes'</span><span class="o">:</span> <span class="nx">removeNamespacedAttributes</span><span class="p">,</span>
<span class="s1">'removeUnreferencedElements'</span><span class="o">:</span> <span class="nx">removeUnreferencedElements</span>
<span class="p">};</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">exposed</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">f</span><span class="p">,</span> <span class="nx">name</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">SVGCleaner</span><span class="p">.</span><span class="nx">prototype</span><span class="p">[</span><span class="nx">name</span><span class="p">]</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span><span class="err"> </span><span class="p">{</span>
<span class="nx">$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">$</span><span class="p">;</span>
<span class="nx">f</span><span class="p">.</span><span class="nx">call</span><span class="p">();</span>
<span class="k">this</span><span class="p">.</span><span class="nx">$</span> <span class="o">=</span> <span class="nx">$</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">});</span></pre></div> </td> </tr> <tr id="section-61"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-61">¶</a> </div> <hr /> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-62"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-62">¶</a> </div> <h2>Processing Steps</h2> </td> <td class="code"> <div class="highlight"><pre><span class="nx">SVGCleaner</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">clean</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span><span class="err"> </span><span class="p">{</span>
<span class="nx">$</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">$</span><span class="p">;</span>
<span class="nx">removeNamespacedElements</span><span class="p">(</span><span class="nx">namespacePrefixes</span><span class="p">);</span>
<span class="nx">removeNamespacedAttributes</span><span class="p">(</span><span class="nx">namespacePrefixes</span><span class="p">);</span></pre></div> </td> </tr> <tr id="section-63"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-63">¶</a> </div> <p>@missing remove the xmlns: declarations now</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-64"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-64">¶</a> </div> <p>@missing ensure namespace for SVG is declared</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-65"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-65">¶</a> </div> <p>@missing check for redundant SVG namespace declaration</p> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">removeComments</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-66"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-66">¶</a> </div> <p>scour:</p>
<blockquote>
<p>repair style (remove unnecessary style properties and change them into XML attributes)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">repairStyles</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-67"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-67">¶</a> </div> <p>@missing convert colors to #RRGGBB format</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-68"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-68">¶</a> </div> <p>@missing remove <metadata> if the user wants to</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-69"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-69">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>flattend defs elements into just one defs element
flattenDefs()</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-70"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-70">¶</a> </div> <p>scour:</p>
<blockquote>
<p>remove unreferenced gradients/patterns outside of defs
and most unreferenced elements inside of defs</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">removeUnreferencedElements</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-71"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-71">¶</a> </div> <p>scour:</p>
<blockquote>
<p>remove empty defs, metadata, g
NOTE: these elements will be removed if they just have whitespace-only text nodes</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-72"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-72">¶</a> </div> <p>@extended: also removes nested empty elements <defs><g></g></defs></p> </td> <td class="code"> <div class="highlight"><pre> <span class="kd">var</span> <span class="nx">elementWasRemoved</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">do</span> <span class="p">{</span>
<span class="nx">elementWasRemoved</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
<span class="nx">_</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'defs, metadata, g'</span><span class="p">)).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">node</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="nx">node</span><span class="p">.</span><span class="nx">children</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="nx">node</span><span class="p">).</span><span class="nx">remove</span><span class="p">();</span>
<span class="nx">elementWasRemoved</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="p">}</span> <span class="k">while</span><span class="p">(</span><span class="nx">elementWasRemoved</span><span class="p">);</span>
<span class="nx">removeUnreferencedIDs</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-73"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-73">¶</a> </div> <p>@missing:
removeDuplicateGradientStops();</p> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-74"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-74">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>remove gradients that are only referenced by one other gradient
collapseSinglyReferencedGradients();</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-75"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-75">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>remove duplicate gradients
removeDuplicateGradients(doc)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-76"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-76">¶</a> </div> <p>@missing scour: </p>
<blockquote>
<p>create <code><g></code> elements if there are runs of elements with the same attributes.
this MUST be before moveCommonAttributesToParentGroup.
createGroupsForCommonAttributes()</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-77"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-77">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>move common attributes to parent group
NOTE: the if the <svg> element's immediate children
all have the same value for an attribute, it must not
get moved to the <svg> element. The <svg> element
doesn't accept fill=, stroke= etc.!</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-78"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-78">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>remove unused attributes from parent</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-79"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-79">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>Collapse groups LAST, because we've created groups. If done before
moveAttributesToParentGroup, empty <code><g></code>'s may remain.</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-80"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-80">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>remove unnecessary closing point of polygons and scour points</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-81"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-81">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>scour points of polyline</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-82"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-82">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>clean path data</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-83"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-83">¶</a> </div> <p>scour:</p>
<blockquote>
<p>shorten ID names as much as possible</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> <span class="nx">shortenIDs</span><span class="p">();</span></pre></div> </td> </tr> <tr id="section-84"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-84">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>scour lengths (including coordinates)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> </pre></div> </td> </tr> <tr id="section-85"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-85">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>more length scouring in this function
numBytesSavedInLengths = reducePrecision(doc.documentElement)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> </pre></div> </td> </tr> <tr id="section-86"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-86">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>remove default values of attributes
numAttrsRemoved += removeDefaultAttributeValues(doc.documentElement, options) </p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> </pre></div> </td> </tr> <tr id="section-87"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-87">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>reduce the length of transformation attributes
numBytesSavedInTransforms = optimizeTransforms(doc.documentElement, options)</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre> </pre></div> </td> </tr> <tr id="section-88"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-88">¶</a> </div> <p>@missing scour:</p>
<blockquote>
<p>convert rasters references to base64-encoded strings</p>
</blockquote> </td> <td class="code"> <div class="highlight"><pre></pre></div> </td> </tr> <tr id="section-89"> <td class="docs"> <div class="pilwrap"> <a class="pilcrow" href="#section-89">¶</a> </div> <p>@missing scour:
properly size the SVG document (ideally width/height should be 100% with a viewBox)</p> </td> <td class="code"> <div class="highlight"><pre> <span class="k">this</span><span class="p">.</span><span class="nx">$</span> <span class="o">=</span> <span class="nx">$</span><span class="p">;</span>
<span class="k">return</span> <span class="k">this</span><span class="p">;</span>
<span class="p">}</span>
</pre></div> </td> </tr> </tbody> </table> </div> </body> </html>