|
1 header {* Some examples with text cartouches *} |
|
2 |
|
3 theory Cartouche_Examples |
|
4 imports Main |
|
5 keywords "cartouche" :: diag |
|
6 begin |
|
7 |
|
8 subsection {* Outer syntax *} |
|
9 |
|
10 ML {* |
|
11 Outer_Syntax.improper_command @{command_spec "cartouche"} "" |
|
12 (Parse.cartouche >> (fn s => |
|
13 Toplevel.imperative (fn () => writeln s))) |
|
14 *} |
|
15 |
|
16 cartouche \<open>abc\<close> |
|
17 cartouche \<open>abc \<open>\<alpha>\<beta>\<gamma>\<close> xzy\<close> |
|
18 |
|
19 |
|
20 subsection {* Inner syntax *} |
|
21 |
|
22 syntax "_string_cartouche" :: "cartouche_position \<Rightarrow> string" ("STR _") |
|
23 |
|
24 parse_translation {* |
|
25 let |
|
26 val mk_nib = |
|
27 Syntax.const o Lexicon.mark_const o |
|
28 fst o Term.dest_Const o HOLogic.mk_nibble; |
|
29 |
|
30 fun mk_char (s, pos) = |
|
31 let |
|
32 val c = |
|
33 if Symbol.is_ascii s then ord s |
|
34 else if s = "" then 10 |
|
35 else error ("String literal contains illegal symbol: " ^ quote s ^ Position.here pos); |
|
36 in Syntax.const @{const_syntax Char} $ mk_nib (c div 16) $ mk_nib (c mod 16) end; |
|
37 |
|
38 fun mk_string [] = Const (@{const_syntax Nil}, @{typ string}) |
|
39 | mk_string (s :: ss) = |
|
40 Syntax.const @{const_syntax Cons} $ mk_char s $ mk_string ss; |
|
41 |
|
42 fun string_tr ctxt args = |
|
43 let fun err () = raise TERM ("string_tr", []) in |
|
44 (case args of |
|
45 [(c as Const (@{syntax_const "_constrain"}, _)) $ Free (s, _) $ p] => |
|
46 (case Term_Position.decode_position p of |
|
47 SOME (pos, _) => |
|
48 c $ mk_string (Symbol_Pos.cartouche_content (Symbol_Pos.explode (s, pos))) $ p |
|
49 | NONE => err ()) |
|
50 | _ => err ()) |
|
51 end; |
|
52 in |
|
53 [(@{syntax_const "_string_cartouche"}, string_tr)] |
|
54 end |
|
55 *} |
|
56 |
|
57 term "STR \<open>\<close>" |
|
58 term "STR \<open>abc\<close>" |
|
59 lemma "STR \<open>abc\<close> @ STR \<open>xyz\<close> = STR \<open>abcxyz\<close>" by simp |
|
60 |
|
61 end |