31 val str_of_source: Token.src -> string |
31 val str_of_source: Token.src -> string |
32 val maybe_pretty_source: (Proof.context -> 'a -> Pretty.T) -> Proof.context -> |
32 val maybe_pretty_source: (Proof.context -> 'a -> Pretty.T) -> Proof.context -> |
33 Token.src -> 'a list -> Pretty.T list |
33 Token.src -> 'a list -> Pretty.T list |
34 val output: Proof.context -> Pretty.T list -> string |
34 val output: Proof.context -> Pretty.T list -> string |
35 val verbatim_text: Proof.context -> string -> string |
35 val verbatim_text: Proof.context -> string -> string |
36 val local_theory_markup: (xstring * Position.T) option * Symbol_Pos.source -> |
36 val old_header_command: Symbol_Pos.source -> Toplevel.transition -> Toplevel.transition |
37 Toplevel.transition -> Toplevel.transition |
37 val document_command: (xstring * Position.T) option * Symbol_Pos.source -> |
38 val proof_markup: Symbol_Pos.source -> Toplevel.transition -> Toplevel.transition |
|
39 val header_markup: Symbol_Pos.source -> Toplevel.transition -> Toplevel.transition |
|
40 val heading_markup: (xstring * Position.T) option * Symbol_Pos.source -> |
|
41 Toplevel.transition -> Toplevel.transition |
38 Toplevel.transition -> Toplevel.transition |
42 end; |
39 end; |
43 |
40 |
44 structure Thy_Output: THY_OUTPUT = |
41 structure Thy_Output: THY_OUTPUT = |
45 struct |
42 struct |
283 val Span ((cmd_name, cmd_pos, cmd_tags), srcs, span_newline) = span; |
280 val Span ((cmd_name, cmd_pos, cmd_tags), srcs, span_newline) = span; |
284 |
281 |
285 val (tag, tags) = tag_stack; |
282 val (tag, tags) = tag_stack; |
286 val tag' = try hd (fold (update (op =)) cmd_tags (the_list tag)); |
283 val tag' = try hd (fold (update (op =)) cmd_tags (the_list tag)); |
287 |
284 |
|
285 val nesting = Toplevel.level state' - Toplevel.level state; |
|
286 |
288 val active_tag' = |
287 val active_tag' = |
289 if is_some tag' then tag' |
288 if is_some tag' then tag' |
290 else if cmd_name = "end" andalso not (Toplevel.is_toplevel state') then NONE |
289 else if cmd_name = "end" andalso not (Toplevel.is_toplevel state') then NONE |
291 else try hd (Keyword.command_tags keywords cmd_name); |
290 else |
|
291 (case Keyword.command_tags keywords cmd_name of |
|
292 default_tag :: _ => SOME default_tag |
|
293 | [] => |
|
294 if Keyword.is_vacuous keywords cmd_name andalso Toplevel.is_proof state |
|
295 then active_tag |
|
296 else NONE); |
|
297 |
292 val edge = (active_tag, active_tag'); |
298 val edge = (active_tag, active_tag'); |
293 |
299 |
294 val newline' = |
300 val newline' = |
295 if is_none active_tag' then span_newline else newline; |
301 if is_none active_tag' then span_newline else newline; |
296 |
302 |
297 val nesting = Toplevel.level state' - Toplevel.level state; |
|
298 val tag_stack' = |
303 val tag_stack' = |
299 if nesting = 0 andalso not (Toplevel.is_proof state) then tag_stack |
304 if nesting = 0 andalso not (Toplevel.is_proof state) then tag_stack |
300 else if nesting >= 0 then (tag', replicate nesting tag @ tags) |
305 else if nesting >= 0 then (tag', replicate nesting tag @ tags) |
301 else |
306 else |
302 (case drop (~ nesting - 1) tags of |
307 (case drop (~ nesting - 1) tags of |
303 tgs :: tgss => (tgs, tgss) |
308 tg :: tgs => (tg, tgs) |
304 | [] => err_bad_nesting (Position.here cmd_pos)); |
309 | [] => err_bad_nesting (Position.here cmd_pos)); |
305 |
310 |
306 val buffer' = |
311 val buffer' = |
307 buffer |
312 buffer |
308 |> end_tag edge |
313 |> end_tag edge |
357 in |
362 in |
358 |
363 |
359 fun present_thy thy command_results toks = |
364 fun present_thy thy command_results toks = |
360 let |
365 let |
361 val keywords = Thy_Header.get_keywords thy; |
366 val keywords = Thy_Header.get_keywords thy; |
362 val is_markup = Outer_Syntax.is_markup thy; |
|
363 |
367 |
364 |
368 |
365 (* tokens *) |
369 (* tokens *) |
366 |
370 |
367 val ignored = Scan.state --| ignore |
371 val ignored = Scan.state --| ignore |
368 >> (fn d => (NONE, (NoToken, ("", d)))); |
372 >> (fn d => (NONE, (NoToken, ("", d)))); |
369 |
373 |
370 fun markup mark mk flag = Scan.peek (fn d => |
374 fun markup pred mk flag = Scan.peek (fn d => |
371 improper |-- |
375 improper |-- |
372 Parse.position (Scan.one (Token.is_command andf is_markup mark o Token.content_of)) -- |
376 Parse.position (Scan.one (fn tok => |
|
377 Token.is_command tok andalso pred keywords (Token.content_of tok))) -- |
373 Scan.repeat tag -- |
378 Scan.repeat tag -- |
374 Parse.!!!! ((improper -- locale -- improper) |-- Parse.document_source --| improper_end) |
379 Parse.!!!! ((improper -- locale -- improper) |-- Parse.document_source --| improper_end) |
375 >> (fn (((tok, pos'), tags), {text, range = (pos, _), ...}) => |
380 >> (fn (((tok, pos'), tags), {text, range = (pos, _), ...}) => |
376 let val name = Token.content_of tok |
381 let val name = Token.content_of tok |
377 in (SOME (name, pos', tags), (mk (name, (text, pos)), (flag, d))) end)); |
382 in (SOME (name, pos', tags), (mk (name, (text, pos)), (flag, d))) end)); |
390 val other = Scan.peek (fn d => |
395 val other = Scan.peek (fn d => |
391 Parse.not_eof >> (fn tok => (NONE, (BasicToken tok, ("", d))))); |
396 Parse.not_eof >> (fn tok => (NONE, (BasicToken tok, ("", d))))); |
392 |
397 |
393 val token = |
398 val token = |
394 ignored || |
399 ignored || |
395 markup Outer_Syntax.Markup MarkupToken Latex.markup_true || |
400 markup Keyword.is_document_heading MarkupToken Latex.markup_true || |
396 markup Outer_Syntax.Markup_Env MarkupEnvToken Latex.markup_true || |
401 markup Keyword.is_document_body MarkupEnvToken Latex.markup_true || |
397 markup Outer_Syntax.Verbatim (VerbatimToken o #2) "" || |
402 markup Keyword.is_document_raw (VerbatimToken o #2) "" || |
398 command || cmt || other; |
403 command || cmt || other; |
399 |
404 |
400 |
405 |
401 (* spans *) |
406 (* spans *) |
402 |
407 |
700 (Context_Position.reports ctxt [(pos, Markup.language_path), (pos, Markup.url name)]; |
705 (Context_Position.reports ctxt [(pos, Markup.language_path), (pos, Markup.url name)]; |
701 enclose "\\url{" "}" name))); |
706 enclose "\\url{" "}" name))); |
702 |
707 |
703 |
708 |
704 |
709 |
705 (** markup commands **) |
710 (** document commands **) |
706 |
711 |
707 fun local_theory_markup (loc, txt) = Toplevel.present_local_theory loc (check_text txt); |
712 fun old_header_command txt = |
708 val proof_markup = Toplevel.present_proof o check_text; |
|
709 |
|
710 fun reject_target NONE = () |
|
711 | reject_target (SOME (_, pos)) = |
|
712 error ("Illegal target specification -- not a theory context" ^ Position.here pos); |
|
713 |
|
714 fun header_markup txt = |
|
715 Toplevel.keep (fn state => |
713 Toplevel.keep (fn state => |
716 if Toplevel.is_toplevel state then |
714 if Toplevel.is_toplevel state then |
717 (legacy_feature "Obsolete 'header' command -- use 'chapter', 'section' etc. instead"; |
715 (legacy_feature "Obsolete 'header' command -- use 'chapter', 'section' etc. instead"; |
718 check_text txt state) |
716 check_text txt state) |
719 else raise Toplevel.UNDEF); |
717 else raise Toplevel.UNDEF); |
720 |
718 |
721 fun heading_markup (loc, txt) = |
719 fun document_command (loc, txt) = |
722 Toplevel.keep (fn state => |
720 Toplevel.keep (fn state => |
723 if Toplevel.is_toplevel state then (reject_target loc; check_text txt state) |
721 (case loc of |
724 else raise Toplevel.UNDEF) o |
722 NONE => check_text txt state |
725 local_theory_markup (loc, txt) o |
723 | SOME (_, pos) => |
726 Toplevel.present_proof (fn state => (reject_target loc; check_text txt state)); |
724 error ("Illegal target specification -- not a theory context" ^ Position.here pos))) o |
|
725 Toplevel.present_local_theory loc (check_text txt); |
727 |
726 |
728 end; |
727 end; |