Created
February 4, 2021 18:00
-
-
Save controversial/9701a5552e18acd05df12317e95f9bcd to your computer and use it in GitHub Desktop.
Sketch plugin to generate an icon library from a directory of SVGs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sketch plugin to generate an icon library from a directory of SVGs | |
const sketchDom = require('sketch/dom'); | |
// Prompt the user to select a folder | |
const dialog = NSOpenPanel.openPanel(); | |
dialog.setCanChooseFiles(false); | |
dialog.setCanChooseDirectories(true); | |
dialog.setAllowsMultipleSelection(false); | |
dialog.setCanCreateDirectories(false); | |
const dialogResponse = dialog.runModal(); | |
if (dialogResponse !== NSOKButton) return; // make sure the user pressed 'ok' instead of cancel | |
const folderPath = dialog.URL().path() + '/'; | |
// Create the document | |
const doc = new sketchDom.Document(); | |
// List files in that folder | |
const fileManager = NSFileManager.defaultManager(); | |
const paths = fileManager.subpathsAtPath(folderPath); | |
paths.sort(); | |
let rightEdge = 0; // where the last artboard ended | |
// Operate on each file path | |
for (let i = 0; i < paths.length; i++) { | |
// Join filename with folder name to get full path | |
const filename = paths[i]; | |
const [name, ext] = filename.split('.'); | |
if (ext !== 'svg') continue; | |
const absPath = folderPath + filename; | |
// Read file contents | |
const binContents = fileManager.contentsAtPath(absPath); | |
if (!binContents) continue; | |
const contents = Buffer.from(binContents).toString('utf-8'); | |
// Grab artboard dimensions from svg width/height attributes | |
const openingTag = contents.match(/<\s*svg\s.*?>/i)[0]; | |
if (!openingTag) continue; | |
const widthAttrRegex = / width="([0-9]+).*?"/i; | |
const heightAttrRegex = / height="([0-9]+).*?"/i; | |
const viewboxAttrRegex = / viewbox="((?:[0-9]+.*?\s){3}[0-9]+.*?)"/i | |
const svgWidth = openingTag.match(widthAttrRegex)?.[1]; | |
const svgHeight = openingTag.match(heightAttrRegex)?.[1]; | |
const svgViewbox = openingTag.match(viewboxAttrRegex)?.[1]; | |
const [canvasWidth, canvasHeight] = (svgWidth && svgHeight) | |
? [parseInt(svgWidth), parseInt(svgHeight)] | |
: svgViewbox.split(' ').slice(2).map((n) => parseInt(n, 10)) | |
if (!canvasWidth || !canvasHeight) continue; | |
// Create symbol | |
const artboard = new sketchDom.SymbolMaster({ | |
name, | |
parent: doc.pages[0], | |
}); | |
artboard.frame.x = rightEdge; | |
artboard.frame.y = 0; | |
artboard.frame.width = canvasWidth; | |
artboard.frame.height = canvasHeight; | |
artboard.moveToBack(); | |
// Put the icon in that symbol | |
const layer = sketchDom.createLayerFromData(contents, 'svg'); | |
layer.parent = artboard; | |
// The right edge of the rightmost artboard should now reflect the new artboard | |
rightEdge += parseInt(canvasWidth); | |
// Add padding | |
rightEdge += 50; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment