diff --git a/src/lib/sgml.pl b/src/lib/sgml.pl index 0289278e..a0370e8c 100644 --- a/src/lib/sgml.pl +++ b/src/lib/sgml.pl @@ -1,28 +1,30 @@ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Predicates for parsing HTML and XML documents. - Written June 2020 by Markus Triska (triska@metalevel.at) + Written 2020-2022 by Markus Triska (triska@metalevel.at) Part of Scryer Prolog. Currently, two predicates are provided: - - load_html(+Source, -Es, +Options) - - load_xml(+Source, -Es, +Options) + - load_html(+Source, -Es, +Options) + - load_xml(+Source, -Es, +Options) These predicates parse HTML and XML documents, respectively. - Source must be a stream, specified as stream(S), or a file, - specified as file(Name), where Name is a list of characters, or a - list of characters with the document contents. + Source must be one of: + + - a list of characters with the document contents + - stream(S), specifying a stream S from which to read the content + - file(Name), where Name is a list of characters specifying a file name. Es is unified with the abstract syntax tree of the parsed document, represented as a list of elements where each is of the form: - * a list of characters, representing text - * element(Name, Attrs, Children) - - Name is the name of the tag - - Attrs is a list of Key=Value pairs: - Key is an atom, and Value is a list of characters - - Children is a list of elements as specified here. + * a list of characters, representing text + * element(Name, Attrs, Children) + - Name, an atom, is the name of the tag + - Attrs is a list of Key=Value pairs: + Key is an atom, and Value is a list of characters + - Children is a list of elements as specified here. Currently, Options are ignored. In the future, more options may be provided to control parsing. @@ -61,21 +63,32 @@ :- use_module(library(charsio)). load_html(Source, Es, Options) :- + must_be_source(Source, load_html/3), + must_be(list, Options), load_structure_(Source, Es, Options, html). load_xml(Source, Es, Options) :- + must_be_source(Source, load_xml/3), + must_be(list, Options), load_structure_(Source, Es, Options, xml). +must_be_source(Source, Context) :- + ( var(Source) -> instantiation_error(Context) + ; is_sgml_source(Source) -> true + ; domain_error(sgml_source, Source, Context) + ). + +is_sgml_source(file(Fs)) :- must_be(chars, Fs). +is_sgml_source(stream(_)). +is_sgml_source([]). +is_sgml_source([C|Cs]) :- must_be(chars, [C|Cs]). + load_structure_([], [], _, _). load_structure_([C|Cs], [E], Options, What) :- load_(What, [C|Cs], E, Options). load_structure_(file(Fs), [E], Options, What) :- - must_be(list, Options), - must_be(list, Fs), - atom_chars(File, Fs), - once(phrase_from_file(seq(Cs), File)), + once(phrase_from_file(seq(Cs), Fs)), load_(What, Cs, E, Options). load_structure_(stream(Stream), [E], Options, What) :- - must_be(list, Options), get_n_chars(Stream, _, Cs), load_(What, Cs, E, Options).