diff --git a/tdom/parser.py b/tdom/parser.py
index 2eec36d8..57475b36 100644
--- a/tdom/parser.py
+++ b/tdom/parser.py
@@ -1,12 +1,24 @@
from collections.abc import Sequence
from dataclasses import dataclass, field
from html.parser import HTMLParser
-from string.templatelib import Interpolation, Template
+from string.templatelib import Template
from .htmlspec import VOID_ELEMENTS
-from .placeholders import PlaceholderConfig, PlaceholderState
-from .template_utils import TemplateRef, combine_template_refs
+from .parser_utils import (
+ HTMLAttribute,
+ ParserPositionTranslator,
+ make_parser_pos_translator,
+)
+from .placeholders import (
+ PlaceholderState,
+)
+from .source import (
+ LinePosition,
+ SourceReader,
+)
+from .template_utils import PartPosition, TemplateRef, combine_template_refs
from .tnodes import (
+ TagSourceInfo,
TAttribute,
TComment,
TComponent,
@@ -19,21 +31,59 @@
TSpreadAttribute,
TTemplatedAttribute,
TText,
+ TTree,
)
-type HTMLAttribute = tuple[str, str | None]
-type HTMLAttributesDict = dict[str, str | None]
+
+class ParsingError(Exception):
+ pass
+
+
+class ParsingAssertionError(ParsingError):
+ pass
+
+
+class AttributeParsingError(ParsingError):
+ pass
+
+
+@dataclass(frozen=True, slots=True)
+class OpenTagSourceInfo:
+ """
+ Retained tag information from the parsed source meant for error reporting.
+
+ @NOTE: This is an temporary structure that will be finalized when the
+ tag is closed.
+ """
+
+ starttag_ref: TemplateRef
+ " Entire starttag as parsed except placeholders are replaced by references. "
+ startend: bool
+ " Was parsed as startend tag, ie.
Warning!
") def test_interpolated_style_attribute_merged(self): @@ -1453,7 +1476,7 @@ def test_style_attribute_str(self): assert res == 'Warning!
' def test_style_attribute_non_str_non_dict(self): - with pytest.raises(TypeError): + with pytest.raises(AttributeProcessingError): styles = [1, 2] _ = html(t"Warning!
") @@ -1511,7 +1534,7 @@ def InputElement(size=10, type="text"): pass callable_info = get_callable_info(InputElement) - with pytest.raises(ValueError): + with pytest.raises(ComponentInvocationError): assert ( prep_component_kwargs(callable_info, {"type2": 15}, children=t"") == {} ) @@ -1555,7 +1578,9 @@ def Comp(children: Template) -> Template: return t"Positional arg: {whoops}
" - with pytest.raises(TypeError): + with pytest.raises( + ComponentInvocationError, match="cannot have required positional arguments" + ): _ = html(t"<{RequiresPositional} />") def test_mismatched_component_closing_tag_fails(self): @@ -1840,9 +1889,39 @@ def OpenTag(children: Template) -> Template: def CloseTag(children: Template) -> Template: return t"