diff --git a/src/glxml.gleam b/src/glxml.gleam
index da1d18d..5c417db 100644
--- a/src/glxml.gleam
+++ b/src/glxml.gleam
@@ -39,16 +39,16 @@ pub type Element {
pub fn main() {
parse_document(
- "\r\n \n",
+ "\r\n \n",
)
|> echo
}
pub fn default_entities() -> dict.Dict(String, Entity) {
dict.from_list([
- #("lt", InternalEntity("<")),
- #("gt", InternalEntity("#62;")),
- #("amp", InternalEntity("&")),
+ #("lt", InternalEntity("<")),
+ #("gt", InternalEntity(">")),
+ #("amp", InternalEntity("&")),
#("apos", InternalEntity("'")),
#("quot", InternalEntity(""")),
])
@@ -60,7 +60,7 @@ fn parse_document(doc: String) -> Result(Document, Nil) {
use #(element, doc) <- result.try(parse_element(doc, doctype))
let doc = parse_misc(doc)
- case doc |> echo {
+ case doc {
"" -> Ok(Document(decl, doctype, Some(element)))
_ -> Error(Nil)
}
@@ -77,7 +77,7 @@ fn parse_empty_elem(
doc: String,
doctype: Option(DocType),
) -> Result(#(Element, String), Nil) {
- case doc |> echo {
+ case doc {
"<" <> tail -> {
use #(name, doc) <- result.try(parse_name(tail))
use #(attrs, doc) <- result.try(parse_attributes(doc, doctype, []))
@@ -184,19 +184,19 @@ fn parse_reference(
";" <> tail -> {
use value <- result.try(int.base_parse(digits, 16))
use codepoint <- result.try(string.utf_codepoint(value))
- Ok(#("", string.from_utf_codepoints([codepoint]) <> tail))
+ Ok(#(string.from_utf_codepoints([codepoint]), tail))
}
_ -> Error(Nil)
}
}
_ -> {
use #(digits, doc) <- result.try(parse_multiple(tail, parse_digit))
-
case doc {
";" <> tail -> {
use value <- result.try(int.base_parse(digits, 10))
use codepoint <- result.try(string.utf_codepoint(value))
- Ok(#("", string.from_utf_codepoints([codepoint]) <> tail))
+
+ Ok(#(string.from_utf_codepoints([codepoint]), tail))
}
_ -> Error(Nil)
}
@@ -207,7 +207,10 @@ fn parse_reference(
use #(name, doc) <- result.try(parse_name(tail))
case doc {
- ";" <> tail -> Ok(#(char <> name <> ";", tail))
+ ";" <> tail -> {
+ use value <- result.try(process_reference(name, doctype))
+ Ok(#("", value <> tail))
+ }
_ -> Error(Nil)
}
}
@@ -215,6 +218,36 @@ fn parse_reference(
}
}
+fn process_reference(
+ ref: String,
+ doctype: Option(DocType),
+) -> Result(String, Nil) {
+ case doctype {
+ Some(DocType(_, entities)) -> {
+ get_reference(entities, ref)
+ }
+ None -> {
+ get_reference(default_entities(), ref)
+ }
+ }
+}
+
+fn get_reference(
+ entities: dict.Dict(String, Entity),
+ ref: String,
+) -> Result(String, Nil) {
+ case dict.get(entities, ref) {
+ Ok(InternalEntity(val)) -> Ok(val)
+ Ok(PublicExternalEntity(_, _)) | Ok(SystemExternalEntity(_)) -> Error(Nil)
+ Error(_) -> {
+ case entities == default_entities() {
+ True -> Error(Nil)
+ False -> get_reference(default_entities(), ref)
+ }
+ }
+ }
+}
+
fn parse_name(doc: String) -> Result(#(String, String), Nil) {
case parse_name_start_char(doc) {
Ok(#(char, tail)) -> {