src/Pure/Thy/latex.ML
author wenzelm
Sat Jun 12 22:45:46 2004 +0200 (2004-06-12)
changeset 14924 2be4cbe27a27
parent 14879 8989eedf72a1
child 14973 0613f64653b7
permissions -rw-r--r--
added output_known_symbols; tuned;
     1 (*  Title:      Pure/Thy/latex.ML
     2     ID:         $Id$
     3     Author:     Markus Wenzel, TU Muenchen
     4     License:    GPL (GNU GENERAL PUBLIC LICENSE)
     5 
     6 LaTeX presentation primitives (based on outer lexical syntax).
     7 *)
     8 
     9 signature LATEX =
    10 sig
    11   val output_known_symbols: (string -> bool) * (string -> bool) ->
    12     Symbol.symbol list -> string
    13   val output_symbols: Symbol.symbol list -> string
    14   datatype token = Basic of OuterLex.token | Markup of string | MarkupEnv of string | Verbatim
    15   val output_tokens: (token * string) list -> string
    16   val flag_markup: bool -> string
    17   val tex_trailer: string
    18   val isabelle_file: string -> string -> string
    19   val symbol_source: (string -> bool) * (string -> bool) ->
    20     string -> Symbol.symbol list -> string
    21   val theory_entry: string -> string
    22   val modes: string list
    23 end;
    24 
    25 structure Latex: LATEX =
    26 struct
    27 
    28 
    29 (* symbol output *)
    30 
    31 local
    32 
    33 val output_chr = fn
    34   " " => "\\ " |
    35   "\n" => "\\isanewline\n" |
    36   "!" => "{\\isacharbang}" |
    37   "\"" => "{\\isachardoublequote}" |
    38   "#" => "{\\isacharhash}" |
    39   "$" => "{\\isachardollar}" |
    40   "%" => "{\\isacharpercent}" |
    41   "&" => "{\\isacharampersand}" |
    42   "'" => "{\\isacharprime}" |
    43   "(" => "{\\isacharparenleft}" |
    44   ")" => "{\\isacharparenright}" |
    45   "*" => "{\\isacharasterisk}" |
    46   "+" => "{\\isacharplus}" |
    47   "," => "{\\isacharcomma}" |
    48   "-" => "{\\isacharminus}" |
    49   "." => "{\\isachardot}" |
    50   "/" => "{\\isacharslash}" |
    51   ":" => "{\\isacharcolon}" |
    52   ";" => "{\\isacharsemicolon}" |
    53   "<" => "{\\isacharless}" |
    54   "=" => "{\\isacharequal}" |
    55   ">" => "{\\isachargreater}" |
    56   "?" => "{\\isacharquery}" |
    57   "@" => "{\\isacharat}" |
    58   "[" => "{\\isacharbrackleft}" |
    59   "\\" => "{\\isacharbackslash}" |
    60   "]" => "{\\isacharbrackright}" |
    61   "^" => "{\\isacharcircum}" |
    62   "_" => "{\\isacharunderscore}" |
    63   "`" => "{\\isacharbackquote}" |
    64   "{" => "{\\isacharbraceleft}" |
    65   "|" => "{\\isacharbar}" |
    66   "}" => "{\\isacharbraceright}" |
    67   "~" => "{\\isachartilde}" |
    68   c => if Symbol.is_digit c then enclose "{\\isadigit{" "}}" c else c;
    69 
    70 val output_chrs = translate_string output_chr;
    71 
    72 fun output_known_sym (known_sym, known_ctrl) sym =
    73   (case Symbol.decode sym of
    74     Symbol.Char s => output_chr s
    75   | Symbol.Sym s => if known_sym s then enclose "{\\isasym" "}" s else output_chrs sym
    76   | Symbol.Ctrl s => if known_ctrl s then enclose "\\isactrl" " " s else output_chrs sym
    77   | Symbol.Raw s => s);
    78 
    79 in
    80 
    81 val output_known_symbols = implode oo (map o output_known_sym);
    82 val output_symbols = output_known_symbols (K true, K true);
    83 val output_syms = output_symbols o Symbol.explode;
    84 
    85 end;
    86 
    87 
    88 (* token output *)
    89 
    90 structure T = OuterLex;
    91 
    92 datatype token =
    93   Basic of T.token |
    94   Markup of string |
    95   MarkupEnv of string |
    96   Verbatim;
    97 
    98 
    99 val invisible_token = T.keyword_with (equal ";") orf T.is_kind T.Comment;
   100 
   101 fun output_tok (Basic tok, _) =
   102       let val s = T.val_of tok in
   103         if invisible_token tok then ""
   104         else if T.is_kind T.Command tok then
   105           "\\isacommand{" ^ output_syms s ^ "}"
   106         else if T.is_kind T.Keyword tok andalso Syntax.is_ascii_identifier s then
   107           "\\isakeyword{" ^ output_syms s ^ "}"
   108         else if T.is_kind T.String tok then output_syms (Library.quote s)
   109         else if T.is_kind T.Verbatim tok then output_syms (enclose "{*" "*}" s)
   110         else output_syms s
   111       end
   112   | output_tok (Markup cmd, txt) =
   113       "%\n\\isamarkup" ^ cmd ^ "{" ^ Symbol.strip_blanks txt ^ "%\n}\n"
   114   | output_tok (MarkupEnv cmd, txt) = "%\n\\begin{isamarkup" ^ cmd ^ "}%\n" ^
   115       Symbol.strip_blanks txt ^ "%\n\\end{isamarkup" ^ cmd ^ "}%\n"
   116   | output_tok (Verbatim, txt) = "%\n" ^ Symbol.strip_blanks txt ^ "\n";
   117 
   118 
   119 val output_tokens = implode o map output_tok;
   120 
   121 
   122 fun flag_markup true = "\\isamarkuptrue%\n"
   123   | flag_markup false = "\\isamarkupfalse%\n";
   124 
   125 
   126 (* theory presentation *)
   127 
   128 val tex_trailer =
   129   "%%% Local Variables:\n\
   130   \%%% mode: latex\n\
   131   \%%% TeX-master: \"root\"\n\
   132   \%%% End:\n";
   133 
   134 fun isabelle_file name txt =
   135   "%\n\\begin{isabellebody}%\n\
   136   \\\def\\isabellecontext{" ^ output_syms name ^ "}%\n" ^ txt ^
   137   "\\end{isabellebody}%\n" ^ tex_trailer;
   138 
   139 fun symbol_source known name syms = isabelle_file name
   140   ("\\isamarkupheader{" ^ output_known_symbols known (Symbol.explode name) ^ "}%\n" ^
   141     output_known_symbols known syms);
   142 
   143 fun theory_entry name = "\\input{" ^ name ^ ".tex}\n\n";
   144 
   145 
   146 (* print mode *)
   147 
   148 val latexN = "latex";
   149 val modes = [latexN, Symbol.xsymbolsN, Symbol.symbolsN];
   150 
   151 fun latex_output str =
   152   let val syms = Symbol.explode str
   153   in (output_symbols syms, real (Symbol.length syms)) end;
   154 
   155 fun latex_indent "" = ""
   156   | latex_indent s = enclose "\\isaindent{" "}" s;
   157 
   158 val _ = Output.add_mode latexN (latex_output, latex_indent o #1, Symbol.default_raw);
   159 
   160 
   161 end;