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( "\n{{html}}\n", { "html": string_coin( "\n{{head}}\n{{body}}\n\n", { "head": string_coin( "\n{{encoding}}\n{{viewport}}\n{{style}}\n{{macro_title}}\n", { "encoding": string_coin( "", { "charset": data["encoding"], } ), "viewport": string_coin( "", { } ), "style": string_coin( "", { "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}}\n", { "title": data["title"], } ) ), } ), "body": string_coin( "{{content}}", { "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()