feat: replace TOML input with YAML
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
# artifacts
|
|
||||||
output/
|
|
||||||
*.svg
|
|
||||||
@@ -8,12 +8,12 @@ Generates SVG QR codes from any text input.
|
|||||||
uv run svgqr "Text to encode"
|
uv run svgqr "Text to encode"
|
||||||
uv run svgqr -t "Text to encode" -o path/to/code.svg
|
uv run svgqr -t "Text to encode" -o path/to/code.svg
|
||||||
uv run svgqr -i values.txt
|
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
|
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
|
safe, truncated form of the text as the SVG filename. Batch mode writes SVGs to
|
||||||
`output/` and ignores `-o`.
|
`output/` and ignores `-o`.
|
||||||
|
|
||||||
`--toml` accepts a flat mapping of output name to text. Standard TOML uses
|
`--yaml` accepts a flat mapping of output name to text, such as
|
||||||
`name = "text"`; the documented `name: text` form is also accepted.
|
`name: text`.
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ readme = "README.md"
|
|||||||
requires-python = ">=3.9"
|
requires-python = ">=3.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"qrcode>=8.0",
|
"qrcode>=8.0",
|
||||||
"tomli>=2.0; python_version < '3.11'",
|
"PyYAML>=6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|||||||
@@ -8,11 +8,7 @@ import re
|
|||||||
from typing import Sequence
|
from typing import Sequence
|
||||||
|
|
||||||
import qrcode
|
import qrcode
|
||||||
|
import yaml
|
||||||
try:
|
|
||||||
import tomllib
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
import tomli as tomllib
|
|
||||||
|
|
||||||
|
|
||||||
SVG_SUFFIX = ".svg"
|
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}"
|
return directory / f"{filename[:stem_length]}{SVG_SUFFIX}"
|
||||||
|
|
||||||
|
|
||||||
def read_toml_items(input_path: Path) -> dict[str, str]:
|
def read_yaml_items(input_path: Path) -> dict[str, str]:
|
||||||
content = input_path.read_text(encoding="utf-8")
|
|
||||||
try:
|
try:
|
||||||
items = tomllib.loads(content)
|
items = yaml.safe_load(input_path.read_text(encoding="utf-8")) or {}
|
||||||
except tomllib.TOMLDecodeError:
|
except yaml.YAMLError as error:
|
||||||
items = {}
|
raise ValueError(f"{input_path}: invalid YAML: {error}") from None
|
||||||
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()
|
|
||||||
|
|
||||||
if not all(isinstance(key, str) and isinstance(value, str) for key, value in items.items()):
|
if not isinstance(items, dict) or not all(
|
||||||
raise ValueError(f"{input_path}: TOML values must be top-level text strings")
|
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
|
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("-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("-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("-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
|
return parser
|
||||||
|
|
||||||
|
|
||||||
@@ -106,9 +94,9 @@ def run(arguments: Sequence[str] | None = None) -> None:
|
|||||||
parser = build_parser()
|
parser = build_parser()
|
||||||
args = parser.parse_args(arguments)
|
args = parser.parse_args(arguments)
|
||||||
|
|
||||||
if args.input is not None or args.toml is not None:
|
if args.input is not None or args.yaml is not None:
|
||||||
if args.input is not None and args.toml is not None:
|
if args.input is not None and args.yaml is not None:
|
||||||
parser.error("--input and --toml cannot be used together")
|
parser.error("--input and --yaml cannot be used together")
|
||||||
if args.text is not None or args.option_text is not None:
|
if args.text is not None or args.option_text is not None:
|
||||||
parser.error("text input cannot be used with batch input")
|
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")))
|
write_svg(line, automatic_output_path(line, Path("output")))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
items = read_toml_items(args.toml)
|
items = read_yaml_items(args.yaml)
|
||||||
except ValueError as error:
|
except ValueError as error:
|
||||||
parser.error(str(error))
|
parser.error(str(error))
|
||||||
for name, text in items.items():
|
for name, text in items.items():
|
||||||
|
|||||||
Reference in New Issue
Block a user