1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
(** *)
module XR = Xtmpl.Rewrite
let external_highlight ~opts code =
let code_file = Filename.temp_file "stog" "code" in
Stog_base.Misc.file_of_string ~file: code_file code;
let temp_file = Filename.temp_file "stog" "highlight" in
let com = Printf.sprintf
"highlight -O xhtml %s -f %s > %s"
opts (Filename.quote code_file)(Filename.quote temp_file)
in
match Sys.command com with
0 ->
let code = Stog_base.Misc.string_of_file temp_file in
Sys.remove code_file;
Sys.remove temp_file;
let code = Stog_base.Misc.strip_string code in
XR.from_string code
| _ ->
failwith (Printf.sprintf "command failed: %s" com)
;;
let higlo_classes =
let keyword = function
0 -> "hl kwa"
| 1 -> "hl kwb"
| 2 -> "hl kwc"
| 3 -> "hl kwd"
| n -> "hl kw"^(string_of_int n)
in
let symbol _ = "sym" in
let title n = Printf.sprintf "h%d" n in
{
Higlo.Printers.id = "" ;
keyword ;
lcomment = "hl slc" ;
bcomment = "hl com" ;
string = "hl str" ;
text = "hl std" ;
numeric = "hl num" ;
directive = "hl dir" ;
escape = "hl esc" ;
symbol ;
constant = "hl num" ;
title ;
}
;;
let unknown_lang_warned = ref Types.Str_set.empty
let highlight ?lang ?opts code =
match lang, opts with
None, Some opts
| Some "", Some opts -> external_highlight ~opts code
| None, None
| Some "", None -> [XR.cdata code]
| Some lang, Some opts ->
let opts = opts^" --syntax="^lang in
external_highlight ~opts code
| Some "txt", None ->
let len = String.length code in
[ Higlo.Printers.token_to_xml_rewrite ~classes: higlo_classes (Higlo.Lang.Text (code, len)) ]
| Some lang, None ->
try
let _lexer = Higlo.Lang.get_lexer lang in
Higlo.Printers.to_xml_rewrite ~classes: higlo_classes ~lang code
with
Higlo.Lang.(Error (Unknown_lang s)) ->
if not (Types.Str_set.mem s !unknown_lang_warned) then
( unknown_lang_warned := Types.Str_set.add s !unknown_lang_warned ;
Log.warn
(fun m -> m "Higlo: unknown language %s. Falling back to external highlight" lang)
);
let opts = " --syntax="^lang in
external_highlight ~opts code
;;