src/Pure/Tools/rail.ML
changeset 62748 aa0084adce1f
parent 61476 1884c40f1539
child 62797 e08c44eed27f
equal deleted inserted replaced
62738:fe827c6fa8c5 62748:aa0084adce1f
     3     Author:     Makarius
     3     Author:     Makarius
     4 
     4 
     5 Railroad diagrams in LaTeX.
     5 Railroad diagrams in LaTeX.
     6 *)
     6 *)
     7 
     7 
     8 structure Rail: sig end =
     8 signature RAIL =
       
     9 sig
       
    10   datatype rails =
       
    11     Cat of int * rail list
       
    12   and rail =
       
    13     Bar of rails list |
       
    14     Plus of rails * rails |
       
    15     Newline of int |
       
    16     Nonterminal of string |
       
    17     Terminal of bool * string |
       
    18     Antiquote of bool * Antiquote.antiq
       
    19   val read: Proof.context -> Input.source -> (string Antiquote.antiquote * rail) list
       
    20   val output_rules: Toplevel.state -> (string Antiquote.antiquote * rail) list -> string
       
    21 end;
       
    22 
       
    23 structure Rail: RAIL =
     9 struct
    24 struct
    10 
    25 
    11 (** lexical syntax **)
    26 (** lexical syntax **)
    12 
    27 
    13 (* singleton keywords *)
    28 (* singleton keywords *)
   311       let val ([cat1', cat2'], y') = fold_map vertical_range_cat [cat1, cat2] y;
   326       let val ([cat1', cat2'], y') = fold_map vertical_range_cat [cat1, cat2] y;
   312       in (Plus (cat1', cat2'), Int.max (y + 1, y')) end
   327       in (Plus (cat1', cat2'), Int.max (y + 1, y')) end
   313   | vertical_range (Newline _) y = (Newline (y + 2), y + 3)
   328   | vertical_range (Newline _) y = (Newline (y + 2), y + 3)
   314   | vertical_range atom y = (atom, y + 1);
   329   | vertical_range atom y = (atom, y + 1);
   315 
   330 
       
   331 in
       
   332 
   316 fun output_rules state rules =
   333 fun output_rules state rules =
   317   let
   334   let
   318     val output_antiq = Thy_Output.eval_antiquote state o Antiquote.Antiq;
   335     val output_antiq = Thy_Output.eval_antiquote state o Antiquote.Antiq;
   319     fun output_text b s =
   336     fun output_text b s =
   320       Output.output s
   337       Output.output s
   354         output "" rail' ^
   371         output "" rail' ^
   355         "\\rail@end\n"
   372         "\\rail@end\n"
   356       end;
   373       end;
   357   in Latex.environment "railoutput" (implode (map output_rule rules)) end;
   374   in Latex.environment "railoutput" (implode (map output_rule rules)) end;
   358 
   375 
   359 in
       
   360 
       
   361 val _ = Theory.setup
   376 val _ = Theory.setup
   362   (Thy_Output.antiquotation @{binding rail} (Scan.lift Args.text_input)
   377   (Thy_Output.antiquotation @{binding rail} (Scan.lift Args.text_input)
   363     (fn {state, context, ...} => output_rules state o read context));
   378     (fn {state, context, ...} => output_rules state o read context));
   364 
   379 
   365 end;
   380 end;
   366 
   381 
   367 end;
   382 end;
   368