From 81de21e039024bf1dd5f038085c87439f0bc0de7 Mon Sep 17 00:00:00 2001 From: Mikkeli Matlock Date: Wed, 26 Aug 2026 15:54:41 +0900 Subject: [PATCH] feat: replace TOML input with YAML --- ,gitignore | 3 --- README.md | 6 +++--- pyproject.toml | 2 +- qr.py | 40 ++++++++++++++-------------------------- 4 files changed, 18 insertions(+), 33 deletions(-) delete mode 100644 ,gitignore diff --git a/,gitignore b/,gitignore deleted file mode 100644 index 2dba6e8..0000000 --- a/,gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# artifacts -output/ -*.svg diff --git a/README.md b/README.md index c830459..b9bb99f 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,12 @@ Generates SVG QR codes from any text input. uv run svgqr "Text to encode" uv run svgqr -t "Text to encode" -o path/to/code.svg uv run svgqr -i values.txt -uv run svgqr --toml values.toml +uv run svgqr --yaml values.yaml ``` Text can be passed positionally or with `-t`. Without `-o`, the program uses a safe, truncated form of the text as the SVG filename. Batch mode writes SVGs to `output/` and ignores `-o`. -`--toml` accepts a flat mapping of output name to text. Standard TOML uses -`name = "text"`; the documented `name: text` form is also accepted. +`--yaml` accepts a flat mapping of output name to text, such as +`name: text`. diff --git a/pyproject.toml b/pyproject.toml index ff9f2a5..95d87a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ readme = "README.md" requires-python = ">=3.9" dependencies = [ "qrcode>=8.0", - "tomli>=2.0; python_version < '3.11'", + "PyYAML>=6.0", ] [project.scripts] diff --git a/qr.py b/qr.py index a5efc79..c98b6f5 100644 --- a/qr.py +++ b/qr.py @@ -8,11 +8,7 @@ import re from typing import Sequence import qrcode - -try: - import tomllib -except ModuleNotFoundError: - import tomli as tomllib +import yaml SVG_SUFFIX = ".svg" @@ -71,24 +67,16 @@ def automatic_output_path(text: str, directory: Path = Path(".")) -> Path: return directory / f"{filename[:stem_length]}{SVG_SUFFIX}" -def read_toml_items(input_path: Path) -> dict[str, str]: - content = input_path.read_text(encoding="utf-8") +def read_yaml_items(input_path: Path) -> dict[str, str]: try: - items = tomllib.loads(content) - except tomllib.TOMLDecodeError: - items = {} - for line_number, line in enumerate(content.splitlines(), start=1): - if not line.strip() or line.lstrip().startswith("#"): - continue - key, separator, value = line.partition(":") - if not separator or not key.strip(): - raise ValueError( - f"{input_path}:{line_number}: expected a flat TOML item" - ) from None - items[key.strip()] = value.strip() + items = yaml.safe_load(input_path.read_text(encoding="utf-8")) or {} + except yaml.YAMLError as error: + raise ValueError(f"{input_path}: invalid YAML: {error}") from None - if not all(isinstance(key, str) and isinstance(value, str) for key, value in items.items()): - raise ValueError(f"{input_path}: TOML values must be top-level text strings") + if not isinstance(items, dict) or not all( + isinstance(key, str) and isinstance(value, str) for key, value in items.items() + ): + raise ValueError(f"{input_path}: YAML must be a flat mapping of text values") return items @@ -98,7 +86,7 @@ def build_parser() -> argparse.ArgumentParser: parser.add_argument("-t", "--text", dest="option_text", help="Text to encode.") parser.add_argument("-o", "--output", type=Path, help="Path for the generated SVG.") parser.add_argument("-i", "--input", type=Path, help="File containing one QR value per line.") - parser.add_argument("--toml", type=Path, help="Flat TOML file containing output names and text.") + parser.add_argument("--yaml", type=Path, help="Flat YAML file containing output names and text.") return parser @@ -106,9 +94,9 @@ def run(arguments: Sequence[str] | None = None) -> None: parser = build_parser() args = parser.parse_args(arguments) - if args.input is not None or args.toml is not None: - if args.input is not None and args.toml is not None: - parser.error("--input and --toml cannot be used together") + if args.input is not None or args.yaml is not None: + if args.input is not None and args.yaml is not None: + parser.error("--input and --yaml cannot be used together") if args.text is not None or args.option_text is not None: parser.error("text input cannot be used with batch input") @@ -117,7 +105,7 @@ def run(arguments: Sequence[str] | None = None) -> None: write_svg(line, automatic_output_path(line, Path("output"))) else: try: - items = read_toml_items(args.toml) + items = read_yaml_items(args.yaml) except ValueError as error: parser.error(str(error)) for name, text in items.items():