mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 00:52:16 -06:00
199 lines
5.6 KiB
Python
Executable file
199 lines
5.6 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
# author: @chinponya
|
|
|
|
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
from urllib.parse import urlparse, parse_qsl
|
|
|
|
|
|
def read_json(path):
|
|
return json.loads(path.read_text())
|
|
|
|
|
|
def get_prism_version(prism_path):
|
|
package_json_path = prism_path / "package.json"
|
|
package_json = read_json(package_json_path)
|
|
return package_json["version"]
|
|
|
|
|
|
def get_prism_components(prism_path):
|
|
components_json_path = prism_path / "components.json"
|
|
components_json = read_json(components_json_path)
|
|
return components_json
|
|
|
|
|
|
def parse_prism_configuration(url_str):
|
|
url = urlparse(url_str)
|
|
# prism.com uses a non-standard query string-like encoding
|
|
query = {k: v.split(" ") for k, v in parse_qsl(url.fragment)}
|
|
return query
|
|
|
|
|
|
def paths_of_component(prism_path, kind, components, name, minified):
|
|
component = components[kind][name]
|
|
meta = components[kind]["meta"]
|
|
path_format = meta["path"]
|
|
path_base = prism_path / path_format.replace("{id}", name)
|
|
|
|
if isinstance(component, str):
|
|
# 'core' component has a different shape, so we convert it to be consistent
|
|
component = {"title": component}
|
|
|
|
if meta.get("noCSS") or component.get("noCSS"):
|
|
extensions = ["js"]
|
|
elif kind == "themes":
|
|
extensions = ["css"]
|
|
else:
|
|
extensions = ["js", "css"]
|
|
|
|
if path_base.is_dir():
|
|
result = {ext: path_base / f"{name}.{ext}" for ext in extensions}
|
|
elif path_base.suffix:
|
|
ext = path_base.suffix.replace(".", "")
|
|
result = {ext: path_base}
|
|
else:
|
|
result = {ext: path_base.with_suffix(f".{ext}") for ext in extensions}
|
|
|
|
if minified:
|
|
result = {
|
|
ext: path.with_suffix(".min" + path.suffix) for ext, path in result.items()
|
|
}
|
|
|
|
return result
|
|
|
|
|
|
def read_component_contents(kv_paths):
|
|
return {k: path.read_text() for k, path in kv_paths.items()}
|
|
|
|
|
|
def get_language_dependencies(components, name):
|
|
dependencies = components["languages"][name].get("require")
|
|
|
|
if isinstance(dependencies, list):
|
|
return dependencies
|
|
elif isinstance(dependencies, str):
|
|
return [dependencies]
|
|
else:
|
|
return []
|
|
|
|
|
|
def make_header(prism_path, url):
|
|
version = get_prism_version(prism_path)
|
|
header = f"/* PrismJS {version}\n{url} */"
|
|
return {"js": header, "css": header}
|
|
|
|
|
|
def make_core(prism_path, components, minified):
|
|
kv_paths = paths_of_component(prism_path, "core", components, "core", minified)
|
|
return read_component_contents(kv_paths)
|
|
|
|
|
|
def make_theme(prism_path, components, name, minified):
|
|
kv_paths = paths_of_component(prism_path, "themes", components, name, minified)
|
|
return read_component_contents(kv_paths)
|
|
|
|
|
|
def make_language(prism_path, components, name, minified):
|
|
kv_paths = paths_of_component(prism_path, "languages", components, name, minified)
|
|
return read_component_contents(kv_paths)
|
|
|
|
|
|
def make_languages(prism_path, components, names, minified):
|
|
names_with_dependencies = sum(
|
|
([*get_language_dependencies(components, name), name] for name in names), []
|
|
)
|
|
|
|
seen = set()
|
|
names_with_dependencies = [
|
|
x for x in names_with_dependencies if not (x in seen or seen.add(x))
|
|
]
|
|
|
|
kv_code = [
|
|
make_language(prism_path, components, name, minified)
|
|
for name in names_with_dependencies
|
|
]
|
|
|
|
return kv_code
|
|
|
|
|
|
def make_plugin(prism_path, components, name, minified):
|
|
kv_paths = paths_of_component(prism_path, "plugins", components, name, minified)
|
|
return read_component_contents(kv_paths)
|
|
|
|
|
|
def make_plugins(prism_path, components, names, minified):
|
|
kv_code = [make_plugin(prism_path, components, name, minified) for name in names]
|
|
return kv_code
|
|
|
|
|
|
def make_code(prism_path, url, minified):
|
|
components = get_prism_components(prism_path)
|
|
configuration = parse_prism_configuration(url)
|
|
theme_name = configuration["themes"][0]
|
|
code = [
|
|
make_header(prism_path, url),
|
|
make_core(prism_path, components, minified),
|
|
make_theme(prism_path, components, theme_name, minified),
|
|
]
|
|
|
|
if configuration.get("languages"):
|
|
code.extend(
|
|
make_languages(prism_path, components, configuration["languages"], minified)
|
|
)
|
|
|
|
if configuration.get("plugins"):
|
|
code.extend(
|
|
make_plugins(prism_path, components, configuration["plugins"], minified)
|
|
)
|
|
|
|
return code
|
|
|
|
|
|
def join_code(kv_code):
|
|
result = {"js": "", "css": ""}
|
|
|
|
for row in kv_code:
|
|
for key, code in row.items():
|
|
result[key] += code
|
|
result[key] += "\n"
|
|
|
|
return result
|
|
|
|
|
|
def write_code(kv_code, js_out, css_out):
|
|
code = join_code(kv_code)
|
|
|
|
with js_out.open("w") as f:
|
|
f.write(code["js"])
|
|
print(f"written {js_out}")
|
|
|
|
with css_out.open("w") as f:
|
|
f.write(code["css"])
|
|
print(f"written {css_out}")
|
|
|
|
|
|
def parse_args():
|
|
# fmt: off
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("url", help="configured prism download url")
|
|
parser.add_argument("--dir", type=Path, default=Path("."), help="prism repo directory")
|
|
parser.add_argument("--minify", default=True, action=argparse.BooleanOptionalAction, help="use minified files",)
|
|
parser.add_argument("--js-out", type=Path, default=Path("prism.js"), help="JS output file path")
|
|
parser.add_argument("--css-out", type=Path, default=Path("prism.css"), help="CSS output file path")
|
|
# fmt: on
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
code = make_code(args.dir, args.url, args.minify)
|
|
write_code(code, args.js_out, args.css_out)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|