Skip to content

Commit

Permalink
Fix text elements
Browse files Browse the repository at this point in the history
  • Loading branch information
reznakt committed Nov 20, 2024
1 parent 60094f1 commit 3b1549f
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 23 deletions.
7 changes: 7 additions & 0 deletions svglab/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
from .elements import CData, Comment, Text
from .io import parse_svg


def main() -> None:
soup = parse_svg("<foo></foo>")
print(soup.prettify())
comment = Comment("foo")
print(comment)
cdata = CData("bar")
print(cdata)
text = Text("baz")
print(text)


if __name__ == "__main__":
Expand Down
16 changes: 5 additions & 11 deletions svglab/elements/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,20 @@ def __repr__(self) -> str:

class Element[T: PageElement](Repr, metaclass=ABCMeta):
def __init__(self, backend: T | None = None) -> None:
self._backend = backend if backend is not None else self._backend_type()
self._backend = backend if backend is not None else self._default_backend

@property
@abstractmethod
def _backend_type(self) -> type[T]: ...
def _default_backend(self) -> T: ...

def __str__(self) -> str:
return self.to_str(pretty=False)
soup = BeautifulSoup()
soup.append(self._backend)
return soup.prettify().strip()

@abstractmethod
def __hash__(self) -> int: ...

def to_str(self, *, pretty: bool = True) -> str:
if pretty:
soup = BeautifulSoup()
soup.append(self._backend)
return soup.prettify()

return str(self._backend)

def __eq__(self, other: object) -> bool:
if not isinstance(other, self.__class__):
return False
Expand Down
50 changes: 38 additions & 12 deletions svglab/elements/text_element.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from abc import ABCMeta, abstractmethod
from abc import ABCMeta
from contextlib import suppress
from typing import cast, final

Expand All @@ -17,6 +17,8 @@ class TextElement[T: _Comment | _CData | NavigableString](
def __init__(
self,
content: str | None = None,
/,
*,
backend: T | None = None,
) -> None:
super().__init__(backend=backend)
Expand All @@ -40,33 +42,57 @@ def content(self, content: str) -> None:
# TODO: figure out a way for mypy to eat this without the cast
self._backend = cast(T, comment)

def __str__(self) -> str:
return self.content

def __hash__(self) -> int:
return hash(self.content)

@property
@abstractmethod
def _backend_type(self) -> type[T]: ...
def _backend_type(self) -> type[T]:
return type(self._default_backend)


@final
class Comment(TextElement[_Comment]):
"""Represents an XML/HTML comment.
Example:
>>> comment = Comment("foo")
>>> print(comment)
<!--foo-->
"""

@property
def _backend_type(self) -> type[_Comment]:
return _Comment
def _default_backend(self) -> _Comment:
return _Comment("")


@final
class CData(TextElement[_CData]):
"""Represents an XML/HTML CDATA section.
Example:
>>> cdata = CData("foo")
>>> print(cdata)
<![CDATA[foo]]>
"""

@property
def _backend_type(self) -> type[_CData]:
return _CData
def _default_backend(self) -> _CData:
return _CData("")


@final
class Text(TextElement[NavigableString]):
"""Represents an XML/HTML text section.
Example:
>>> text = Text("foo")
>>> print(text)
foo
"""

@property
def _backend_type(self) -> type[NavigableString]:
return NavigableString
def _default_backend(self) -> NavigableString:
return NavigableString("")

0 comments on commit 3b1549f

Please sign in to comment.