chore: format python codeicons
This commit is contained in:
+5
-75
@@ -8,10 +8,6 @@ from urllib.error import HTTPError
|
|||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Configuration
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DEVICON_VERSION = "v2.17.0"
|
DEVICON_VERSION = "v2.17.0"
|
||||||
|
|
||||||
ICONS = {
|
ICONS = {
|
||||||
@@ -77,64 +73,40 @@ ICONS = {
|
|||||||
"graphql": "graphql",
|
"graphql": "graphql",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Markdown / syntax-highlighter aliases -> Devicon icon name.
|
|
||||||
ALIASES = {
|
ALIASES = {
|
||||||
"cpp": "cpp",
|
"cpp": "cpp",
|
||||||
"cc": "cpp",
|
"cc": "cpp",
|
||||||
"cxx": "cpp",
|
"cxx": "cpp",
|
||||||
|
|
||||||
"cs": "csharp",
|
"cs": "csharp",
|
||||||
|
|
||||||
"js": "javascript",
|
"js": "javascript",
|
||||||
"jsx": "javascript",
|
"jsx": "javascript",
|
||||||
|
|
||||||
"ts": "typescript",
|
"ts": "typescript",
|
||||||
"tsx": "typescript",
|
"tsx": "typescript",
|
||||||
|
|
||||||
"py": "python",
|
"py": "python",
|
||||||
|
|
||||||
"sh": "bash",
|
"sh": "bash",
|
||||||
"shell": "bash",
|
"shell": "bash",
|
||||||
|
|
||||||
"ps1": "powershell",
|
"ps1": "powershell",
|
||||||
|
|
||||||
"vb": "visualbasic",
|
"vb": "visualbasic",
|
||||||
|
|
||||||
"objective-c": "objectivec",
|
"objective-c": "objectivec",
|
||||||
"obj-c": "objectivec",
|
"obj-c": "objectivec",
|
||||||
|
|
||||||
"groovyscript": "groovy",
|
"groovyscript": "groovy",
|
||||||
|
|
||||||
"pascal": "delphi",
|
"pascal": "delphi",
|
||||||
|
|
||||||
"coffee": "coffeescript",
|
"coffee": "coffeescript",
|
||||||
|
|
||||||
"mysql": "sql",
|
"mysql": "sql",
|
||||||
"postgres": "sql",
|
"postgres": "sql",
|
||||||
"postgresql": "sql",
|
"postgresql": "sql",
|
||||||
"sqlite": "sql",
|
"sqlite": "sql",
|
||||||
|
|
||||||
"yml": "yaml",
|
"yml": "yaml",
|
||||||
|
|
||||||
"htm": "html",
|
"htm": "html",
|
||||||
|
|
||||||
"scss": "sass",
|
"scss": "sass",
|
||||||
|
|
||||||
"md": "markdown",
|
"md": "markdown",
|
||||||
|
|
||||||
"dockerfile": "docker",
|
"dockerfile": "docker",
|
||||||
"docker-compose": "docker",
|
"docker-compose": "docker",
|
||||||
|
|
||||||
"tex": "latex",
|
"tex": "latex",
|
||||||
|
|
||||||
"gql": "graphql",
|
"gql": "graphql",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Helpers
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
ICON_VARIANTS = (
|
ICON_VARIANTS = (
|
||||||
"plain",
|
"plain",
|
||||||
"original",
|
"original",
|
||||||
@@ -158,9 +130,7 @@ def fetch_svg(devicon_name: str) -> str:
|
|||||||
if error.code != 404:
|
if error.code != 404:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
raise RuntimeError(
|
raise RuntimeError(f"No usable SVG variant found for '{devicon_name}'.")
|
||||||
f"No usable SVG variant found for '{devicon_name}'."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def element_to_path(element) -> str:
|
def element_to_path(element) -> str:
|
||||||
@@ -219,14 +189,6 @@ def element_to_path(element) -> str:
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# SVG path data normalization
|
|
||||||
#
|
|
||||||
# Devicon path data crams arc flags against the following coordinate
|
|
||||||
# (e.g. "a28.78 28.78 0 00-2.65-7.58"), which Qt's PathSvg parser handles
|
|
||||||
# unreliably. Parse every path and re-emit it with canonical spacing.
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
PATH_COMMANDS = "MmLlHhVvCcSsQqTtAaZz"
|
PATH_COMMANDS = "MmLlHhVvCcSsQqTtAaZz"
|
||||||
_NUMBER = re.compile(r"[+-]?(?:\d+\.\d*|\.\d+|\d+)(?:[eE][+-]?\d+)?")
|
_NUMBER = re.compile(r"[+-]?(?:\d+\.\d*|\.\d+|\d+)(?:[eE][+-]?\d+)?")
|
||||||
|
|
||||||
@@ -278,7 +240,6 @@ def parse_path(data: str) -> list[tuple[str, list[str]]]:
|
|||||||
x, i = _read_number(data, i)
|
x, i = _read_number(data, i)
|
||||||
y, i = _read_number(data, i)
|
y, i = _read_number(data, i)
|
||||||
commands.append((implicit, [x, y]))
|
commands.append((implicit, [x, y]))
|
||||||
# Subsequent coordinate pairs after a moveto are linetos.
|
|
||||||
implicit = "L" if implicit == "M" else "l"
|
implicit = "L" if implicit == "M" else "l"
|
||||||
elif implicit in "LlTt":
|
elif implicit in "LlTt":
|
||||||
x, i = _read_number(data, i)
|
x, i = _read_number(data, i)
|
||||||
@@ -291,14 +252,12 @@ def parse_path(data: str) -> list[tuple[str, list[str]]]:
|
|||||||
y, i = _read_number(data, i)
|
y, i = _read_number(data, i)
|
||||||
commands.append((implicit, [y]))
|
commands.append((implicit, [y]))
|
||||||
elif implicit in "Cc":
|
elif implicit in "Cc":
|
||||||
# Cubic bezier: x1 y1 x2 y2 x y
|
|
||||||
p = []
|
p = []
|
||||||
for _ in range(6):
|
for _ in range(6):
|
||||||
value, i = _read_number(data, i)
|
value, i = _read_number(data, i)
|
||||||
p.append(value)
|
p.append(value)
|
||||||
commands.append((implicit, p))
|
commands.append((implicit, p))
|
||||||
elif implicit in "SsQq":
|
elif implicit in "SsQq":
|
||||||
# Smooth cubic / quadratic: x1 y1 x y
|
|
||||||
p = []
|
p = []
|
||||||
for _ in range(4):
|
for _ in range(4):
|
||||||
value, i = _read_number(data, i)
|
value, i = _read_number(data, i)
|
||||||
@@ -308,8 +267,6 @@ def parse_path(data: str) -> list[tuple[str, list[str]]]:
|
|||||||
rx, i = _read_number(data, i)
|
rx, i = _read_number(data, i)
|
||||||
ry, i = _read_number(data, i)
|
ry, i = _read_number(data, i)
|
||||||
rotation, i = _read_number(data, i)
|
rotation, i = _read_number(data, i)
|
||||||
# Arc flags are single digits, possibly crammed against
|
|
||||||
# the following coordinate, so read them positionally.
|
|
||||||
i = _skip_separators(data, i)
|
i = _skip_separators(data, i)
|
||||||
large_arc = data[i]
|
large_arc = data[i]
|
||||||
i += 1
|
i += 1
|
||||||
@@ -351,7 +308,6 @@ def extract_paths(svg: str) -> str:
|
|||||||
|
|
||||||
normalized = normalize_path(path)
|
normalized = normalize_path(path)
|
||||||
|
|
||||||
# Guard against a tokenizer that changes the path it normalizes.
|
|
||||||
if parse_path(normalized) != parse_path(path):
|
if parse_path(normalized) != parse_path(path):
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"Path normalization round-trip mismatch:\n"
|
"Path normalization round-trip mismatch:\n"
|
||||||
@@ -363,12 +319,10 @@ def extract_paths(svg: str) -> str:
|
|||||||
if not paths:
|
if not paths:
|
||||||
raise RuntimeError("SVG contains no drawable shape elements")
|
raise RuntimeError("SVG contains no drawable shape elements")
|
||||||
|
|
||||||
# Multiple path elements are valid SVG path data when concatenated.
|
|
||||||
return " ".join(paths)
|
return " ".join(paths)
|
||||||
|
|
||||||
|
|
||||||
def qml_string(value: str) -> str:
|
def qml_string(value: str) -> str:
|
||||||
# JSON string escaping is valid for the string syntax we need in QML.
|
|
||||||
return json.dumps(value, ensure_ascii=False)
|
return json.dumps(value, ensure_ascii=False)
|
||||||
|
|
||||||
|
|
||||||
@@ -381,10 +335,6 @@ def qml_identifier(name: str) -> str:
|
|||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# Generation
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def generate(output: Path) -> None:
|
def generate(output: Path) -> None:
|
||||||
icons = {}
|
icons = {}
|
||||||
|
|
||||||
@@ -405,10 +355,6 @@ Singleton {
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# -------------------------------------------------------------------
|
|
||||||
# Icon path properties
|
|
||||||
# -------------------------------------------------------------------
|
|
||||||
|
|
||||||
for icon, path in icons.items():
|
for icon, path in icons.items():
|
||||||
identifier = qml_identifier(icon)
|
identifier = qml_identifier(icon)
|
||||||
|
|
||||||
@@ -419,10 +365,6 @@ Singleton {
|
|||||||
|
|
||||||
file.write("\n")
|
file.write("\n")
|
||||||
|
|
||||||
# -------------------------------------------------------------------
|
|
||||||
# Language -> icon lookup
|
|
||||||
# -------------------------------------------------------------------
|
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
""" function path(language) {
|
""" function path(language) {
|
||||||
const key = language.toLowerCase()
|
const key = language.toLowerCase()
|
||||||
@@ -435,8 +377,7 @@ Singleton {
|
|||||||
identifier = qml_identifier(icon)
|
identifier = qml_identifier(icon)
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
f' case "{icon}":\n'
|
f' case "{icon}":\n return {identifier}\n'
|
||||||
f" return {identifier}\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for alias, icon in ALIASES.items():
|
for alias, icon in ALIASES.items():
|
||||||
@@ -448,8 +389,7 @@ Singleton {
|
|||||||
identifier = qml_identifier(icon)
|
identifier = qml_identifier(icon)
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
f' case "{alias}":\n'
|
f' case "{alias}":\n return {identifier}\n'
|
||||||
f" return {identifier}\n"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
@@ -463,8 +403,6 @@ Singleton {
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
# Human-readable names can initially be handled here.
|
|
||||||
# Add/remove these as your codeblock UI evolves.
|
|
||||||
names = {
|
names = {
|
||||||
"c": "C",
|
"c": "C",
|
||||||
"cpp": "C++",
|
"cpp": "C++",
|
||||||
@@ -535,18 +473,14 @@ Singleton {
|
|||||||
|
|
||||||
name = names[icon]
|
name = names[icon]
|
||||||
|
|
||||||
file.write(
|
file.write(f' case "{icon}":\n return "{name}"\n')
|
||||||
f' case "{icon}":\n'
|
|
||||||
f' return "{name}"\n'
|
|
||||||
)
|
|
||||||
|
|
||||||
for alias, icon in ALIASES.items():
|
for alias, icon in ALIASES.items():
|
||||||
if icon not in names:
|
if icon not in names:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
f' case "{alias}":\n'
|
f' case "{alias}":\n return "{names[icon]}"\n'
|
||||||
f' return "{names[icon]}"\n'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
file.write(
|
file.write(
|
||||||
@@ -561,10 +495,6 @@ Singleton {
|
|||||||
print(f"Generated {output}")
|
print(f"Generated {output}")
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
# CLI
|
|
||||||
# ---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
print(f"Usage: {sys.argv[0]} OUTPUT.qml", file=sys.stderr)
|
print(f"Usage: {sys.argv[0]} OUTPUT.qml", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user