author | nipkow |
Tue, 17 Jun 2025 06:29:55 +0200 | |
changeset 82732 | 71574900b6ba |
parent 80860 | 64dc09f7f189 |
permissions | -rw-r--r-- |
80850 | 1 |
(* Title: Pure/PIDE/xml0.ML |
80801 | 2 |
Author: Makarius |
3 |
||
80860 | 4 |
Untyped XML trees and YXML notation: minimal bootstrap version. |
80801 | 5 |
*) |
6 |
||
80860 | 7 |
(** XML **) |
8 |
||
80801 | 9 |
signature XML = |
10 |
sig |
|
11 |
type attributes = (string * string) list |
|
12 |
datatype tree = |
|
13 |
Elem of (string * attributes) * tree list |
|
14 |
| Text of string |
|
15 |
type body = tree list |
|
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
16 |
val xml_elemN: string |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
17 |
val xml_nameN: string |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
18 |
val xml_bodyN: string |
80836 | 19 |
val wrap_elem: ((string * attributes) * body) * body -> tree |
20 |
val unwrap_elem: tree -> (((string * attributes) * body) * body) option |
|
80838
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
21 |
val unwrap_elem_body: tree -> body option |
80851 | 22 |
val traverse_text: (string -> 'a -> 'a) -> tree -> 'a -> 'a |
23 |
val traverse_texts: (string -> 'a -> 'a) -> body -> 'a -> 'a |
|
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
24 |
val content_of: body -> string |
80801 | 25 |
end |
26 |
||
27 |
structure XML: XML = |
|
28 |
struct |
|
29 |
||
30 |
type attributes = (string * string) list; |
|
31 |
||
32 |
datatype tree = |
|
33 |
Elem of (string * attributes) * tree list |
|
34 |
| Text of string; |
|
35 |
||
36 |
type body = tree list; |
|
37 |
||
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
38 |
|
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
39 |
(* wrapped elements *) |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
40 |
|
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
41 |
val xml_elemN = "xml_elem"; |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
42 |
val xml_nameN = "xml_name"; |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
43 |
val xml_bodyN = "xml_body"; |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
44 |
|
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
45 |
fun wrap_elem (((a, atts), body1), body2) = |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
46 |
Elem ((xml_elemN, (xml_nameN, a) :: atts), Elem ((xml_bodyN, []), body1) :: body2); |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
47 |
|
80837 | 48 |
fun unwrap_elem (Elem ((name, (n, a) :: atts), Elem ((name', []), body1) :: body2)) = |
49 |
if name = xml_elemN andalso n = xml_nameN andalso name' = xml_bodyN |
|
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
50 |
then SOME (((a, atts), body1), body2) else NONE |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
51 |
| unwrap_elem _ = NONE; |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
52 |
|
80838
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
53 |
fun unwrap_elem_body (Elem ((name, (n, _) :: _), Elem ((name', []), _) :: body)) = |
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
54 |
if name = xml_elemN andalso n = xml_nameN andalso name' = xml_bodyN |
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
55 |
then SOME body else NONE |
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
56 |
| unwrap_elem_body _ = NONE; |
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
57 |
|
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
58 |
|
80851 | 59 |
(* traverse text content *) |
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
60 |
|
80851 | 61 |
fun traverse_text f tree = |
80838
aaf9e8a392cc
minor performance tuning, following Isabelle/Scala;
wenzelm
parents:
80837
diff
changeset
|
62 |
(case unwrap_elem_body tree of |
80851 | 63 |
SOME ts => traverse_texts f ts |
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
64 |
| NONE => |
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
65 |
(case tree of |
80851 | 66 |
Elem (_, ts) => traverse_texts f ts |
67 |
| Text s => f s)) |
|
68 |
and traverse_texts _ [] res = res |
|
69 |
| traverse_texts f (t :: ts) res = traverse_texts f ts (traverse_text f t res); |
|
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
70 |
|
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
71 |
fun content_of body = |
80851 | 72 |
String.concat (rev (traverse_texts (fn x => fn xs => x :: xs) body [])); |
80803
7e39c785ca5d
clarified modules: enable pretty.ML to use XML/YXML more directly;
wenzelm
parents:
80801
diff
changeset
|
73 |
|
80801 | 74 |
end; |
80860 | 75 |
|
76 |
||
77 |
||
78 |
(** YXML **) |
|
79 |
||
80 |
signature YXML = |
|
81 |
sig |
|
82 |
val X_char: char |
|
83 |
val Y_char: char |
|
84 |
val X: string |
|
85 |
val Y: string |
|
86 |
val XY: string |
|
87 |
val XYX: string |
|
88 |
val detect: string -> bool |
|
89 |
val output_markup: string * XML.attributes -> string * string |
|
90 |
end; |
|
91 |
||
92 |
structure YXML: YXML = |
|
93 |
struct |
|
94 |
||
95 |
(* markers *) |
|
96 |
||
97 |
val X_char = Char.chr 5; |
|
98 |
val Y_char = Char.chr 6; |
|
99 |
||
100 |
val X = String.str X_char; |
|
101 |
val Y = String.str Y_char; |
|
102 |
val XY = X ^ Y; |
|
103 |
val XYX = XY ^ X; |
|
104 |
||
105 |
fun detect s = Char.contains s X_char orelse Char.contains s Y_char; |
|
106 |
||
107 |
||
108 |
(* output markup *) |
|
109 |
||
110 |
fun output_markup ("", _) = ("", "") |
|
111 |
| output_markup (name, atts) = |
|
112 |
let |
|
113 |
val bgs = XY :: name :: List.foldr (fn ((a, b), ps) => Y :: a :: "=" :: b :: ps) [X] atts; |
|
114 |
val en = XYX; |
|
115 |
in (String.concat bgs, en) end; |
|
116 |
||
117 |
end; |