From b042a297b556cab3755f07536769c9740b15ac43 Mon Sep 17 00:00:00 2001 From: truePhilipp Date: Sun, 5 May 2024 20:48:28 +0200 Subject: [PATCH] more formatting --- html_to_django/converter.py | 6 ++-- html_to_django/formatters/__init__.py | 6 ++-- html_to_django/formatters/style_formatter.py | 34 +++++++++++++++++++ .../formatters/style_raw_formatter.py | 12 +++++++ tests/formatters/tests_block_formatter.py | 2 +- 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 html_to_django/formatters/style_formatter.py create mode 100644 html_to_django/formatters/style_raw_formatter.py diff --git a/html_to_django/converter.py b/html_to_django/converter.py index 5288eb3..3e4d7b2 100644 --- a/html_to_django/converter.py +++ b/html_to_django/converter.py @@ -18,7 +18,9 @@ def convert_file(path: str, overwrite: bool = False) -> None: out_path = path.replace(".html", ".n.html") with open(out_path, "w") as file: file.write("{% load static %}\n") - file.write(soup.prettify(formatter=bs4.formatter.HTMLFormatter(indent=4))) + file.write(soup + .prettify(formatter=bs4.formatter.HTMLFormatter(indent=4)) + .replace(""", '"')) # Could this cause any issues? (maybe in attributes) def convert_dir(path: str, overwrite: bool = False) -> None: @@ -29,6 +31,6 @@ def convert_dir(path: str, overwrite: bool = False) -> None: def command_entry() -> None: path = os.path.abspath(sys.argv[1]) if os.path.isdir(path): - convert_dir(path) + convert_dir(path, True) elif os.path.isfile(path): convert_file(path) diff --git a/html_to_django/formatters/__init__.py b/html_to_django/formatters/__init__.py index adbd25b..2c991ed 100644 --- a/html_to_django/formatters/__init__.py +++ b/html_to_django/formatters/__init__.py @@ -1,6 +1,8 @@ from . import (for_formatter, if_formatter, var_formatter, block_formatter, static_formatter, attr_formatter, - for_wrap_formatter, unwrap_formatter, include_formatter, remove_default_formatter, command_formatter) + for_wrap_formatter, unwrap_formatter, include_formatter, remove_default_formatter, command_formatter, + style_formatter, style_raw_formatter) formatters = [for_formatter, if_formatter, var_formatter, block_formatter, static_formatter, attr_formatter, - for_wrap_formatter, unwrap_formatter, include_formatter, remove_default_formatter, command_formatter] + for_wrap_formatter, unwrap_formatter, include_formatter, remove_default_formatter, command_formatter, + style_formatter, style_raw_formatter] diff --git a/html_to_django/formatters/style_formatter.py b/html_to_django/formatters/style_formatter.py new file mode 100644 index 0000000..dcda57b --- /dev/null +++ b/html_to_django/formatters/style_formatter.py @@ -0,0 +1,34 @@ +from bs4 import BeautifulSoup + + +def parse_style(style: str) -> dict: + result = {} + key_buffer = "" + buffer = "" + for char in style: + if char == ":" and not key_buffer: + key_buffer = buffer + buffer = "" + elif char == ";": + result[key_buffer] = buffer + key_buffer = "" + buffer = "" + elif char != " ": + buffer += char + if key_buffer and buffer: + result[key_buffer] = buffer + return result + + +def style_to_string(style: dict) -> str: + return ";".join([f"{name}:{value}" for name, value in style.items()]) + + +def format(soup: BeautifulSoup) -> None: + for element in soup.find_all(attrs={"dj-style": True}): + style = parse_style(element["style"]) + dj_style = element.get("dj-style").replace(""", '"') + for name, value, value_type in [declaration.split(";") for declaration in dj_style.split("~") if declaration]: + style[name] = f"{{{{ {value} }}}}{value_type}" + element["style"] = style_to_string(style) + del element.attrs["dj-style"] diff --git a/html_to_django/formatters/style_raw_formatter.py b/html_to_django/formatters/style_raw_formatter.py new file mode 100644 index 0000000..ea2d2ea --- /dev/null +++ b/html_to_django/formatters/style_raw_formatter.py @@ -0,0 +1,12 @@ +from bs4 import BeautifulSoup +from .style_formatter import parse_style, style_to_string + + +def format(soup: BeautifulSoup) -> None: + for element in soup.find_all(attrs={"dj-style-raw": True}): + style = parse_style(element["style"]) + dj_style = element.get("dj-style-raw") + for name, value in [declaration.split(";") for declaration in dj_style.split("~") if declaration]: + style[name] = value + element["style"] = style_to_string(style) + del element.attrs["dj-style-raw"] diff --git a/tests/formatters/tests_block_formatter.py b/tests/formatters/tests_block_formatter.py index f78dbcc..7ba9eda 100644 --- a/tests/formatters/tests_block_formatter.py +++ b/tests/formatters/tests_block_formatter.py @@ -17,4 +17,4 @@ class BlockTests(TestCase): def test_with_block_inside(self): soup = BeautifulSoup('
Test
', "html.parser") block_formatter.format(soup) - self.assertEqual("{% block content %}{% block inner %}Test{% endblock %}{% endblock %}", str(soup)) \ No newline at end of file + self.assertEqual("{% block content %}{% block inner %}Test{% endblock %}{% endblock %}", str(soup))