diff --git a/src/glxml.gleam b/src/glxml.gleam index 9857965..ccc1578 100644 --- a/src/glxml.gleam +++ b/src/glxml.gleam @@ -1,16 +1,16 @@ +import gleam/option.{type Option, None} import gleam/result pub type Declaration { - Declaration(versioninfo: String, encoding: String) + Declaration(versioninfo: String, encoding: String, standalone: Bool) } pub type DocType { - None DocType(name: String) } pub type Document { - Document(decl: Declaration, doctype: DocType) + Document(decl: Declaration, doctype: Option(DocType)) } pub fn main() { @@ -23,8 +23,13 @@ fn parse_document(doc: String) -> Result(Document, Nil) { Ok(Document(decl, doctype)) } -fn parse_prolog(doc: String) -> Result(#(Declaration, DocType, String), Nil) { - use #(decl, doc) <- result.try(parse_decl(doc)) +fn parse_prolog( + doc: String, +) -> Result(#(Declaration, Option(DocType), String), Nil) { + let #(decl, doc) = case parse_decl(doc) { + Ok(#(decl, doc)) -> #(decl, doc) + _ -> #(Declaration("1.0", "UTF-8", False), doc) + } Ok(#(decl, None, doc)) } @@ -37,9 +42,14 @@ fn parse_decl(doc: String) -> Result(#(Declaration, String), Nil) { Ok(e) -> e Error(_) -> #("", doc) } + let #(standalone, doc) = case parse_standalone(doc) { + Ok(e) -> e + Error(_) -> #(False, doc) + } case trim_space(doc) { - "?>" <> tail -> Ok(#(Declaration(versioninfo:, encoding:), tail)) + "?>" <> tail -> + Ok(#(Declaration(versioninfo:, encoding:, standalone:), tail)) _ -> Error(Nil) } } @@ -142,6 +152,17 @@ fn parse_encoding(doc: String) -> Result(#(String, String), Nil) { } } +fn parse_standalone(doc: String) -> Result(#(Bool, String), Nil) { + use #(_, doc) <- result.try(parse_space(doc)) + + case doc { + "standalone=\"yes\"" <> tail | "standalone='yes'" <> tail -> + Ok(#(True, tail)) + "standalone=\"no\"" <> tail | "standalone='no'" <> tail -> Ok(#(True, tail)) + _ -> Error(Nil) + } +} + fn do_parse_digit(doc: String) -> Result(#(String, String), Nil) { case doc { "0" as digit <> tail