From 6d6af200ab5bb06da7c1b2a06507218d4c4819cb Mon Sep 17 00:00:00 2001 From: Starnakin Date: Tue, 8 Jul 2025 14:16:00 +0200 Subject: [PATCH] add: bozodown --- src/bozodown.py | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/bozodown.py diff --git a/src/bozodown.py b/src/bozodown.py new file mode 100644 index 0000000..d55d8fc --- /dev/null +++ b/src/bozodown.py @@ -0,0 +1,139 @@ +from collections.abc import Callable +from typing import Any + +def _photohub_render(id: str, text: str) -> str: + if (id == "img"): + return f"" + +def _bozodown_render(id: str, text: str) -> str: + if (id == "list"): + print("error: list not supported") + return "" + + +_specific_case_namespaces: dict[str, Callable[[str, str], str]] = { + "bozodown": _bozodown_render, + "photohub": _photohub_render, +} + + +_converters: list[dict[str, str]] = [ + { + "from_prefix": "# ", + "from_suffix": "\n", + "to_prefix": "

", + "to_suffix": "

", + }, + { + "from_prefix": "## ", + "from_suffix": "\n", + "to_prefix": "

", + "to_suffix": "

", + }, + { + "from_prefix": "### ", + "from_suffix": "\n", + "to_prefix": "

", + "to_suffix": "

", + }, + { + "from_prefix": "#### ", + "from_suffix": "\n", + "to_prefix": "

", + "to_suffix": "

", + }, + { + "from_prefix": "`", + "from_suffix": "`", + "to_prefix": "

", + "to_suffix": "

", + }, + { + "from_prefix": "**", + "from_suffix": "**", + "to_prefix": "", + "to_suffix": "", + }, + { + "from_prefix": "- ", + "from_suffix": "\n", + "code": "bozodown:list", + }, + { + "from_prefix": "```", + "from_suffix": "```", + "to_prefix": "
",
+        "to_suffix": "
", + }, + { + "from_prefix": "![", + "from_suffix": "]", + "code": "photohub:img", + }, + { + "from_prefix": "- [ ] ", + "from_suffix": "\n", + "to_prefix": "
  • ", + "to_suffix": "
  • ", + }, + { + "from_prefix": "- [x] ", + "from_suffix": "\n", + "to_prefix": "
  • ", + "to_suffix": "
  • ", + }, + { + "from_prefix": "
    ", + "from_suffix": "", + "to_prefix": "
    ", + }, +] + +_default_converter: dict[str, str] = { + "from_prefix": "", + "to_prefix": "

    ", + "to_suffix": "

    ", +} + +def _render_element(text: str, converter: dict[str, str]) -> str: + code: str = converter.get("code") + if (code is not None): + namespace, id = code.split(":") + print(namespace, id) + func = _specific_case_namespaces[namespace] + return func(id, text) + print(converter) + start: int = len(converter["from_prefix"]) + stop: int = len(text) - len(converter.get("from_suffix", "")) + return f"{converter['to_prefix']}{text[start:stop]}{converter['to_suffix']}" + +def _get_first_converter(text: str) -> tuple[str, dict] | None: + first_converter_found: dict[str, str | Callable[[str, list[str]], Any]] | None = None + start: int | None = None + for converter in _converters: + matching_patern_pos: str = text.find(converter['from_prefix']) + if (matching_patern_pos != -1): + if (first_converter_found is None or matching_patern_pos < start): + first_converter_found = converter + start = matching_patern_pos + if (first_converter_found is None): + return text, _default_converter + if (start != 0): + return text[:start], _default_converter + suffix: int = first_converter_found.get("from_suffix", "") + prefix: int = first_converter_found['from_prefix'] + stop: int = text.find(suffix, start) + if (stop == -1): + print(f"error: '{prefix}' was never finished by a '{suffix}'") + return + stop += len(suffix) + return text[start:stop], first_converter_found + +def render(raw_content: str) -> str: + content: str = "" + to_parse: str = raw_content + while len(to_parse) > 0: + text, converter = _get_first_converter(to_parse) + content += _render_element(text, converter) + to_parse = to_parse[len(text):] + return content \ No newline at end of file