commit 8e9b6f32bbc0456ae9c33a8b323ec388df36036a
parent 516941ab2da836ffab7e0e9c0135487bbdb9551f
Author: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Date: Thu, 5 Sep 2024 14:32:08 +0800
parse: handle the preabmle
The preamble is currently defined as all content that isn't an opening
tag.
Signed-off-by: Jack Mordaunt <jackmordaunt.dev@gmail.com>
Diffstat:
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/html.odin b/html.odin
@@ -2,7 +2,8 @@ package html
// Document is the root level data structure containing the entire document.
Document :: struct {
- root: Node_Tag,
+ preamble: string,
+ root: Node_Tag,
}
// Node_Tag is a tag element that might contain other tags.
diff --git a/parse.odin b/parse.odin
@@ -22,12 +22,34 @@ parse :: proc(text: string) -> Document {
@(private = "file")
_parse_document :: proc(l: ^Lexer) -> (doc: Document) {
+ doc.preamble = _parse_preamble(l)
doc.root.name = "html"
doc.root.children = _parse_children(l)
return
}
@(private = "file")
+_parse_preamble :: proc(l: ^Lexer) -> (s: string) {
+ for {
+ t, ok := lexer_peek_token(l)
+ if !ok {
+ break
+ }
+ if token_kind(t) == .Open_Tag_Start {
+ break
+ }
+ switch t in t {
+ case Token_Span:
+ s = l.source[0:t.end + 1]
+ case Token_Atom:
+ s = l.source[0:t.start + 1]
+ }
+ lexer_next(l)
+ }
+ return
+}
+
+@(private = "file")
_parse_attributes :: proc(l: ^Lexer) -> (attrs: [dynamic]Attribute) {
for token in lexer_next(l) {
#partial switch token_kind(token) {
@@ -102,6 +124,20 @@ test_parse_doctype :: proc(t: ^testing.T) {
}
@(test)
+test_parse_doctype_2 :: proc(t: ^testing.T) {
+ text := "<!DOCTYPE html><html><body><div>foo</div></body></html>"
+
+ want := []Node {
+ Node_Tag{name = "html"},
+ Node_Tag{name = "body"},
+ Node_Tag{name = "div"},
+ Node_Text{text = "foo"},
+ }
+
+ _test_parse(t, text, want)
+}
+
+@(test)
test_parse_single_tag :: proc(t: ^testing.T) {
text := "<button />"