clean: create bozodown module
This commit is contained in:
153
src/bozodown.py
153
src/bozodown.py
@ -1,153 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from collections.abc import Callable
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
def _photohub_render(id: str, text: str) -> str:
|
|
||||||
if (id == "img"):
|
|
||||||
return f"<img src='{text[2:-1]}'>"
|
|
||||||
|
|
||||||
def _bozodown_render(id: str, text: str) -> str:
|
|
||||||
if (id == "list"):
|
|
||||||
print("error: list not supported")
|
|
||||||
return ""
|
|
||||||
if (id == "block"):
|
|
||||||
style, to_parse = text[5:-5].split("---")
|
|
||||||
style = style.replace("\n", "")
|
|
||||||
content: str = render(to_parse)
|
|
||||||
return f"""
|
|
||||||
<div style="{style}">
|
|
||||||
{content}
|
|
||||||
</div>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
_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": "<h1>",
|
|
||||||
"to_suffix": "</h1>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "## ",
|
|
||||||
"from_suffix": "\n",
|
|
||||||
"to_prefix": "<h2>",
|
|
||||||
"to_suffix": "</h2>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "### ",
|
|
||||||
"from_suffix": "\n",
|
|
||||||
"to_prefix": "<h3>",
|
|
||||||
"to_suffix": "</h3>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "#### ",
|
|
||||||
"from_suffix": "\n",
|
|
||||||
"to_prefix": "<h4>",
|
|
||||||
"to_suffix": "</h4>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "`",
|
|
||||||
"from_suffix": "`",
|
|
||||||
"to_prefix": "<p><code>",
|
|
||||||
"to_suffix": "</code></p>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "**",
|
|
||||||
"from_suffix": "**",
|
|
||||||
"to_prefix": "<strong>",
|
|
||||||
"to_suffix": "</strong>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "- ",
|
|
||||||
"from_suffix": "\n",
|
|
||||||
"code": "bozodown:list",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "```",
|
|
||||||
"from_suffix": "```",
|
|
||||||
"to_prefix": "<pre><code>",
|
|
||||||
"to_suffix": "</code></pre>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "![",
|
|
||||||
"from_suffix": "]",
|
|
||||||
"code": "photohub:img",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "- [ ] ",
|
|
||||||
"from_suffix": "\n",
|
|
||||||
"to_prefix": "<li><input type='checkbox' disabled> ",
|
|
||||||
"to_suffix": "</li>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "- [x] ",
|
|
||||||
"from_suffix": "\n",
|
|
||||||
"to_prefix": "<li><input type='checkbox' checked disabled> ",
|
|
||||||
"to_suffix": "</li>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "<br>",
|
|
||||||
"from_suffix": "",
|
|
||||||
"to_prefix": "<br>",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"from_prefix": "-----",
|
|
||||||
"from_suffix": "-----",
|
|
||||||
"code": "bozodown:block"
|
|
||||||
},
|
|
||||||
]
|
|
||||||
|
|
||||||
_default_converter: dict[str, str] = {
|
|
||||||
"from_prefix": "",
|
|
||||||
"to_prefix": "<p>",
|
|
||||||
"to_suffix": "</p>",
|
|
||||||
}
|
|
||||||
|
|
||||||
def _render_element(text: str, converter: dict[str, str]) -> str:
|
|
||||||
code: str = converter.get("code")
|
|
||||||
if (code is not None):
|
|
||||||
namespace, id = code.split(":")
|
|
||||||
func = _specific_case_namespaces[namespace]
|
|
||||||
return func(id, text)
|
|
||||||
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 + len(prefix))
|
|
||||||
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
|
|
1
src/bozodown/__init__.py
Normal file
1
src/bozodown/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
__all__ = ["Bozodown"]
|
65
src/bozodown/bozodown.py
Normal file
65
src/bozodown/bozodown.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
|
||||||
|
from . import default_converters
|
||||||
|
|
||||||
|
class Bozodown():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._converters: dict[str, dict[str, str]] = default_converters.converters.copy()
|
||||||
|
self._text_converter: dict[str, str] = default_converters.text_converter.copy()
|
||||||
|
self._specific_case_namespaces: dict[str, Callable[[object, str, str], str]] = {
|
||||||
|
"bozodown": self._bozodown_render,
|
||||||
|
}
|
||||||
|
|
||||||
|
def render(self, to_parse: str):
|
||||||
|
content: str = ""
|
||||||
|
while len(to_parse) > 0:
|
||||||
|
text, converter = self._get_first_converter(to_parse)
|
||||||
|
content += self._render_element(text, converter)
|
||||||
|
to_parse = to_parse[len(text):]
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def _render_element(self, text: str, converter: dict[str, str]) -> str:
|
||||||
|
code: str = converter.get("code")
|
||||||
|
if (code is not None):
|
||||||
|
namespace, id = code.split(":")
|
||||||
|
func = self._specific_case_namespaces[namespace]
|
||||||
|
return func(id, text)
|
||||||
|
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 _bozodown_render(self, id: str, text: str) -> str:
|
||||||
|
if (id == "list"):
|
||||||
|
print("error: list not supported")
|
||||||
|
return ""
|
||||||
|
if (id == "block"):
|
||||||
|
style, to_parse = text[5:-5].split("---")
|
||||||
|
style = style.replace("\n", "")
|
||||||
|
content: str = self.render(to_parse)
|
||||||
|
return f"<div style='{style}'>{content}</div>"
|
||||||
|
|
||||||
|
def _get_first_converter(self, text: str) -> tuple[str, dict] | None:
|
||||||
|
first_converter_found: dict[str, str] | None = None
|
||||||
|
start: int | None = None
|
||||||
|
for converter in self._converters.values():
|
||||||
|
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, self._text_converter
|
||||||
|
if (start != 0):
|
||||||
|
return text[:start], self._text_converter
|
||||||
|
suffix: int = first_converter_found.get("from_suffix", "")
|
||||||
|
prefix: int = first_converter_found['from_prefix']
|
||||||
|
stop: int = text.find(suffix, start + len(prefix))
|
||||||
|
if (stop == -1):
|
||||||
|
print(f"error: '{prefix}' was never finished by a '{suffix}'")
|
||||||
|
return
|
||||||
|
stop += len(suffix)
|
||||||
|
return text[start:stop], first_converter_found
|
83
src/bozodown/default_converters.py
Normal file
83
src/bozodown/default_converters.py
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
converters: list[str, dict[str, str]] = {
|
||||||
|
"title": {
|
||||||
|
"from_prefix": "# ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"to_prefix": "<h1>",
|
||||||
|
"to_suffix": "</h1>",
|
||||||
|
},
|
||||||
|
"subtitle": {
|
||||||
|
"from_prefix": "## ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"to_prefix": "<h2>",
|
||||||
|
"to_suffix": "</h2>",
|
||||||
|
},
|
||||||
|
"subsubtitle": {
|
||||||
|
"from_prefix": "### ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"to_prefix": "<h3>",
|
||||||
|
"to_suffix": "</h3>",
|
||||||
|
},
|
||||||
|
"subsubsubtitle": {
|
||||||
|
"from_prefix": "#### ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"to_prefix": "<h4>",
|
||||||
|
"to_suffix": "</h4>",
|
||||||
|
},
|
||||||
|
"quote": {
|
||||||
|
"from_prefix": "`",
|
||||||
|
"from_suffix": "`",
|
||||||
|
"to_prefix": "<p><code>",
|
||||||
|
"to_suffix": "</code></p>",
|
||||||
|
},
|
||||||
|
"bold": {
|
||||||
|
"from_prefix": "**",
|
||||||
|
"from_suffix": "**",
|
||||||
|
"to_prefix": "<strong>",
|
||||||
|
"to_suffix": "</strong>",
|
||||||
|
},
|
||||||
|
"list": {
|
||||||
|
"from_prefix": "- ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"code": "bozodown:list",
|
||||||
|
},
|
||||||
|
"code": {
|
||||||
|
"from_prefix": "```",
|
||||||
|
"from_suffix": "```",
|
||||||
|
"to_prefix": "<pre><code>",
|
||||||
|
"to_suffix": "</code></pre>",
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"from_prefix": "![",
|
||||||
|
"from_suffix": "]",
|
||||||
|
"to_prefix": "<img src='",
|
||||||
|
"to_suffix": "'>",
|
||||||
|
},
|
||||||
|
"block": {
|
||||||
|
"from_prefix": "-----",
|
||||||
|
"from_suffix": "-----",
|
||||||
|
"code": "bozodown:block",
|
||||||
|
},
|
||||||
|
"checkbox_clear": {
|
||||||
|
"from_prefix": "- [ ] ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"to_prefix": "<li><input type='checkbox' disabled> ",
|
||||||
|
"to_suffix": "</li>",
|
||||||
|
},
|
||||||
|
"checkbox_full": {
|
||||||
|
"from_prefix": "- [x] ",
|
||||||
|
"from_suffix": "\n",
|
||||||
|
"to_prefix": "<li><input type='checkbox' checked disabled> ",
|
||||||
|
"to_suffix": "</li>",
|
||||||
|
},
|
||||||
|
"newline": {
|
||||||
|
"from_prefix": "<br>",
|
||||||
|
"from_suffix": "",
|
||||||
|
"to_prefix": "<br>",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
text_converter: dict[str, str] = {
|
||||||
|
"from_prefix": "",
|
||||||
|
"to_prefix": "<p>",
|
||||||
|
"to_suffix": "</p>",
|
||||||
|
}
|
28
src/photodown.py
Normal file
28
src/photodown.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
from bozodown.bozodown import Bozodown
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from picture import Picture
|
||||||
|
from bulk_page import BulkPage
|
||||||
|
|
||||||
|
class Photodown(Bozodown):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._specific_case_namespaces.update({"photohub": self._photohub_render})
|
||||||
|
image_converter = self._converters.get("image")
|
||||||
|
image_converter.update({"code": "photohub:image"})
|
||||||
|
self._bulk: list[Picture] = []
|
||||||
|
|
||||||
|
def add_bulk(self, bulk: list[Picture]):
|
||||||
|
self._bulk = bulk.copy()
|
||||||
|
|
||||||
|
def _photohub_render(self, id: str, text: str) -> str:
|
||||||
|
if (id == "image"):
|
||||||
|
picture_url = f"{text[2:-1]}"
|
||||||
|
|
||||||
|
return f"<img src='{picture_url}'>"
|
||||||
|
|
Reference in New Issue
Block a user