src/Pure/Thy/latex.ML
changeset 67194 1c0a6a957114
parent 67189 725897bbabef
child 67195 6be90977f882
equal deleted inserted replaced
67193:4ade0d387429 67194:1c0a6a957114
     4 LaTeX presentation elements -- based on outer lexical syntax.
     4 LaTeX presentation elements -- based on outer lexical syntax.
     5 *)
     5 *)
     6 
     6 
     7 signature LATEX =
     7 signature LATEX =
     8 sig
     8 sig
       
     9   type text
       
    10   val string: string -> text
       
    11   val text: string * Position.T -> text
       
    12   val block: text list -> text
       
    13   val enclose_body: string -> string -> text list -> text list
       
    14   val output_text: text list -> string
       
    15   val output_positions: Position.T -> text list -> string
     9   val output_name: string -> string
    16   val output_name: string -> string
    10   val output_ascii: string -> string
    17   val output_ascii: string -> string
    11   val latex_control: Symbol.symbol
    18   val latex_control: Symbol.symbol
    12   val is_latex_control: Symbol.symbol -> bool
    19   val is_latex_control: Symbol.symbol -> bool
    13   val embed_raw: string -> string
    20   val embed_raw: string -> string
    14   val output_known_symbols: (string -> bool) * (string -> bool) ->
    21   val output_known_symbols: (string -> bool) * (string -> bool) ->
    15     Symbol.symbol list -> string
    22     Symbol.symbol list -> string
    16   val output_symbols: Symbol.symbol list -> string
    23   val output_symbols: Symbol.symbol list -> string
    17   val output_syms: string -> string
    24   val output_syms: string -> string
    18   val line_output: Position.T -> string -> string
       
    19   val output_token: Token.T -> string
    25   val output_token: Token.T -> string
    20   val begin_delim: string -> string
    26   val begin_delim: string -> string
    21   val end_delim: string -> string
    27   val end_delim: string -> string
    22   val begin_tag: string -> string
    28   val begin_tag: string -> string
    23   val end_tag: string -> string
    29   val end_tag: string -> string
       
    30   val environment_block: string -> text list -> text
    24   val environment: string -> string -> string
    31   val environment: string -> string -> string
    25   val isabelle_theory: Position.T -> string -> string -> string
    32   val isabelle_body: string -> text list -> text list
    26   val symbol_source: (string -> bool) * (string -> bool) ->
    33   val symbol_source: (string -> bool) * (string -> bool) ->
    27     string -> Symbol.symbol list -> string
    34     string -> Symbol.symbol list -> string
    28   val theory_entry: string -> string
    35   val theory_entry: string -> string
    29   val latexN: string
    36   val latexN: string
    30 end;
    37 end;
    31 
    38 
    32 structure Latex: LATEX =
    39 structure Latex: LATEX =
    33 struct
    40 struct
       
    41 
       
    42 (* text with positions *)
       
    43 
       
    44 abstype text = Text of string * Position.T | Block of text list
       
    45 with
       
    46 
       
    47 fun string s = Text (s, Position.none);
       
    48 val text = Text;
       
    49 val block = Block;
       
    50 
       
    51 fun output_text texts =
       
    52   let
       
    53     fun output (Text (s, _)) = Buffer.add s
       
    54       | output (Block body) = fold output body;
       
    55   in Buffer.empty |> fold output texts |> Buffer.content end;
       
    56 
       
    57 fun output_positions file_pos texts =
       
    58   let
       
    59     fun position (a, b) = enclose "%:%" "%:%" (a ^ "=" ^ b);
       
    60     fun output (Text (s, pos)) (positions, line) =
       
    61           let
       
    62             val positions' =
       
    63               (case Position.line_of pos of
       
    64                 NONE => positions
       
    65               | SOME l => position (apply2 Value.print_int (line, l)) :: positions);
       
    66             val line' = fold_string (fn c => fn n => if c = "\n" then n + 1 else n) s line;
       
    67           in (positions', line') end
       
    68       | output (Block body) res = fold output body res;
       
    69   in
       
    70     (case Position.file_of file_pos of
       
    71       NONE => ""
       
    72     | SOME file =>
       
    73         ([position (Markup.fileN, file), "\\endinput"], 1)
       
    74         |> fold output texts |> #1 |> rev |> cat_lines)
       
    75   end;
       
    76 
       
    77 end;
       
    78 
       
    79 fun enclose_body bg en body = string bg :: body @ [string en];
       
    80 
    34 
    81 
    35 (* output name for LaTeX macros *)
    82 (* output name for LaTeX macros *)
    36 
    83 
    37 val output_name =
    84 val output_name =
    38   translate_string
    85   translate_string
   168           (output_symbols (map Symbol_Pos.symbol body)));
   215           (output_symbols (map Symbol_Pos.symbol body)));
   169 
   216 
   170 end;
   217 end;
   171 
   218 
   172 
   219 
   173 (* positions *)
       
   174 
       
   175 fun output_prop (a, b) = enclose "%:%" "%:%\n" (a ^ "=" ^ b);
       
   176 
       
   177 fun output_file pos =
       
   178   (case Position.file_of pos of
       
   179     NONE => ""
       
   180   | SOME file => output_prop (Markup.fileN, file));
       
   181 
       
   182 
       
   183 val is_blank_line = forall_string (fn s => s = " " orelse s = "\t");
       
   184 
       
   185 fun line_output pos output =
       
   186   (case Position.line_of pos of
       
   187     NONE => output
       
   188   | SOME n =>
       
   189       (case take_prefix is_blank_line (split_lines output) of
       
   190         (_, []) => output
       
   191       | (blank, rest) =>
       
   192           cat_lines blank ^ " %\n" ^
       
   193           output_prop (Markup.lineN, Value.print_int n) ^
       
   194           cat_lines rest));
       
   195 
       
   196 
       
   197 (* output token *)
   220 (* output token *)
   198 
   221 
   199 fun output_token tok =
   222 fun output_token tok =
   200   let
   223   let
   201     val s = Token.content_of tok;
   224     val s = Token.content_of tok;
   229 fun end_tag tg = enclose_name "%\n\\endisatag" "\n" tg ^ enclose "{\\isafold" "}%\n" tg;
   252 fun end_tag tg = enclose_name "%\n\\endisatag" "\n" tg ^ enclose "{\\isafold" "}%\n" tg;
   230 
   253 
   231 
   254 
   232 (* theory presentation *)
   255 (* theory presentation *)
   233 
   256 
   234 fun environment name =
   257 fun environment_delim name =
   235   enclose ("%\n\\begin{" ^ output_name name ^ "}%\n") ("%\n\\end{" ^ output_name name ^ "}");
   258  ("%\n\\begin{" ^ output_name name ^ "}%\n",
   236 
   259   "%\n\\end{" ^ output_name name ^ "}");
   237 fun isabelle_theory pos name txt =
   260 
   238   output_file pos ^
   261 fun environment_block name = environment_delim name |-> enclose_body #> block;
   239   "\\begin{isabellebody}%\n\
   262 fun environment name = environment_delim name |-> enclose;
   240   \\\setisabellecontext{" ^ output_syms name ^ "}%\n" ^ txt ^
   263 
   241   "%\n\\end{isabellebody}%\n";
   264 fun isabelle_body_delim name =
       
   265  ("%\n\\begin{isabellebody}%\n\\setisabellecontext{" ^ output_syms name ^ "}%\n",
       
   266   "%\n\\end{isabellebody}%\n");
       
   267 
       
   268 fun isabelle_body name = isabelle_body_delim name |-> enclose_body;
   242 
   269 
   243 fun symbol_source known name syms =
   270 fun symbol_source known name syms =
   244   isabelle_theory Position.none name
   271   isabelle_body_delim name
       
   272   |-> enclose
   245     ("\\isamarkupfile{" ^ output_known_symbols known (Symbol.explode name) ^ "}%\n" ^
   273     ("\\isamarkupfile{" ^ output_known_symbols known (Symbol.explode name) ^ "}%\n" ^
   246       output_known_symbols known syms);
   274       output_known_symbols known syms);
   247 
   275 
   248 fun theory_entry name = "\\input{" ^ name ^ ".tex}\n\n";
   276 fun theory_entry name = "\\input{" ^ name ^ ".tex}\n\n";
   249 
   277