ligo/src/test/md.mll

63 lines
1.4 KiB
OCaml
Raw Normal View History

2019-12-23 18:18:32 +04:00
{
(* initial version taken from https://github.com/realworldocaml/mdx *)
type arg =
| Field of string
| NameValue of string * string
type block = {
line : int;
file : string;
arguments: arg list;
header : string option;
contents: string list;
}
exception Err of string
let line_ref = ref 1
let newline lexbuf =
Lexing.new_line lexbuf;
incr line_ref
}
let eol = '\n' | eof
let ws = ' ' | '\t'
rule text = parse
| eof { [] }
| "```" ([^' ' '\n']* as h) ws* ([^'\n']* as l) eol
{
let header = if h = "" then None else Some h in
let contents = block lexbuf in
let arguments = String.split_on_char ' ' l in
let arguments = List.map (fun a ->
if (String.contains a '=') then
( let a = String.split_on_char '=' a in
NameValue (List.nth a 0, List.nth a 1))
else
Field a
) arguments in
let file = lexbuf.Lexing.lex_start_p.Lexing.pos_fname in
newline lexbuf;
let line = !line_ref in
List.iter (fun _ -> newline lexbuf) contents;
newline lexbuf;
{ file; line; header; arguments; contents; }
:: text lexbuf }
| [^'\n']* eol
{ newline lexbuf;
text lexbuf }
and block = parse
| eof | "```" ws* eol { [] }
| ([^'\n'] * as str) eol { str :: block lexbuf }
{
let token lexbuf =
try
text lexbuf
with Failure _ ->
raise (Err "incomplete code block")
}