...loading

Lucide icon processing workflow for Home Assistant

Published: 3 months ago

A short tutorial on processing Lucide icons for Home Assistant integration.

Converting strokes to fills

Home Assistant icon API provides only an option to provide single (or at most 2) paths for the svg icon, which is an issue for Lucide, because they are originally provided as a set of strokes. Therefore we need to convert the strokes with respective stroke-width to a filled path and merge all of those together to achieve single, filled path. For this purpose we will use Inkscape. Here is a bash script, that does described process.

Inkscape

#!/usr/bin/env bash

mkdir ./output

cd ./icons || return

for i in *.svg
do
    inkscape --actions="select-all;selection-ungroup;select-all;selection-ungroup;select-all;object-stroke-to-path;object-set-attribute:stroke-width,0;path-union;object-set-attribute:stroke-width,0;" --export-plain-svg --export-type=svg --export-filename=- $i > ../output/$i
    echo "done with "$i
done

Sanitizing output

Now we have a new folder output, which contains processed icons. However, we may sanitize output and provide additional useful attributes like tags, that are provided with the icons inside .json files. To do this, I used Julia with following script:

using EzXML
using JSON

const ROOT_DIR = "/home/xxx"
const OUTPUT_DIR = "/output"
const INPUT_DIR = "/icons"

function process_icon(icon, root_dir, input_dir, output_dir)

    attributes = JSON.parsefile("$root_dir$input_dir/$icon.json")

    doc = readxml("$root_dir$output_dir/$icon.svg")
    root = EzXML.root(doc)

    # Remove unneccessary attributes from svg tag and set correct values
    delete!(root, "version")
    delete!(root, "id")
    delete!(root, "stroke")
    delete!(root, "stroke-width")
    delete!(root, "stroke-linecap")
    delete!(root, "stroke-linejoin")
    root["fill"] = "currentColor"
    root["tags"] = join(attributes["tags"], ",")
    root["categories"] = join(attributes["categories"], ",")

    els = elements(root)

    #Remove defs tag
    unlink!(els[1])

    # Remove unneccessary attributes from path tag
    delete!(els[2], "id")
    delete!(els[2], "style")
    delete!(els[2], "stroke-width")

    write("$root_dir$output_dir/$icon.svg", doc)
end

filelist = readdir("$ROOT_DIR$INPUT_DIR/")
filelist = filter(x -> occursin(".svg", x), filelist)

for p in filelist
    # Extract icon name from filename
    icon = p[1:end-4]

    process_icon(icon, ROOT_DIR, INPUT_DIR, OUTPUT_DIR)
end

On This Page