-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Iconify Icons #8118
Labels
sig/contributor-experience
Categorizes an issue or PR as relevant to SIG Contributor Experience.
sig/docs
Categorizes an issue or PR as relevant to SIG Docs.
Comments
k8s-ci-robot
added
the
needs-sig
Indicates an issue or PR lacks a `sig/foo` label and requires one.
label
Oct 21, 2024
/sig docs |
k8s-ci-robot
added
sig/docs
Categorizes an issue or PR as relevant to SIG Docs.
sig/contributor-experience
Categorizes an issue or PR as relevant to SIG Contributor Experience.
and removed
needs-sig
Indicates an issue or PR lacks a `sig/foo` label and requires one.
labels
Oct 21, 2024
If anybody is reading this, I wrote up a little script to do this: """This script should generate ``icons.json`` (e.g. ``iconify``) from existing svgs
so that icons are available for use with tools [mermaid](https://mermaid.js.org)
that load the svg from json.
"""
import json
import os
import pathlib
from typing import Any, Iterable, Optional
from xml.dom import minidom
import rich.console
import typer
path_here = pathlib.Path(__file__).resolve().parent.parent
path_icons_json = path_here / "icons.json"
path_svg = path_here / "svg"
DELIM = "_"
def walk(directory: pathlib.Path):
"""Iterate through ``directory`` content."""
contents = os.listdir(directory)
for path in map(lambda path: directory / path, contents):
if os.path.isdir(path):
yield from walk(directory / path)
continue
yield directory / path
def load(path: pathlib.Path) -> str:
"""Load and process the ``svg`` file at ``path``."""
loaded = minidom.parse(str(path))
elements = loaded.getElementsByTagName("g")
element = next((ee for ee in elements if ee.getAttribute("id") == "layer1"), None)
if element is None:
console.print(f"Could not find ``layer1`` of ``{path}``.")
raise typer.Exit(1)
return element.toxml("utf-8").decode()
def create_name(path: pathlib.Path):
"""Create name from ``path``."""
head, _ = os.path.splitext(os.path.relpath(path, path_svg))
pieces = head.split("/")
# NOTE: Labeled icons are the default. When an icon is unlabeled, just
# attach ``unlabeled`` to the end.
if "labeled" in pieces:
pieces.remove("labeled")
elif "unlabeled" in pieces:
loc = pieces.index("unlabeled")
pieces[loc], pieces[-1] = pieces[-1], "u"
# NOTE: These prefixes are not necessary in icon names.
if "infrastructure_components" in pieces:
pieces.remove("infrastructure_components")
elif "control_plane_components" in pieces:
pieces.remove("control_plane_components")
elif "resources" in pieces:
pieces.remove("resources")
return DELIM.join(pieces).replace("-", DELIM)
def create_alias(name: str) -> str | None:
"""For a short name, create its long alias."""
split = name.split("-")
for pos, item in enumerate(split):
if item in abbr:
split[pos] = abbr[item]
elif item == "u":
split[pos] = "unlabeled"
alias = DELIM.join(split).replace("-", DELIM)
if alias == name:
return None
return alias
def create_aliases(names: Iterable[str]):
"""Create aliases ``$.aliases``."""
aliases = {
alias: {"parent": name}
for name in names
if (alias := create_alias(name)) is not None
}
return aliases
def create_iconify_icon(path: pathlib.Path) -> dict[str, Any]:
"""Create ``$.icons`` values."""
# NOTE: Height and width must be 17 to prevent cropping.
return {"height": 17, "width": 17, "body": load(path)}
def create_icons():
"""Create ``$.icons``."""
return {create_name(item): create_iconify_icon(item) for item in walk(path_svg)}
def create_iconify_json(include: set[str] = set()):
"""Create ``kubernetes.json``, the iconify icon set."""
icons = create_icons()
if include:
icons = {name: icon for name, icon in create_icons().items() if name in include}
aliases = create_aliases(icons)
return {"icons": icons, "prefix": "k8s", "aliases": aliases}
cli = typer.Typer()
console = rich.console.Console()
abbr = {
"pvc": "persistent_volume-claim",
"svc": "service",
"vol": "volume",
"rb": "role-binding",
"rs": "replica-set",
"ing": "ingress",
"secret": "secret",
"pv": "persistent-volume",
"cronjob": "cron-job",
"sts": "stateful-set",
"pod": "pod",
"cm": "config-map",
"deploy": "deployment",
"sc": "storage-class",
"hpa": "horizontal-pod-autoscaler",
"crd": "custom-resource-definition",
"quota": "resource-quota",
"psp": "pod-security-policy",
"sa": "service-account",
"role": "role",
"c-role": "cluster-role",
"ns": "namespace",
"node": "node",
"job": "job",
"ds": "daemon-set",
"ep": "endpoint",
"crb": "cluster-role-binding",
"limits": "limit-range",
"control-plane": "control-plane",
"k-proxy": "kube-proxy",
"sched": "scheduler",
"api": "api-server",
"c-m": "controller-manager",
"c-c-m": "cloud-controller-manager",
"kubelet": "kubelet",
"group": "group",
"user": "user",
"netpol": "network-policy",
}
@cli.command("make")
def main(include: list[str] = list(), out: Optional[pathlib.Path] = None):
iconify = create_iconify_json(set(include))
if out is None:
print(json.dumps(iconify, indent=2))
return
with open(out, "w") as file:
json.dump(iconify, file, indent=2)
@cli.command("aliases")
def aliases(include: list[str] = list()):
names = map(create_name, walk(path_svg))
if include:
_include = set(include)
names = filter(lambda item: item in _include, names)
aliases = create_aliases(names)
print(json.dumps(aliases))
@cli.command("names")
def names():
print(json.dumps(list(map(create_name, walk(path_svg)))))
if __name__ == "__main__":
cli() I will write up a version with no extra dependencies for python and make a pull request unless anyone objects. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
sig/contributor-experience
Categorizes an issue or PR as relevant to SIG Contributor Experience.
sig/docs
Categorizes an issue or PR as relevant to SIG Docs.
Describe the issue
Hi everybody!
I wanted to make an iconify icon pack to distribute
svg
icons for use in mermaid architecture diagrams. I was wondering if it would be worth while to contribute the snippet I wrote to makeiconify.json
so that distribution may be automated here. I will like to the script once I have pushed it somewhere.Further, I would like to note that the script is a python script, which should run in the container specify in the
icons
folder (it isubuntu:22
I think) so that should be fine so long as I remove any dependencies that do not ship with python by default.Thanks you everybody!
The text was updated successfully, but these errors were encountered: