226 |
226 |
227 (* present spans *) |
227 (* present spans *) |
228 |
228 |
229 local |
229 local |
230 |
230 |
231 fun err_bad_nesting pos = |
231 fun err_bad_nesting here = |
232 error ("Bad nesting of commands in presentation" ^ pos); |
232 error ("Bad nesting of commands in presentation" ^ here); |
233 |
233 |
234 fun edge which f (x: string option, y) = |
234 fun edge which f (x: string option, y) = |
235 if x = y then I |
235 if x = y then I |
236 else (case which (x, y) of NONE => I | SOME txt => cons (Latex.string (f txt))); |
236 else (case which (x, y) of NONE => I | SOME txt => cons (Latex.string (f txt))); |
237 |
237 |
238 val begin_tag = edge #2 Latex.begin_tag; |
238 val begin_tag = edge #2 Latex.begin_tag; |
239 val end_tag = edge #1 Latex.end_tag; |
239 val end_tag = edge #1 Latex.end_tag; |
240 fun open_delim delim e = edge #2 Latex.begin_delim e #> delim #> edge #2 Latex.end_delim e; |
240 fun open_delim delim e = edge #2 Latex.begin_delim e #> delim #> edge #2 Latex.end_delim e; |
241 fun close_delim delim e = edge #1 Latex.begin_delim e #> delim #> edge #1 Latex.end_delim e; |
241 fun close_delim delim e = edge #1 Latex.begin_delim e #> delim #> edge #1 Latex.end_delim e; |
242 |
242 |
243 fun document_tag ctxt tag = |
243 fun document_tag cmd_pos state state' tag_stack = |
244 try hd (fold (update (op =)) (Document_Source.get_tags ctxt) (the_list tag)); |
244 let |
|
245 val ctxt' = Toplevel.presentation_context state'; |
|
246 val nesting = Toplevel.level state' - Toplevel.level state; |
|
247 |
|
248 val (tag, tags) = tag_stack; |
|
249 val tag' = try hd (fold (update (op =)) (Document_Source.get_tags ctxt') (the_list tag)); |
|
250 val tag_stack' = |
|
251 if nesting = 0 andalso not (Toplevel.is_proof state) then tag_stack |
|
252 else if nesting >= 0 then (tag', replicate nesting tag @ tags) |
|
253 else |
|
254 (case drop (~ nesting - 1) tags of |
|
255 tg :: tgs => (tg, tgs) |
|
256 | [] => err_bad_nesting (Position.here cmd_pos)); |
|
257 in (tag', tag_stack') end; |
245 |
258 |
246 fun read_tag s = |
259 fun read_tag s = |
247 (case space_explode "%" s of |
260 (case space_explode "%" s of |
248 ["", b] => (SOME b, NONE) |
261 ["", b] => (SOME b, NONE) |
249 | [a, b] => (NONE, SOME (a, b)) |
262 | [a, b] => (NONE, SOME (a, b)) |
285 #> cons (Latex.string flag) |
298 #> cons (Latex.string flag) |
286 | _ => I); |
299 | _ => I); |
287 |
300 |
288 val Span ((cmd_name, cmd_pos), srcs, span_newline) = span; |
301 val Span ((cmd_name, cmd_pos), srcs, span_newline) = span; |
289 |
302 |
290 val (tag, tags) = tag_stack; |
303 val (tag', tag_stack') = document_tag cmd_pos state state' tag_stack; |
291 val tag' = document_tag ctxt' tag; |
304 val active_tag' = if is_some tag' then tag' else command_tag cmd_name state state' active_tag; |
292 val active_tag' = |
|
293 if is_some tag' then tag' |
|
294 else command_tag cmd_name state state' active_tag; |
|
295 val edge = (active_tag, active_tag'); |
305 val edge = (active_tag, active_tag'); |
296 |
|
297 val nesting = Toplevel.level state' - Toplevel.level state; |
|
298 |
306 |
299 val newline' = |
307 val newline' = |
300 if is_none active_tag' then span_newline else newline; |
308 if is_none active_tag' then span_newline else newline; |
301 |
|
302 val tag_stack' = |
|
303 if nesting = 0 andalso not (Toplevel.is_proof state) then tag_stack |
|
304 else if nesting >= 0 then (tag', replicate nesting tag @ tags) |
|
305 else |
|
306 (case drop (~ nesting - 1) tags of |
|
307 tg :: tgs => (tg, tgs) |
|
308 | [] => err_bad_nesting (Position.here cmd_pos)); |
|
309 |
309 |
310 val latex' = |
310 val latex' = |
311 latex |
311 latex |
312 |> end_tag edge |
312 |> end_tag edge |
313 |> close_delim (fst present_cont) edge |
313 |> close_delim (fst present_cont) edge |