src/Pure/Thy/thy_output.ML
changeset 58999 ed09ae4ea2d8
parent 58992 584077922200
child 59064 a8bcb5a446c8
equal deleted inserted replaced
58998:6237574c705b 58999:ed09ae4ea2d8
    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;