-
Notifications
You must be signed in to change notification settings - Fork 0
/
Util.fs
46 lines (33 loc) · 1.23 KB
/
Util.fs
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
module Util
open FParsec
type Parser<'a> = Parser<'a, unit>
module private CodeBlockParsers =
let blockOpen =
pstring "```" .>> skipMany letter
let blockClose = pstring "```"
let doubleBacktick: Parser<string> =
pstring "``" .>>? notFollowedBy (pchar '`')
let singleBacktick: Parser<char> =
pchar '`' .>>? notFollowedBy (pchar '`')
let blockContents =
many1Chars (
satisfy ((<>) '`')
<|> (pchar '`' .>>? notFollowedBy (pstring "``"))
)
let inlineDoubleContents =
many1Chars (satisfy ((<>) '`') <|> singleBacktick)
let inlineSingleContents =
many1Strings (many1Chars (satisfy ((<>) '`')) <|> doubleBacktick)
let codeBlockParser =
choice [ between blockOpen blockClose blockContents
between doubleBacktick doubleBacktick inlineDoubleContents
between singleBacktick singleBacktick inlineSingleContents ]
open CodeBlockParsers
let parseCodeBlockFromMessage s =
let parser =
skipMany (satisfy ((<>) '`')) >>. codeBlockParser
.>> skipMany anyChar
.>> eof
match run parser s with
| Success (code, _, _) -> Core.Ok code
| Failure (e, _, _) -> Core.Error e