coin/source/main.py
2025-07-17 11:31:32 +02:00

179 lines
2.9 KiB
Python

import sys as _sys
import json as _json
import yaml as _yaml
import argparse as _argparse
def convey(
x,
fs
):
y = x
for f in fs:
y = f(y)
return y
def string_coin(
template,
arguments,
options = None
):
options = (
{
"character_open": "{{",
"character_close": "}}"
}
|
(options or {})
)
result = template
for (key, value, ) in arguments.items():
result = result.replace(
(
"%s%s%s"
% (
options["character_open"],
key,
options["character_close"],
)
),
value
)
return result
def file_read(
path
):
handle = open(path, "r")
content = handle.read()
handle.close()
return content
def handle_value(
value,
options = None
):
options = (
{
"indicator": "@",
}
|
(options or {})
)
return (
file_read(value[len(options["indicator"]):])
if
value.startswith(options["indicator"])
else
value
)
def data_from_file(
path
):
return (
{}
if
(path is None)
else
(
(
lambda content: (
_json.loads(content)
if
path.endswith(".json")
else
_yaml.safe_load(content)
)
) (file_read(path))
)
)
def data_from_arguments(
arguments
):
return dict(
map(
lambda argument: (
(
lambda parts: (
parts[0],
handle_value(parts[1]),
)
) (argument.split(":", 1))
),
(arguments or {})
)
)
def main(
):
## args
argument_parser = _argparse.ArgumentParser(
prog = "coin",
formatter_class = _argparse.ArgumentDefaultsHelpFormatter,
description = "transforms an input string (stdin) by processing its placeholders; example: »echo '{{flowers}} are {{color}}' | coin -a flowers:roses -a color:red«",
)
argument_parser.add_argument(
"-d",
"--data-path",
type = str,
default = None,
metavar = "<data-path>",
help = "path to JSON or YAML file, containing placeholder assignments (e.g. »{\"flowers\": \"roses\", \"color\": \"red\"}«)",
)
argument_parser.add_argument(
"-a",
"--argument",
type = str,
dest = "arguments",
action = "append",
default = None,
metavar = "<key>:<value>",
help = "prefixing <value> with '@' causes the value to be interpreted as the path to a text file, whose content shall be used",
)
argument_parser.add_argument(
"-o",
"--character-open",
type = str,
default = "{{",
metavar = "<character-open>",
help = "placeholder opening character",
)
argument_parser.add_argument(
"-c",
"--character-close",
type = str,
default = "}}",
metavar = "<character-close>",
help = "placeholder closing character",
)
args = argument_parser.parse_args()
## exec
content_in = _sys.stdin.read()
data = (
data_from_file(args.data_path)
|
data_from_arguments(args.arguments)
)
content_out = string_coin(
content_in,
data,
{
"character_open": args.character_open,
"character_close": args.character_close,
}
)
_sys.stdout.write(content_out)
main()