(*********************************************************************************)
(*                Xtmpl                                                          *)
(*                                                                               *)
(*    Copyright (C) 2012-2021 Institut National de Recherche en Informatique     *)
(*    et en Automatique. All rights reserved.                                    *)
(*                                                                               *)
(*    This program is free software; you can redistribute it and/or modify       *)
(*    it under the terms of the GNU Lesser General Public License version        *)
(*    3 as published by the Free Software Foundation.                            *)
(*                                                                               *)
(*    This program is distributed in the hope that it will be useful,            *)
(*    but WITHOUT ANY WARRANTY; without even the implied warranty of             *)
(*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *)
(*    GNU Library General Public License for more details.                       *)
(*                                                                               *)
(*    You should have received a copy of the GNU Lesser General Public           *)
(*    License along with this program; if not, write to the Free Software        *)
(*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                   *)
(*    02111-1307  USA                                                            *)
(*                                                                               *)
(*    Contact: Maxence.Guesdon@inria.fr                                          *)
(*                                                                               *)
(*                                                                               *)
(*********************************************************************************)

(** Regular XML trees. *)

module SMap : Map.S with type key = string

(** {2 Errors} *)

type Types.error += Parse_error of Types.loc * string
val parse_error : Types.loc -> string -> 'a

(** {2 XML documents} *)

module Name : Map.OrderedType with type t = string * string
module Name_map : Map.S with type key = Name.t

val string_of_name : Name.t -> string

(** [name_of_string str] cuts a name according to first ':' character.
     If no such character is found, return [("",str)]. *)
val name_of_string : string -> Name.t

module P :
  sig
    module Attributes : Map.S with type key = Name.t
    type attr_value = string Types.with_loc_option
    type data = unit
    val default_data : unit -> data
    val version_name : unit -> Name.t
    val default_version : unit -> attr_value
    val default_attr_value : unit -> attr_value
    val pp_name : Format.formatter -> Name.t -> unit
    val pp_attr_value : Format.formatter -> attr_value -> unit
  end

(** XML documents with [string*string] as names and
  optionnaly located string as attribute values. *)
include (Types.S with
  type name = Name.t and
  type attr_value = P.attr_value and
  type attributes = P.attr_value Name_map.t and
  type data = unit)

module Name_set : Set.S with type elt = Name.t
module SSet : Set.S with type elt = string

(** {2 Parsing} *)

type parse_param =
  { ignore_unclosed : bool ; (** auto-close unclosed elements *)
    self_closing : SSet.t ; (** self-closing elements *)
    entities : Uchar.t SMap.t ; (** entity references to unescape to utf-8 chars *)
  }

val default_parse_param : parse_param
  (** Default: no self-closing tags, unescape XML entities (amp, apos,quot, lt, gt).
    ignore_unclosed: [false]. *)

val xml_entities : Uchar.t SMap.t (** mapping from XML entities to utf-8 code points *)
val html_entities : Uchar.t SMap.t (** mapping from HTML entities to utf-8 code points *)

(** Unescape character references and entity references from [parse_param.entities].
     @param entities can be set to [false] not to unescape entity references.
*)
val unescape : parse_param -> ?entities:bool -> string -> string

val from_string : ?param:parse_param -> ?pos_start:Types.pos -> string -> tree list
val from_channel : ?param:parse_param -> ?pos_start:Types.pos -> in_channel -> tree list
val from_file : ?param:parse_param -> string -> tree list

val doc_from_string : ?param:parse_param -> ?pos_start:Types.pos -> string -> doc
val doc_from_channel : ?param:parse_param -> ?pos_start:Types.pos -> in_channel -> doc
val doc_from_file : ?param:parse_param -> string -> doc


