This commit is contained in:
		@@ -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 &#38;ha' battr='baba' ref='&'/><!-- ma comment --><![CDATA[Testing&&<haha>]]></b>",
 | 
			
		||||
    "<?xml version=\"1.1\" encoding='UTF-8'?>\r\n   <!-- hello-world -->   \n<b><a attr='ha &#38;ha' battr='baba' ref='&'/><!-- 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)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user