diff --git a/plugins/reusePaths.js b/plugins/reusePaths.js index d0cce6d9e..208cff0d3 100644 --- a/plugins/reusePaths.js +++ b/plugins/reusePaths.js @@ -1,5 +1,7 @@ 'use strict'; +const { detachNodeFromParent, querySelectorAll } = require('../lib/xast'); + /** * @typedef {import('../lib/types').XastElement} XastElement * @typedef {import('../lib/types').XastParent} XastParent @@ -113,11 +115,36 @@ exports.fn = () => { defsTag.children.push(reusablePath); // convert paths to for (const pathNode of list) { - pathNode.name = 'use'; - pathNode.attributes['xlink:href'] = '#' + id; delete pathNode.attributes.d; delete pathNode.attributes.stroke; delete pathNode.attributes.fill; + + if ( + defsTag.children.includes(pathNode) && + pathNode.children.length === 0 + ) { + if (Object.keys(pathNode.attributes).length === 0) { + detachNodeFromParent(pathNode, defsTag); + continue; + } + + if ( + Object.keys(pathNode.attributes).length === 1 && + pathNode.attributes.id != null + ) { + detachNodeFromParent(pathNode, defsTag); + const selector = `[xlink\\:href=#${pathNode.attributes.id}]`; + for (const child of querySelectorAll(node, selector)) { + if (child.type === 'element') { + child.attributes['xlink:href'] = '#' + id; + } + } + continue; + } + } + + pathNode.name = 'use'; + pathNode.attributes['xlink:href'] = '#' + id; } } } diff --git a/test/plugins/reusePaths.05.svg b/test/plugins/reusePaths.05.svg new file mode 100644 index 000000000..7cfd410c5 --- /dev/null +++ b/test/plugins/reusePaths.05.svg @@ -0,0 +1,33 @@ +When merging existing defs, remove redundant paths with no attributes or only +an ID attribute. + +=== + + + + + + + + + + + + + + + +@@@ + + + + + + + + + + + + +