const data = require("./_data/simple-icons.json"); const { htmlFriendlyToTitle } = require("./scripts/utils.js"); const getBounds = require("svg-path-bounding-box"); const titleRegexp = /(.+) icon$/; const iconSize = 24; const iconFloatPrecision = 3; const iconIgnored = require("./.svglint-ignored.json"); module.exports = { rules: { elm: { "svg": 1, "svg > title": 1, "svg > path": 1, "*": false, }, attr: [ { // ensure that the SVG elm has the appropriate attrs "role": "img", "viewBox": `0 0 ${iconSize} ${iconSize}`, "xmlns": "http://www.w3.org/2000/svg", "rule::selector": "svg", "rule::whitelist": true, }, { // ensure that the title elm has the appropriate attr "rule::selector": "svg > title", "rule::whitelist": true, }, { // ensure that the path element only has the 'd' attr (no style, opacity, etc.) "d": /^[,a-zA-Z0-9\. -]+$/, "rule::selector": "svg > path", "rule::whitelist": true, } ], custom: [ function(reporter, $, ast) { reporter.name = "icon-title"; const iconTitleText = $.find("title").text(); if (!titleRegexp.test(iconTitleText)) { reporter.error(" should follow the format \"[ICON_NAME] icon\""); } else { const titleMatch = iconTitleText.match(titleRegexp); // titleMatch = [ "[ICON_NAME] icon", "[ICON_NAME]" ] const rawIconName = titleMatch[1]; const iconName = htmlFriendlyToTitle(rawIconName); const icon = data.icons.find(icon => icon.title === iconName); if (icon === undefined) { reporter.error(`No icon with title "${iconName}" found in simple-icons.json`); } } }, function(reporter, $, ast) { reporter.name = "icon-size"; const iconPath = $.find("path").attr("d"); if (iconIgnored.hasOwnProperty(iconPath)) { return; } const bounds = getBounds(iconPath); const width = +bounds.width.toFixed(iconFloatPrecision); const height = +bounds.height.toFixed(iconFloatPrecision); if (width === 0 && height === 0) { reporter.error("Path bounds were reported as 0 x 0; check if the path is valid"); } else if (width !== iconSize && height !== iconSize) { reporter.error(`Size of <path> must be exactly ${iconSize} in one dimension; the size is currently ${width} x ${height}`); } }, ] } };