| author | wenzelm |
| Tue, 02 Jan 2018 19:52:17 +0100 | |
| changeset 67323 | d02208cefbdb |
| parent 67193 | 4ade0d387429 |
| child 67426 | 6311cf9dc943 |
| permissions | -rw-r--r-- |
|
30587
ad19c99529eb
moved Isar/antiquote.ML to General/antiquote.ML, which is loaded early;
wenzelm
parents:
30573
diff
changeset
|
1 |
(* Title: Pure/General/antiquote.ML |
|
55511
984e210d412e
antiquotations within plain text: Scala version in accordance to ML;
wenzelm
parents:
55107
diff
changeset
|
2 |
Author: Makarius |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
3 |
|
|
55511
984e210d412e
antiquotations within plain text: Scala version in accordance to ML;
wenzelm
parents:
55107
diff
changeset
|
4 |
Antiquotations within plain text. |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
5 |
*) |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
6 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
7 |
signature ANTIQUOTE = |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
8 |
sig |
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
9 |
type control = {range: Position.range, name: string * Position.T, body: Symbol_Pos.T list}
|
|
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
10 |
type antiq = {start: Position.T, stop: Position.T, range: Position.range, body: Symbol_Pos.T list}
|
|
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
11 |
datatype 'a antiquote = Text of 'a | Control of control | Antiq of antiq |
| 61434 | 12 |
type text_antiquote = Symbol_Pos.T list antiquote |
| 61450 | 13 |
val range: text_antiquote list -> Position.range |
| 61434 | 14 |
val split_lines: text_antiquote list -> text_antiquote list list |
| 61457 | 15 |
val antiq_reports: 'a antiquote list -> Position.report list |
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
16 |
val scan_control: Symbol_Pos.T list -> control * Symbol_Pos.T list |
| 55526 | 17 |
val scan_antiq: Symbol_Pos.T list -> antiq * Symbol_Pos.T list |
| 61434 | 18 |
val scan_antiquote: Symbol_Pos.T list -> text_antiquote * Symbol_Pos.T list |
| 62749 | 19 |
val parse: Position.T -> Symbol_Pos.T list -> text_antiquote list |
| 61434 | 20 |
val read: Input.source -> text_antiquote list |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
21 |
end; |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
22 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
23 |
structure Antiquote: ANTIQUOTE = |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
24 |
struct |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
25 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
26 |
(* datatype antiquote *) |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
27 |
|
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
28 |
type control = {range: Position.range, name: string * Position.T, body: Symbol_Pos.T list};
|
|
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
29 |
type antiq = {start: Position.T, stop: Position.T, range: Position.range, body: Symbol_Pos.T list};
|
|
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
30 |
datatype 'a antiquote = Text of 'a | Control of control | Antiq of antiq; |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
31 |
|
| 61434 | 32 |
type text_antiquote = Symbol_Pos.T list antiquote; |
33 |
||
| 61450 | 34 |
fun antiquote_range (Text ss) = Symbol_Pos.range ss |
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
35 |
| antiquote_range (Control {range, ...}) = range
|
|
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
36 |
| antiquote_range (Antiq {range, ...}) = range;
|
| 61450 | 37 |
|
38 |
fun range ants = |
|
39 |
if null ants then Position.no_range |
|
| 62797 | 40 |
else Position.range (#1 (antiquote_range (hd ants)), #2 (antiquote_range (List.last ants))); |
| 61450 | 41 |
|
| 61434 | 42 |
|
43 |
(* split lines *) |
|
44 |
||
45 |
fun split_lines input = |
|
46 |
let |
|
47 |
fun add a (line, lines) = (a :: line, lines); |
|
48 |
fun flush (line, lines) = ([], rev line :: lines); |
|
49 |
fun split (a as Text ss) = |
|
50 |
(case take_prefix (fn ("\n", _) => false | _ => true) ss of
|
|
51 |
([], []) => I |
|
52 |
| (_, []) => add a |
|
53 |
| ([], _ :: rest) => flush #> split (Text rest) |
|
54 |
| (prefix, _ :: rest) => add (Text prefix) #> flush #> split (Text rest)) |
|
55 |
| split a = add a; |
|
| 61440 | 56 |
in if null input then [] else rev (#2 (flush (fold split input ([], [])))) end; |
| 61434 | 57 |
|
| 27342 | 58 |
|
| 44736 | 59 |
(* reports *) |
|
30641
72980f8d7ee8
export report -- version that actually covers all cases;
wenzelm
parents:
30635
diff
changeset
|
60 |
|
| 61457 | 61 |
fun antiq_reports ants = ants |> maps |
| 61471 | 62 |
(fn Text _ => [] |
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
63 |
| Control {range = (pos, _), ...} => [(pos, Markup.antiquoted)]
|
|
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
64 |
| Antiq {start, stop, range = (pos, _), ...} =>
|
| 61471 | 65 |
[(start, Markup.antiquote), |
66 |
(stop, Markup.antiquote), |
|
67 |
(pos, Markup.antiquoted), |
|
68 |
(pos, Markup.language_antiquotation)]); |
|
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
69 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
70 |
|
|
30590
1d9c9fcf8513
parameterized datatype antiquote and read operation;
wenzelm
parents:
30589
diff
changeset
|
71 |
(* scan *) |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
72 |
|
| 30573 | 73 |
open Basic_Symbol_Pos; |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
74 |
|
| 22114 | 75 |
local |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
76 |
|
| 48764 | 77 |
val err_prefix = "Antiquotation lexical error: "; |
78 |
||
| 67193 | 79 |
val scan_nl = Scan.one (fn (s, _) => s = "\n") >> single; |
80 |
||
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
81 |
val scan_txt = |
| 67193 | 82 |
scan_nl || |
| 61476 | 83 |
Scan.repeats1 |
|
61491
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
84 |
(Scan.many1 (fn (s, _) => |
| 67193 | 85 |
not (Symbol.is_control s) andalso s <> Symbol.open_ andalso s <> "@" andalso |
86 |
s <> "\n" andalso Symbol.not_eof s) || |
|
87 |
$$$ "@" --| Scan.ahead (~$$ "{")) @@@ Scan.optional scan_nl [];
|
|
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
88 |
|
| 55512 | 89 |
val scan_antiq_body = |
| 48764 | 90 |
Scan.trace (Symbol_Pos.scan_string_qq err_prefix || Symbol_Pos.scan_string_bq err_prefix) >> #2 || |
| 61481 | 91 |
Symbol_Pos.scan_cartouche err_prefix || |
| 58854 | 92 |
Scan.one (fn (s, _) => s <> "}" andalso Symbol.not_eof s) >> single; |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
93 |
|
|
61491
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
94 |
fun control_name sym = (case Symbol.decode sym of Symbol.Control name => name); |
|
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
95 |
|
|
42508
e21362bf1d93
allow nested @{antiq} (nonterminal) and @@{antiq} terminal;
wenzelm
parents:
42503
diff
changeset
|
96 |
in |
|
e21362bf1d93
allow nested @{antiq} (nonterminal) and @@{antiq} terminal;
wenzelm
parents:
42503
diff
changeset
|
97 |
|
| 61471 | 98 |
val scan_control = |
|
61491
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
99 |
Scan.option (Scan.one (Symbol.is_control o Symbol_Pos.symbol)) -- |
| 61481 | 100 |
Symbol_Pos.scan_cartouche err_prefix >> |
|
61491
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
101 |
(fn (opt_control, body) => |
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
102 |
let |
|
61491
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
103 |
val (name, range) = |
|
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
104 |
(case opt_control of |
|
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
105 |
SOME (sym, pos) => ((control_name sym, pos), Symbol_Pos.range ((sym, pos) :: body)) |
|
97261e6c1d42
another antiquotation short form: undecorated cartouche as alias for @{text};
wenzelm
parents:
61481
diff
changeset
|
106 |
| NONE => (("cartouche", #2 (hd body)), Symbol_Pos.range body));
|
| 61595 | 107 |
in {name = name, range = range, body = body} end) ||
|
108 |
Scan.one (Symbol.is_control o Symbol_Pos.symbol) >> |
|
109 |
(fn (sym, pos) => |
|
110 |
{name = (control_name sym, pos), range = Symbol_Pos.range [(sym, pos)], body = []});
|
|
| 61471 | 111 |
|
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
112 |
val scan_antiq = |
| 55526 | 113 |
Symbol_Pos.scan_pos -- ($$ "@" |-- $$ "{" |-- Symbol_Pos.scan_pos --
|
| 48764 | 114 |
Symbol_Pos.!!! (fn () => err_prefix ^ "missing closing brace") |
| 61476 | 115 |
(Scan.repeats scan_antiq_body -- Symbol_Pos.scan_pos -- ($$ "}" |-- Symbol_Pos.scan_pos))) >> |
|
61473
34d1913f0b20
clarified control antiquotations: decode control symbol to get name;
wenzelm
parents:
61471
diff
changeset
|
116 |
(fn (pos1, (pos2, ((body, pos3), pos4))) => |
| 62797 | 117 |
{start = Position.range_position (pos1, pos2),
|
118 |
stop = Position.range_position (pos3, pos4), |
|
119 |
range = Position.range (pos1, pos4), |
|
| 61476 | 120 |
body = body}); |
|
30590
1d9c9fcf8513
parameterized datatype antiquote and read operation;
wenzelm
parents:
30589
diff
changeset
|
121 |
|
| 61471 | 122 |
val scan_antiquote = |
| 61481 | 123 |
scan_txt >> Text || scan_control >> Control || scan_antiq >> Antiq; |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
124 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
125 |
end; |
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
126 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
127 |
|
| 27767 | 128 |
(* read *) |
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
129 |
|
| 62749 | 130 |
fun parse pos syms = |
| 61456 | 131 |
(case Scan.read Symbol_Pos.stopper (Scan.repeat scan_antiquote) syms of |
| 62749 | 132 |
SOME ants => ants |
| 61456 | 133 |
| NONE => error ("Malformed quotation/antiquotation source" ^ Position.here pos));
|
134 |
||
| 62749 | 135 |
fun read source = |
136 |
let |
|
137 |
val ants = parse (Input.pos_of source) (Input.source_explode source); |
|
138 |
val _ = Position.reports (antiq_reports ants); |
|
139 |
in ants end; |
|
|
9138
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
140 |
|
|
6a4fae41a75f
Text with antiquotations of inner items (terms, types etc.).
wenzelm
parents:
diff
changeset
|
141 |
end; |