html-docwrap/source/main.py

237 lines
4.4 KiB
Python
Raw Normal View History

2025-07-30 09:17:08 +02:00
import sys as _sys
import argparse as _argparse
def string_coin(
template,
arguments
):
result = template
for (key, value, ) in arguments.items():
result = result.replace("{{%s}}" % key, value)
return result
def css_render_color_hsl(
css_color_hsl
):
return string_coin(
"hsl({{hue}},{{saturation}},{{lightness}})",
{
"hue": ("%.4f" % (css_color_hsl["hue"] * 360)),
"saturation": ("%.4f%%" % (css_color_hsl["saturation"] * 100)),
"lightness": ("%.4f%%" % (css_color_hsl["lightness"] * 100)),
}
)
def css_render_assignments(
css_assignments
):
return (
"; ".join(
map(
lambda pair: string_coin(
"{{name}}: {{value}}",
{
"name": pair[0],
"value": pair[1],
}
),
css_assignments.items()
)
)
)
def css_render_rule(
css_rule
):
return string_coin(
"{{selector}} {{{assignments}}}",
{
"selector": css_rule["selector"],
"assignments": css_render_assignments(css_rule["assignments"]),
}
)
def make_stylesheet(
css_rules
):
return (
"\n".join(
map(
lambda css_rule: css_render_rule(css_rule),
css_rules
)
)
)
def make_doc(
content,
data
):
return string_coin(
"<!DOCTYPE html>\n{{html}}\n",
{
"html": string_coin(
"<html>\n{{head}}\n{{body}}\n</html>\n",
{
"head": string_coin(
"<head>\n{{encoding}}\n{{viewport}}\n{{style}}\n{{macro_title}}</head>\n",
{
"encoding": string_coin(
"<meta charset=\"{{charset}}\"/>",
{
"charset": data["encoding"],
}
),
"viewport": string_coin(
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>",
{
}
),
"style": string_coin(
"<style>\n{{style}}\n</style>",
{
"style": make_stylesheet(
[
{
"selector": "html",
"assignments": {
"background-color": css_render_color_hsl(
{
"hue": data["hue"],
"saturation": 0,
"lightness": 0,
}
),
"color": css_render_color_hsl(
{
"hue": data["hue"],
"saturation": 0,
"lightness": 1,
}
),
}
},
{
"selector": "body",
"assignments": {
"background-color": css_render_color_hsl(
{
"hue": data["hue"],
"saturation": 0,
"lightness": (1/8),
}
),
"color": css_render_color_hsl(
{
"hue": data["hue"],
"saturation": 0,
"lightness": (7/8),
}
),
"max-width": "960px",
"margin": "auto",
"padding": "32px",
}
},
{
"selector": "a",
"assignments": {
"color": css_render_color_hsl(
{
"hue": data["hue"],
"saturation": (1/2),
"lightness": (2/4),
}
),
"text-decoration": "none",
}
},
{
"selector": "a:hover",
"assignments": {
"color": css_render_color_hsl(
{
"hue": data["hue"],
"saturation": (1/2),
"lightness": (3/4),
}
),
}
},
]
),
}
),
"macro_title": (
""
if (data["title"] is None) else
string_coin(
"<title>{{title}}</title>\n",
{
"title": data["title"],
}
)
),
}
),
"body": string_coin(
"<body>{{content}}</body>",
{
"content": content,
}
),
}
),
}
)
def main(
):
## args
argument_parser = _argparse.ArgumentParser()
argument_parser.add_argument(
"-t",
"--title",
type = str,
default = None,
)
argument_parser.add_argument(
"-c",
"--hue",
type = int,
default = 150,
)
argument_parser.add_argument(
"-e",
"--encoding",
type = str,
default = "utf-8",
)
args = argument_parser.parse_args()
## exec
content_in = _sys.stdin.read(
)
content_out = make_doc(
content_in,
{
"encoding": args.encoding,
"hue": (args.hue / 360),
"title": args.title,
}
)
_sys.stdout.write(
content_out
)
main()