File: texquote2.ml

package info (click to toggle)
camlidl 1.13-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,572 kB
  • sloc: ml: 5,236; ansic: 945; cpp: 908; makefile: 358; xml: 213; sh: 74
file content (137 lines) | stat: -rw-r--r-- 3,826 bytes parent folder | download | duplicates (6)
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
type environment =
  | Normal
  | Caml
  | Verbatim of string * string
  | Verbatim_like

let in_quotes = ref false

let is_alpha c =
  ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')

let is_prefix prefix str =
  let length_prefix = String.length prefix in
  let length_str = String.length str in
  if length_prefix > length_str
  then false
  else (String.sub str 0 length_prefix) = prefix

let escape = function
  | ' ' | '\n' -> "\\ "
  | '{' -> "{\\char123}"
  | '}' -> "{\\char125}"
  | '^' -> "{\\char94}"
  | '_' -> "{\\char95}"
  | '\\' -> "{\\char92}"
  | '~' -> "{\\char126}"
  | '$' -> "\\$"
  | '&' -> "{\\char38}"
  | '#' -> "\\#"
  | '%' -> "\\%"
  | '\'' -> "{\\textquotesingle}"
  | '`' -> "{\\textasciigrave}"
  | _ -> ""

let process_normal_line line =
  let (verb_mark : char option ref) = ref None in
  let l = String.length line in
  let i = ref 0 in
  while !i<l do
    match !verb_mark with
    | None ->
      (match line.[!i] with
      | '"' ->
        let r = if !in_quotes then "}}" else "{\\machine{" in
        print_string r;
        in_quotes := not !in_quotes;
        incr i;
      | '\\' ->
        if !in_quotes
        then begin
          if (!i < l-1) && (line.[!i+1] = '"' || line.[!i+1] = '\\')
          then incr i;
          let t = escape line.[!i] in
          if t<>"" then print_string t else print_char line.[!i];
          incr i;
        end else if is_prefix "\\verb" (String.sub line !i (l - !i))
                    && not (is_alpha line.[!i+5])
        then begin
          i := !i+5;
          verb_mark := Some line.[!i];
          print_string "\\verb";
          print_char line.[!i];
          incr i;
        end else (print_char '\\'; incr i)
      | _ ->
        if !in_quotes && (escape line.[!i] <> "")
        then print_string (escape line.[!i])
        else print_char line.[!i];
        incr i;
      )
    | Some mark ->
      if line.[!i] = mark
      then verb_mark := None
      else if line.[!i] = '\'' || line.[!i] = '`'
      then Printf.eprintf "Warning: %c found in \\verb\n" line.[!i];
      print_char line.[!i];
      incr i;
  done

let process_line line = function
  | Normal ->
    if is_prefix "\\begin{caml_" line || is_prefix "\\begin{rawhtml}" line
    then (print_string line; Verbatim_like)
    else if is_prefix "\\begin{camlexample}" line
    then (print_endline line; Caml)
    else if is_prefix "\\begin{verbatim}" line
    then begin
      print_string "\\begin{machineenv}";
      (Verbatim ("\\end{verbatim}", "\\end{machineenv}"))
    end else if is_prefix "\\begin{ocamldoccode}" line
    then begin
      print_string "\\begin{ocamldoccode}";
      (Verbatim ("\\end{ocamldoccode}", "\\end{ocamldoccode}"))
    end else begin
      process_normal_line line;
      if !in_quotes
      then print_string (escape '\n')
      else print_newline();
      Normal
    end
  | Caml ->
    print_endline line;
    if is_prefix "\\end{camlexample}" line then Normal else Caml
  | Verbatim (verbatim_end_in, verbatim_end_out) as env ->
    if is_prefix verbatim_end_in line
    then begin
      print_string verbatim_end_out;
      Normal
    end else begin
      for i=0 to (String.length line) - 1 do
        let c = line.[i] in
        let t = escape c in
        if c=' ' || c='\n' || t=""
        then print_char c
        else print_string t
      done;
      print_newline();
      env
    end
  | Verbatim_like ->
    print_endline line;
    if is_prefix "\\end{caml_" line || is_prefix "\\end{rawhtml}" line
    then Normal
    else Verbatim_like

let rec process_input env = match input_line stdin with
  | exception End_of_file -> ()
  | line ->
    let env = process_line line env in
    process_input env

let main() =
  print_endline "% THIS FILE IS GENERATED.";
  print_newline();
  process_input Normal

let _ = main()