feat: Added PI Parsing
Some checks failed
test / test (push) Has been cancelled

This commit is contained in:
2025-10-09 19:20:02 +01:00
parent 963f44dbeb
commit 489590bdac

View File

@@ -38,11 +38,13 @@ pub type Element {
Text(content: String)
Comment(content: String)
CData(content: String)
PI(name: String, content: String)
Whitespace
}
pub fn main() {
parse_document(
"<?xml version=\"1.1\" encoding='UTF-8'?>\r\n <!-- hello-world --> \n<b><a attr='ha&#x20;&#38;#38;ha' battr='baba' ref='&amp;'/><!-- ma comment --><![CDATA[Testing&&<haha>]]></b>",
"<?xml version=\"1.1\" encoding='UTF-8'?>\r\n <!-- hello-world --> \n<b><a attr='ha&#x20;&#38;#38;ha' battr='baba' ref='&amp;'/><!-- ma comment --><![CDATA[Testing&&<haha>]]><?test asuhashd ?></b>",
)
|> echo
}
@@ -153,13 +155,9 @@ fn parse_content(
try_parsers(
[
parse_element(_, doctype),
fn(doc) {
case parse_comment(doc) {
Ok(#(comment, doc)) -> Ok(#(Comment(comment), doc))
Error(_) -> Error(Nil)
}
},
parse_comment,
parse_cdata,
parse_pi,
],
doc,
)
@@ -172,6 +170,38 @@ fn parse_content(
}
}
fn parse_pi(doc: String) -> Result(#(Element, String), Nil) {
case doc {
"<?" <> tail -> {
use #(name, doc) <- result.try(parse_name(tail))
use <- bool.guard(
when: string.lowercase(name) == "xml",
return: Error(Nil),
)
let doc = trim_space(doc)
use #(content, doc) <- result.try(parse_pi_content(doc, ""))
case doc {
"?>" <> tail -> Ok(#(PI(name, content), tail))
_ -> Error(Nil)
}
}
_ -> Error(Nil)
}
}
fn parse_pi_content(doc: String, pi: String) -> Result(#(String, String), Nil) {
case doc {
"?>" <> _ -> Ok(#(pi, doc))
"" -> Error(Nil)
_ -> {
case parse_char(doc) {
Ok(#(char, doc)) -> parse_pi_content(doc, pi <> char)
Error(_) -> Ok(#(pi, doc))
}
}
}
}
fn parse_cdata(doc: String) -> Result(#(Element, String), Nil) {
case doc {
"<![CDATA[" <> tail -> {
@@ -404,13 +434,22 @@ fn parse_prolog(
}
fn parse_misc(doc: String) -> String {
let #(_, doc) =
parse_multiple_optional(
case
try_parsers(
[
parse_comment,
fn(doc) {
parse_space(doc)
|> result.map(fn(sp) { #(Whitespace, sp.1) })
},
parse_pi,
],
doc,
try_parsers([parse_comment, parse_space], _),
"",
)
doc
{
Ok(#(_element, doc)) -> parse_misc(doc)
Error(Nil) -> doc
}
}
fn parse_decl(doc: String) -> Result(#(Declaration, String), Nil) {
@@ -640,12 +679,12 @@ fn parse_alpha(doc: String) -> Result(#(String, String), Nil) {
}
}
fn parse_comment(doc: String) -> Result(#(String, String), Nil) {
fn parse_comment(doc: String) -> Result(#(Element, String), Nil) {
case doc {
"<!--" <> tail -> {
let #(comment, doc) = do_parse_comment(tail)
case doc {
"-->" <> tail -> Ok(#(comment, tail))
"-->" <> tail -> Ok(#(Comment(comment), tail))
_ -> Error(Nil)
}
}