@@ -11,6 +11,9 @@ open System
11
11
12
12
13
13
module Markups =
14
+ let Success = Decode.Success
15
+ let Invalid = Decode.Fail.invalidValue
16
+
14
17
type link = { linkType: string ; url: string }
15
18
type markup =
16
19
| Link of link
@@ -20,14 +23,18 @@ module Markups =
20
23
with
21
24
static member OfJson json =
22
25
match json with
23
- | JArray o ->
24
- match List.ofSeq o with
25
- | ( JString " a" ) :: ( JString lType) :: ( JString url) :: [] -> Decode.Success ( Link { linkType = lType; url = url })
26
- | ( JString " code" ) :: [] -> Decode.Success Code
27
- | ( JString " em" ) :: [] -> Decode.Success Emphasis
28
- | ( JString " strong" ) :: [] -> Decode.Success Strong
29
- | _ -> Decode.Fail.invalidValue json " failed to parse into markup"
30
- | _ -> Decode.Fail.arrExpected json
26
+ | JArray arr ->
27
+ match List.ofSeq arr with
28
+ | [( JString " code" )] -> Success Code
29
+ | [( JString " em" )] -> Success Emphasis
30
+ | [( JString " strong" )] -> Success Strong
31
+ | [( JString " a" ); ( JArray o)] ->
32
+ match List.ofSeq o with
33
+ | [( JString lType); ( JString url)] -> Success <| Link { linkType = lType; url = url }
34
+ | _ -> Invalid json " failed to parse into reference markup"
35
+ | _ -> Invalid json " failed to parse into markup"
36
+ | o -> Decode.Fail.arrExpected o
37
+
31
38
32
39
module Cards =
33
40
// Callout cards can be directly translated into CMS paragraph blocks
@@ -72,50 +79,58 @@ module Cards =
72
79
match json with
73
80
| JArray o ->
74
81
match List.ofSeq o with
75
- | ( JString " callout" ) :: ( cardObject: Encoding) :: [ ] -> Callout <!> ( callout.OfJson cardObject)
76
- | ( JString " toggle" ) :: ( cardObject: Encoding) :: [ ] -> Toggle <!> ( toggle.OfJson cardObject)
77
- | ( JString " code" ) :: ( cardObject: Encoding) :: [ ] -> Code <!> ( code.OfJson cardObject)
82
+ | [ JString " callout" ; cardObject: Encoding] -> Callout <!> ( callout.OfJson cardObject)
83
+ | [ JString " toggle" ; cardObject: Encoding] -> Toggle <!> ( toggle.OfJson cardObject)
84
+ | [ JString " code" ; cardObject: Encoding] -> Code <!> ( code.OfJson cardObject)
78
85
| _ -> Decode.Fail.invalidValue json " failed to parse into card"
79
86
| _ -> Decode.Fail.arrExpected json
80
87
81
88
82
89
module Sections =
83
90
type sectionTag =
84
- | Paragraph
85
- | Heading
86
- | Card
91
+ | Paragraph
92
+ | Heading
93
+ | Card
87
94
88
95
// Specialised parsers since this library doesn't seem to give us any :(((((((
89
96
// Might stack overflow on large lists but I dont see us ever having to deal with that, if stack overflows are an issue just optimise to be tail call recursive
90
97
let rec parseListInner ( parser : Encoding -> Result < 'a , DecodeError >) arr : Result < 'a list , DecodeError > =
91
98
match arr with
99
+ | [] -> Ok []
92
100
| x :: xs -> match parseListInner parser xs with
93
101
| Ok arr -> ( fun parsedValue -> parsedValue :: arr) <!> ( parser x)
94
102
| Error x -> Error x
95
- | [] -> Ok []
96
103
97
104
let parseList parser arr = parseListInner parser ( List.ofSeq arr)
98
105
let parseNumberList = parseList ( function | JNumber x -> Ok ( Decimal.ToInt32 x) | x -> Decode.Fail.numExpected x)
99
106
100
107
// Individual styling rules for a section
108
+ type sectionType =
109
+ | AtomIndex of int
110
+ | StringValue of string
111
+
101
112
type sectionBlock = {
102
113
openMarkups: int list ;
103
114
numClosedMarkups: int ;
104
- value: string ;
115
+ value: sectionType ;
105
116
} with
117
+ static member createSectionBlock = fun openMarkups numClosedMarkups value -> { openMarkups = openMarkups; numClosedMarkups = numClosedMarkups; value = value }
106
118
static member OfJson json =
107
119
match json with
108
120
| JArray o -> match List.ofSeq o with
109
- | ( JNumber 0 m) :: ( JArray openMarkups) :: ( JNumber numClosedMarkups) :: ( JString text) :: [] ->
110
- ( fun openMarkups numClosedMarkups text -> { openMarkups = openMarkups; numClosedMarkups = numClosedMarkups; value = text })
111
- <!> ( parseNumberList openMarkups)
112
- <*> ( Ok ( Decimal.ToInt32 numClosedMarkups))
113
- <*> ( Ok text)
121
+ | [ JNumber sectionType; JArray openMarkups; JNumber numClosedMarkups; value] ->
122
+ let block = sectionBlock.createSectionBlock <!> ( parseNumberList openMarkups) <*> ( Ok ( Decimal.ToInt32 numClosedMarkups))
123
+ match ( sectionType, value) with
124
+ | ( 0 m, JString text) -> block <*> ( Ok <| StringValue text)
125
+ | ( 1 m, JNumber atomIndex) -> block <*> ( Ok <| AtomIndex ( Decimal.ToInt32 atomIndex))
126
+ | _ -> Decode.Fail.invalidValue json " failed to parse section type"
127
+
114
128
| _ -> Decode.Fail.invalidValue json " failed to parse into section block"
115
129
116
130
| json -> Decode.Fail.arrExpected json
117
131
118
- let parseSectionBlockList = parseList sectionBlock.OfJson
132
+ let parseSectionBlockList = parseList sectionBlock.OfJson
133
+ let parseSectionBlockListInner = parseListInner sectionBlock.OfJson
119
134
120
135
type blockValue =
121
136
| Section of list < sectionBlock >
@@ -126,15 +141,35 @@ module Sections =
126
141
tag: sectionTag ;
127
142
blocks: blockValue ;
128
143
} with
144
+ static member createSection = fun sections tag -> { tag = tag; blocks = Section sections }
129
145
static member OfJson json =
130
146
match json with
131
147
| JArray o -> match List.ofSeq o with
132
- | ( JNumber 1 m) :: ( JString " p" ) :: ( JArray subsections) :: [] -> ( fun sections -> { tag = Paragraph; blocks = Section sections }) <!> ( parseSectionBlockList subsections)
133
- | ( JNumber 1 m) :: ( JString " h2" ) :: ( JArray subsections) :: [] -> ( fun sections -> { tag = Heading; blocks = Section sections }) <!> ( parseSectionBlockList subsections)
134
- | ( JNumber 10 m) :: ( JNumber x) :: [] -> Decode.Success { tag = Card; blocks = CardReference <| Decimal.ToInt32 x }
135
- | _ -> Decode.Fail.invalidValue json " failed to parse into sections"
136
- | json -> Decode.Fail.arrExpected json
137
- // Sections are the core of the ghost mobiledoc format, they're what will directly dictate the structure of the exported CMS json
148
+ | [ JNumber 10 m; JNumber x] -> Decode.Success { tag = Card; blocks = CardReference <| Decimal.ToInt32 x }
149
+ | [ JNumber 3 m; JString sectionType; JArray subsectionArray] ->
150
+ // this is so hacky im sorry :(, please fix this later
151
+ let rec sequenceSubsections = function
152
+ | [] -> Ok []
153
+ | x :: xs ->
154
+ match x with
155
+ | JArray inner -> match parseSectionBlockList inner with
156
+ | Ok arr -> ( fun parsedValue -> List.append arr parsedValue) <!> ( sequenceSubsections xs)
157
+ | Error x -> Error x
158
+ | o -> Decode.Fail.arrExpected o
159
+
160
+ section.createSection <!> ( sequenceSubsections <| List.ofSeq subsectionArray) <*> ( Ok Paragraph)
161
+
162
+ | [ JNumber 1 m; JString sectionType; JArray subsections] ->
163
+ let partialSection = section.createSection <!> ( parseSectionBlockList subsections)
164
+ match sectionType with
165
+ | " p" -> partialSection <*> ( Ok Paragraph)
166
+ | " h2" | " h3" | " h4" -> partialSection <*> ( Ok Heading)
167
+ | _ -> Decode.Fail.invalidValue json " failed to parse into sections"
168
+
169
+ | _ -> Decode.Fail.invalidValue json " failed to parse into sections"
170
+ | json ->
171
+ printf " %A " json
172
+ Decode.Fail.arrExpected json
138
173
139
174
140
175
type GhostDocument = {
@@ -149,7 +184,6 @@ type GhostDocument = {
149
184
let! markups = o .@ " markups"
150
185
let! cards = o .@ " cards"
151
186
let! sections = o .@ " sections"
152
-
153
187
return {
154
188
Cards = cards
155
189
Markups = markups
0 commit comments