-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.ml
171 lines (167 loc) · 6.54 KB
/
main.ml
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
open Type
exception DoNotUnderstandException of string
exception MathInMathException
exception LatexException
exception BufferException
exception SuccessBreak
let main () =
let lexbuf = Lexing.from_channel stdin in
let e = Parser.parser_main Lexer.lexing_token lexbuf in
(*
let rec stringify : latex list -> string =
let rec aux ll = match ll with
| LDesc s -> (
match s with
| "<" -> "<" | ">" -> ">"
| _ -> s
)
| LCommand (cmd, argument) -> cmd
| LMath _ -> raise LatexException
in
fun e -> String.concat "" (List.map aux e)
in
*)
let rec to_string_math : latex list -> string =
let rec aux : latex list -> string list = fun e -> match e with
| [] -> []
| hd::tl ->
let res = ref [] in
try (
let u = (
match hd with
| LDesc s ->
let flag = Char.code (String.get s 0) in
if 48 <= flag && flag < 58 then s
else if flag == 32 then ""
else if s = "," then ", "
else if s = "=" then " = "
else if s = "<" then " < "
else if s = ">" then " > "
else if s = "\\pi" then "π"
else if s = "_" || s = "^" then (
let tag_name = if s = "_" then "sub" else "sup" in
match tl with
| [] -> raise LatexException
| hd2::tl2 ->
let _ : unit = res := (
"<" ^ tag_name ^ ">" ^ (
match hd2 with
| LMath u -> to_string_math u
| _ -> List.nth (aux [hd2]) 0
) ^ "</" ^ tag_name ^ ">"
)::(aux tl2) in
raise SuccessBreak
) else if (65 <= flag && flag < 91) || (97 <= flag && flag < 123) then (
"<span style=\"font-style: italic;\">" ^ s ^ "</span>"
) else s
| LCommand (cmd, argument) -> (
match cmd with
| "leq" | "le" -> " ≤ "
| "geq" | "ge" -> " ≥ "
| "neq" -> " ≠ "
| "," -> ","
| "cdots" -> "…"
| "cdot" -> "·"
| "times" -> " × "
| "blacksquare" -> "■"
| "texttt" -> "<code>" ^ (List.nth argument 0) ^ "</code>"
| "sign" -> (
match argument with
| [hd2] ->
let cnv2 = to_string_math [LDesc hd2] in
let cnv3 = to_string_math [LDesc hd2] in
"<span style=\"display: inline-block; position: relative; vertical-align: middle; letter-spacing: 0.001em; text-align: center;\">" ^
"<span style=\"display: block; padding: 0.1em;\">|" ^ cnv2 ^ "|</span>" ^
"<span style=\"display: none; padding: 0.1em;\">/</span>" ^
"<span style=\"display: block; padding: 0.1em; border-top: thin solid black;\">" ^ cnv3 ^ "</span>" ^
"</span>"
| _ -> raise LatexException
)
| "frac" -> (
match argument with
| hd2::(hd3::[]) ->
let cnv2 = to_string_math [LDesc hd2] in
let cnv3 = to_string_math [LDesc hd3] in
"<span style=\"display: inline-block; position: relative; vertical-align: middle; letter-spacing: 0.001em; text-align: center;\">" ^
"<span style=\"display: block; padding: 0.1em;\">" ^ cnv2 ^ "</span>" ^
"<span style=\"display: none; padding: 0.1em;\">/</span>" ^
"<span style=\"display: block; padding: 0.1em; border-top: thin solid black;\">" ^ cnv3 ^ "</span>" ^
"</span>"
| _ -> raise LatexException
)
| "pi" -> "π"
| _ -> raise (DoNotUnderstandException cmd)
)
| LMath _ -> raise MathInMathException
) in
let tl' = aux tl in
if u = "" then tl' else u::tl'
) with SuccessBreak -> !res
in
fun e -> String.concat "" (aux e)
in
let rec to_string : latex -> string = fun e ->
match e with
| LDesc s ->
if (String.get s 0) == '\n' then (
if (String.length s) = 1 then " "
else "</p>\n<p>"
) else s
| LMath m -> to_string_math m
| LCommand (cmd, argument) -> (
match cmd with
| "begin" -> (
match argument with
| [] -> raise LatexException
| hd::tl -> match hd with
| "example" -> "예제는 다른 곳에서 입력합니다."
| "itemize" -> "<ul>\n<li>"
| "problem" ->
let title = List.nth tl 0 in
"<h1>" ^ title ^ "</h1>\n<p>"
| "quote" -> "<blockquote>"
| _ -> raise (DoNotUnderstandException hd)
)
| "end" -> (
match argument with
| [] -> raise LatexException
| hd::tl -> match hd with
| "example" -> ""
| "itemize" -> "</li>\n</ul>"
| "problem" -> ""
| "quote" -> "</blockquote>"
| _ -> raise (DoNotUnderstandException hd)
)
| "ldots" -> "…"
| "exmpfile" -> ""
| "item" -> "</li>\n<li>"
| "textbf" ->
let u = List.nth argument 0 in
"<strong>" ^ u ^ "</strong>"
| "pagebreak" -> ""
| "textit" ->
let u = List.nth argument 0 in
"<span style=\"font-style: italic;\">" ^ u ^ "</span>"
| "texttt" ->
let u = List.nth argument 0 in
"<code>" ^ u ^ "</code>"
(* Problem Grammar *)
| "InputFile" -> "</p>\n<h3>입력 형식</h3>\n<p>"
| "OutputFile" -> "</p>\n<h3>출력 형식</h3>\n<p>"
| "Examples" -> "</p>\n<h3>예제</h3>\n<p>"
| "Note" | "Notes" -> "</p>\n<h3>노트</h3>\n<p>"
| _ -> raise (DoNotUnderstandException cmd)
)
| LComment _ -> ""
in
let s = (String.concat "" (List.map to_string e)) ^ "</p>" in
let postprocess : string -> string = fun s ->
let no_sp = Str.global_replace (Str.regexp " ") " " s in
let no_bli = Str.global_replace (Str.regexp "\n?<li> *</li>") "" no_sp in
let no_bp = Str.global_replace (Str.regexp "\n?<p> *</p>") "" no_bli in
let quote = Str.global_replace (Str.regexp "``") "\"" no_bp in
let no_absp = Str.global_replace (Str.regexp " *\\(<p>\\|</p>\\|<li>\\|</li>\\) *") "\\1" quote in
let nosp_btwn0 = Str.global_replace (Str.regexp "0, +0") "0,0" no_absp in
nosp_btwn0
in print_endline (postprocess s)
let _ : unit = main ()