Skip to content

Instantly share code, notes, and snippets.

@dudeuter
Last active December 15, 2022 01:40
Show Gist options
  • Save dudeuter/7c3eebf15d3e13c9da5560654c1fd6b3 to your computer and use it in GitHub Desktop.
Save dudeuter/7c3eebf15d3e13c9da5560654c1fd6b3 to your computer and use it in GitHub Desktop.
node.js script to add `xmlns:tools` and fill/stroke to transparent assets

node.js script to add xmlns:tools and fill/stroke to transparent assets

dependencies:

node

installation:

copy this script

usage:

node index.js [path to directory]

warning:

this script will overrite existing files, make sure you're using git with your assets commited, and review before using.

const process = require('process');
const fs = require('fs').promises;
const path = require('path');
const args = process.argv.slice(2);
const directoryPath = path.resolve(args[0]);
function copyPad(str) {
let pad = '';
for (const char of str) {
if (char.match(/^\s$/)) {
pad += char;
} else {
return pad;
}
}
console.warn('Warning: invariant -- entire string is whitespace\n', new Error().stack.slice(7));
return pad;
}
(async function main() {
const vectorDrawables = (await fs.readdir(directoryPath, { encoding: 'utf-8', withFileTypes: true })).filter(dirent => dirent.name.trim().match(/.*\.xml$/));
for (const { name: fileName } of vectorDrawables) {
const filePath = path.resolve(directoryPath, fileName);
const lines = (await fs.readFile(filePath, { encoding: 'utf-8' })).split(/\r\n|\r|\n/);
let cursor = 0;
while (cursor < lines.length) {
let line = lines[cursor];
if (line.match(/^<vector/)) {
cursor += 1;
line = lines[cursor];
while (line.includes('xmlns:')) {
cursor += 1;
line = lines[cursor];
}
const pad = copyPad(lines[cursor]);
lines.splice(cursor, 0, `${pad}xmlns:tools="http://schemas.android.com/tools"`);
}
function upsertByType(type) {
if (!line.match(new RegExp(`\s*android:${type}=`))) return;
const pad = copyPad(line);
let i = line.search(/\s*\/>$/); // search for the index of the closing tag
i = i === -1 ? line.length : i; // if there's no closing tag use the full length
const close = line.slice(i, line.length);
lines[cursor] = line.slice(0, i);
cursor += 1;
lines.splice(cursor, 0, `${pad}tools:${type}="#000"${close}`);
}
upsertByType('strokeColor');
upsertByType('fillColor');
cursor += 1;
}
fs.writeFile(filePath, lines.join('\n'), { encoding: 'utf-8' });
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment