author | Christian Urban <urbanc@in.tum.de> |
Tue, 17 Mar 2009 17:32:12 +0100 | |
changeset 183 | 8bb4eaa2ec92 |
parent 176 | 3da5f3f07d8b |
permissions | -rw-r--r-- |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
1 |
|
24 | 2 |
structure Chunks = |
3 |
struct |
|
4 |
||
171
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
5 |
(* rebuilding the output function from ThyOutput in order to *) |
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
6 |
(* enable the options [gray, linenos] *) |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
7 |
|
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
8 |
val gray = ref false; |
117
796c6ea633b3
added an option for linenumbers to the chunk-antiquotation
Christian Urban <urbanc@in.tum.de>
parents:
96
diff
changeset
|
9 |
val linenos = ref false |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
10 |
|
171
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
11 |
fun output prts = |
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
12 |
prts |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
13 |
|> (if ! ThyOutput.quotes then map Pretty.quote else I) |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
14 |
|> (if ! ThyOutput.display then |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
15 |
map (Output.output o Pretty.string_of o Pretty.indent (! ThyOutput.indent)) |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
16 |
#> space_implode "\\isasep\\isanewline%\n" |
118
5f003fdf2653
polished and added more material to the package chapter
Christian Urban <urbanc@in.tum.de>
parents:
117
diff
changeset
|
17 |
#> (if ! linenos then (enclose "\\begin{linenos}%\n" "%\n\\end{linenos}") else I) |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
18 |
#> (if ! gray then (enclose "\\begin{graybox}%\n" "%\n\\end{graybox}") else I) |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
19 |
#> enclose "\\begin{isabelle}%\n" "%\n\\end{isabelle}" |
171
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
20 |
else |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
21 |
map (Output.output o (if ! ThyOutput.break then Pretty.string_of else Pretty.str_of)) |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
22 |
#> space_implode "\\isasep\\isanewline%\n" |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
23 |
#> enclose "\\isa{" "}"); |
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
24 |
|
171
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
25 |
|
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
26 |
fun boolean "" = true |
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
27 |
| boolean "true" = true |
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
28 |
| boolean "false" = false |
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
29 |
| boolean s = error ("Bad boolean value: " ^ quote s); |
96
018bfa718982
(re)defined the document antiquotation @subgoal in order to be closer to what is actually printed
Christian Urban <urbanc@in.tum.de>
parents:
90
diff
changeset
|
30 |
|
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
31 |
val _ = ThyOutput.add_options |
117
796c6ea633b3
added an option for linenumbers to the chunk-antiquotation
Christian Urban <urbanc@in.tum.de>
parents:
96
diff
changeset
|
32 |
[("gray", Library.setmp gray o boolean), |
796c6ea633b3
added an option for linenumbers to the chunk-antiquotation
Christian Urban <urbanc@in.tum.de>
parents:
96
diff
changeset
|
33 |
("linenos", Library.setmp linenos o boolean)] |
90
b071a0b88298
made chunks aware of the gray-option
Christian Urban <urbanc@in.tum.de>
parents:
57
diff
changeset
|
34 |
|
96
018bfa718982
(re)defined the document antiquotation @subgoal in order to be closer to what is actually printed
Christian Urban <urbanc@in.tum.de>
parents:
90
diff
changeset
|
35 |
|
018bfa718982
(re)defined the document antiquotation @subgoal in order to be closer to what is actually printed
Christian Urban <urbanc@in.tum.de>
parents:
90
diff
changeset
|
36 |
|
018bfa718982
(re)defined the document antiquotation @subgoal in order to be closer to what is actually printed
Christian Urban <urbanc@in.tum.de>
parents:
90
diff
changeset
|
37 |
|
24 | 38 |
(** theory data **) |
39 |
||
40 |
structure ChunkData = TheoryDataFun |
|
41 |
( |
|
42 |
type T = (ML_Lex.token list * stamp) NameSpace.table |
|
43 |
val empty = NameSpace.empty_table; |
|
44 |
val copy = I; |
|
45 |
val extend = I; |
|
46 |
fun merge _ tables : T = NameSpace.merge_tables (eq_snd (op =)) tables handle Symtab.DUP dup => |
|
47 |
error ("Attempt to merge different versions of ML chunk " ^ quote dup); |
|
48 |
); |
|
49 |
||
50 |
fun declare_chunk name thy = |
|
55 | 51 |
(Sign.full_bname thy name, |
176
3da5f3f07d8b
updated to new read_specification
Christian Urban <urbanc@in.tum.de>
parents:
171
diff
changeset
|
52 |
ChunkData.map (snd o NameSpace.define (Sign.naming_of thy) |
55 | 53 |
(Binding.name name, ([], stamp ()))) thy |
24 | 54 |
handle Symtab.DUP _ => error ("Duplicate definition of ML chunk " ^ quote name)); |
55 |
||
56 |
fun augment_chunk tok name = |
|
57 |
ChunkData.map (apsnd (Symtab.map_entry name (apfst (cons tok)))); |
|
58 |
||
59 |
fun the_chunk thy name = |
|
60 |
let val (space, tab) = ChunkData.get thy |
|
61 |
in case Symtab.lookup tab (NameSpace.intern space name) of |
|
62 |
NONE => error ("Unknown ML chunk " ^ quote name) |
|
63 |
| SOME (toks, _) => rev toks |
|
64 |
end; |
|
65 |
||
66 |
||
67 |
(** parsers **) |
|
68 |
||
69 |
val not_eof = ML_Lex.stopper |> Scan.is_stopper #> not; |
|
70 |
||
71 |
val scan_space = Scan.many Symbol.is_blank; |
|
72 |
||
73 |
fun scan_cmt scan = |
|
74 |
Scan.one (ML_Lex.kind_of #> equal ML_Lex.Comment) >> |
|
75 |
(ML_Lex.content_of #> Symbol.explode #> Scan.finite Symbol.stopper scan #> fst); |
|
76 |
||
77 |
val scan_chunks = Scan.depend (fn (open_chunks, thy) => |
|
78 |
scan_cmt ((Scan.this_string "(*" -- scan_space -- Scan.this_string "@chunk" -- |
|
79 |
scan_space) |-- Symbol.scan_id --| |
|
80 |
(scan_space -- Scan.this_string "*)") >> (fn name => |
|
81 |
let val (name', thy') = declare_chunk name thy |
|
82 |
in ((name' :: open_chunks, thy'), "") end)) |
|
83 |
|| |
|
84 |
scan_cmt (Scan.this_string "(*" -- scan_space -- Scan.this_string "@end" -- |
|
85 |
scan_space -- Scan.this_string "*)" >> (fn _ => |
|
86 |
(case open_chunks of |
|
87 |
[] => error "end without matching chunk encountered" |
|
88 |
| _ :: open_chunks' => ((open_chunks', thy), "")))) |
|
89 |
|| |
|
90 |
Scan.one not_eof >> (fn tok => |
|
91 |
((open_chunks, fold (augment_chunk tok) open_chunks thy), ML_Lex.content_of tok))); |
|
92 |
||
93 |
fun chunks_of s thy = |
|
94 |
let val toks = Source.exhaust (ML_Lex.source (Source.of_string s)) |
|
95 |
in case Scan.finite' ML_Lex.stopper (Scan.repeat (Scan.error scan_chunks)) |
|
96 |
(([], thy), toks) of |
|
97 |
(toks', (([], thy'), _)) => (implode toks', thy') |
|
98 |
| (_, ((open_chunks, _), _)) => |
|
99 |
error ("Open chunks at end of text: " ^ commas_quote open_chunks) |
|
100 |
end; |
|
101 |
||
102 |
||
103 |
(** use command **) |
|
104 |
||
105 |
fun load_ml dir raw_path thy = |
|
106 |
(case ThyLoad.check_ml dir raw_path of |
|
107 |
NONE => error ("Could not find ML file " ^ quote (Path.implode raw_path)) |
|
108 |
| SOME (path, _) => |
|
109 |
let val (s, thy') = chunks_of (File.read path) thy |
|
110 |
in |
|
111 |
Context.theory_map (ThyInfo.exec_file false raw_path) thy' |
|
112 |
end); |
|
113 |
||
114 |
fun use_chunks path thy = |
|
115 |
load_ml (ThyInfo.master_directory (Context.theory_name thy)) path thy; |
|
116 |
||
117 |
val _ = |
|
118 |
OuterSyntax.command "use_chunks" "eval ML text from file" |
|
119 |
(OuterKeyword.tag_ml OuterKeyword.thy_decl) |
|
120 |
(OuterParse.path >> (Toplevel.theory o use_chunks)); |
|
121 |
||
122 |
||
123 |
(** antiquotation **) |
|
124 |
||
125 |
val str_of_source = space_implode " " o map OuterLex.unparse o #2 o #1 o Args.dest_src; |
|
126 |
||
127 |
val verbatim = space_implode "\\verb,|," o map (enclose "\\verb|" "|") o space_explode "|"; |
|
128 |
||
129 |
val transform_cmts = |
|
130 |
Scan.finite ML_Lex.stopper (Scan.repeat |
|
131 |
( scan_cmt |
|
132 |
(Scan.this_string "(*{" |-- |
|
133 |
Scan.repeat (Scan.unless (Scan.this_string "}*)") |
|
134 |
(Scan.one (not o Symbol.is_eof))) --| |
|
135 |
Scan.this_string "}*)" >> |
|
57
065f472c09ab
Repaired output of marginal comments in ML antiquotation.
berghofe
parents:
55
diff
changeset
|
136 |
(Symbol.encode_raw o enclose "\\hfill\\textrm{\\textit{" "}}" o implode)) |
24 | 137 |
|| Scan.one not_eof >> ML_Lex.content_of)) #> |
138 |
fst; |
|
139 |
||
165
890fbfef6d6b
partially adapted to new antiquotation infrastructure
Christian Urban <urbanc@in.tum.de>
parents:
118
diff
changeset
|
140 |
fun output_chunk {state: Toplevel.state, source = src, context = ctxt} name = |
24 | 141 |
let |
142 |
val toks = the_chunk (ProofContext.theory_of ctxt) name; |
|
143 |
val (spc, toks') = (case toks of |
|
144 |
[] => ("", []) |
|
145 |
| [tok] => ("", [tok]) |
|
146 |
| tok :: toks' => |
|
147 |
let |
|
148 |
val (toks'', tok') = split_last toks' |
|
149 |
val toks''' = |
|
150 |
if ML_Lex.kind_of tok' = ML_Lex.Space then toks'' |
|
151 |
else toks' |
|
152 |
in |
|
153 |
if ML_Lex.kind_of tok = ML_Lex.Space then |
|
154 |
(tok |> ML_Lex.content_of |> Symbol.explode |> |
|
155 |
take_suffix (equal " ") |> snd |> implode, |
|
156 |
toks''') |
|
157 |
else ("", tok :: toks''') |
|
158 |
end) |
|
159 |
val txt = spc ^ implode (transform_cmts toks') |
|
160 |
in |
|
57
065f472c09ab
Repaired output of marginal comments in ML antiquotation.
berghofe
parents:
55
diff
changeset
|
161 |
txt |> split_lines |> |
171
18f90044c777
simplified antiquotations
Christian Urban <urbanc@in.tum.de>
parents:
165
diff
changeset
|
162 |
(map Pretty.str) |> output |
24 | 163 |
end; |
164 |
||
165
890fbfef6d6b
partially adapted to new antiquotation infrastructure
Christian Urban <urbanc@in.tum.de>
parents:
118
diff
changeset
|
165 |
val _ = ThyOutput.antiquotation "ML_chunk" (Scan.lift Args.name) output_chunk; |
24 | 166 |
|
167 |
end; |