0 | module Text.YAML.Parser
4 | import public Text.Parse.Manual
5 | import public Text.YAML.Types
6 | import Text.YAML.Lexer
20 | evs : SnocList (Bounded Event)
23 | emit : Bounds -> Event -> YState -> YState
24 | emit bs e = {evs $= (:< B e bs)}
29 | emptyScalarP : Props -> Position -> SnocList (Bounded Event) -> SnocList (Bounded Event)
30 | emptyScalarP pr p = (:< oneChar (Scalar pr.anchor pr.tag Plain "") p)
33 | emptyScalar : Position -> SnocList (Bounded Event) -> SnocList (Bounded Event)
34 | emptyScalar = emptyScalarP noProps
41 | data Pending : Type where
42 | PScalar : Props -> Style -> String -> Pending
43 | PAlias : Anchor -> Pending
44 | PProps : Props -> Pending
45 | PFlow : SnocList (Bounded Event) -> Pending
47 | flushPend : (start, end : Position) -> SnocList (Bounded Event) -> Pending -> SnocList (Bounded Event)
48 | flushPend s e evs (PScalar pr sty str) = evs :< bounded (Scalar pr.anchor pr.tag sty str) s e
49 | flushPend s e evs (PAlias a) = evs :< bounded (Alias a) s e
50 | flushPend s _ evs (PProps pr) = emptyScalarP pr s evs
51 | flushPend _ _ evs (PFlow d) = evs ++ d
55 | patchFlow : Props -> SnocList (Bounded Event) -> Either YErr (SnocList (Bounded Event))
56 | patchFlow pr evs = case evs <>> [] of
57 | B (SeqStart f a t) bs :: es =>
58 | (\p => [<] <>< (B (SeqStart f p.anchor p.tag) bs :: es)) <$> mergeProps pr (MkProps a t)
59 | B (MapStart f a t) bs :: es =>
60 | (\p => [<] <>< (B (MapStart f p.anchor p.tag) bs :: es)) <$> mergeProps pr (MkProps a t)
64 | colonBlock : List Char -> Bool
65 | colonBlock (':' :: t) = wordEnd t
66 | colonBlock _ = False
69 | colonFlow : List Char -> Bool
70 | colonFlow (':' :: n :: _) = not (isPlainSafe True n)
71 | colonFlow (':' :: []) = True
75 | dashNext : List Char -> Bool
76 | dashNext ('-' :: t) = wordEnd t
79 | plainSafeNext : List Char -> Bool
80 | plainSafeNext (c :: _) = isPlainSafe True c
81 | plainSafeNext [] = False
84 | candStart : (inFlow : Bool) -> List Char -> Bool
85 | candStart inFlow (c :: cs) =
86 | c == '[' || c == '{' || c == '\'' || c == '"' || c == '*' ||
87 | isPlainFirst inFlow c cs
88 | candStart _ [] = False
91 | bsStart : List Char -> Maybe Bool
92 | bsStart ('|' :: _) = Just False
93 | bsStart ('>' :: _) = Just True
96 | breakStart : List Char -> Bool
97 | breakStart (c :: _) = isBreak c || c == '#'
98 | breakStart [] = False
100 | propStart : List Char -> Bool
101 | propStart (c :: _) = c == '&' || c == '!'
102 | propStart [] = False
104 | colonNext : List Char -> Bool
105 | colonNext (':' :: _) = True
106 | colonNext _ = False
109 | propsOnlyLine : List Char -> Bool
113 | tok : List Char -> Bool
115 | if isWhite c || isBreak c then go (c :: cs) else tok cs
118 | go : List Char -> Bool
119 | go (' ' :: cs) = go cs
120 | go ('\t' :: cs) = go cs
121 | go ('\n' :: _) = True
122 | go ('#' :: _) = True
123 | go ('&' :: cs) = tok cs
124 | go ('!' :: cs) = tok cs
130 | jsonLike : Pending -> Bool
131 | jsonLike (PScalar _ SingleQ _) = True
132 | jsonLike (PScalar _ DoubleQ _) = True
133 | jsonLike (PFlow _) = True
137 | pendProps : Pending -> Bool
138 | pendProps (PScalar pr _ _) = not (isNoProps pr)
139 | pendProps (PProps _) = True
140 | pendProps _ = False
159 | 0 Rule : Bool -> Type -> Type
162 | -> (cs : List Char)
163 | -> (0 acc : SuffixAcc cs)
164 | -> Result0 b Char cs (BoundedErr YErr) a
177 | -> (cs : List Char)
178 | -> (0 a : SuffixAcc cs)
179 | -> Result0 True Char cs (BoundedErr YErr) (Props, Position)
180 | pProps env pr pos ('&' :: cs) sa@(SA r) = case pr.anchor of
181 | Just _ => custom (oneChar pos) MultipleAnchors
182 | Nothing => case anchorName ('&' :: cs) of
183 | Succ nm rem @{prf} =>
184 | let IL cnt tbw2 rem2 w := inlineWhite rem
185 | pos2 := addCol cnt (move pos prf)
186 | pr2 := {anchor := Just nm} pr
187 | 0 pp := trans w prf
188 | in if propStart rem2
189 | then succT (pProps env pr2 pos2 rem2 (r @{pp})) @{pp}
190 | else Succ0 (pr2, pos2) rem2 @{pp}
191 | Fail start errEnd err => Fail0 (boundedErr pos start errEnd err)
192 | pProps env pr pos ('!' :: cs) sa@(SA r) = case pr.tag of
193 | NoTag => case tagToken ('!' :: cs) of
194 | Succ et rem @{prf} =>
195 | let pos1 := move pos prf
196 | in case resolved et of
197 | Left e => custom (BS pos pos1) e
199 | let IL cnt tbw2 rem2 w := inlineWhite rem
200 | pr2 := {tag := tg} pr
201 | 0 pp := trans w prf
202 | in if propStart rem2
203 | then succT (pProps env pr2 (addCol cnt pos1) rem2 (r @{pp})) @{pp}
204 | else Succ0 (pr2, addCol cnt pos1) rem2 @{pp}
205 | Fail start errEnd err => Fail0 (boundedErr pos start errEnd err)
206 | _ => custom (oneChar pos) MultipleTags
209 | resolved : Either Tag (String, String) -> Either YErr Tag
210 | resolved (Left t) = Right t
211 | resolved (Right (h, s)) = resolveTag env h s
212 | pProps env pr pos [] _ = eoi
213 | pProps env pr pos (c :: cs) _ =
214 | parseFail (oneChar pos) (Expected ["'&'", "'!'"] (pack [c]))
227 | -> (cs : List Char)
228 | -> Result0 False Char cs (BoundedErr YErr) Position
229 | flowLines tok b mi pos cs = case skipToContent cs of
230 | SR (L _ LEnd _) rem prf => Succ0 (endPos pos prf) rem @{prf}
231 | SR (L ind LContent tb) rem prf =>
233 | then Succ0 (endPos pos prf) rem @{prf}
234 | else custom (oneChar $
endPos pos prf) BadIndent
235 | SR (L _ _ _) rem prf => unclosed b tok
243 | -> (cs : List Char)
244 | -> Result0 False Char cs (BoundedErr YErr) Position
245 | flowComment tok b mi pos (c :: cs) =
247 | then succF $
flowLines tok b mi (incLine pos) cs
248 | else succF $
flowComment tok b mi (incCol pos) cs
249 | flowComment _ _ _ pos [] = Succ0 pos []
261 | -> (cs : List Char)
262 | -> Result0 False Char cs (BoundedErr YErr) Position
263 | flowSkip tok b mi sw pos (c :: cs) =
264 | if isWhite c then succF $
flowSkip tok b mi True (incCol pos) cs
265 | else if isBreak c then succF $
flowLines tok b mi (incLine pos) cs
266 | else if c == '#' && sw then succF $
flowComment tok b mi (incCol pos) cs
267 | else Succ0 pos (c :: cs)
268 | flowSkip _ _ _ _ pos [] = Succ0 pos []
275 | lineEndC : Position -> (cs : List Char) -> Result0 False Char cs (BoundedErr YErr) Position
276 | lineEndC pos [] = Succ0 pos []
277 | lineEndC pos (c :: cs) =
279 | then Succ0 pos (c :: cs)
280 | else succF $
lineEndC (incCol pos) cs
285 | lineEnd : (sw : Bool) -> Position -> (cs : List Char) -> Result0 False Char cs (BoundedErr YErr) Position
286 | lineEnd sw pos [] = Succ0 pos []
287 | lineEnd sw pos (c :: cs) =
288 | if isWhite c then succF $
lineEnd True (incCol pos) cs
289 | else if isBreak c then Succ0 pos (c :: cs)
290 | else if c == '#' && sw then succF $
lineEndC (incCol pos) cs
291 | else custom (oneChar pos) TrailingContent
300 | parseDirective : TagEnv -> (sawYaml : Bool) -> String -> Either YErr (TagEnv, Bool)
301 | parseDirective env sy ln = case takeWhile (not . isPrefixOf "#") (words ln) of
303 | if sy then Left (BadDirective "duplicate %YAML directive")
304 | else if versionOk (unpack v) then Right (env, True)
305 | else Left (BadVersion v)
306 | ("%YAML" :: _) => Left (BadDirective ln)
307 | ["%TAG", h, pre] => case lookup h env.handles of
308 | Just _ => Left (DuplicateHandle h)
310 | if handleOk (unpack h)
311 | then Right (TE ((h, pre) :: env.handles), sy)
312 | else Left (BadDirective ln)
313 | ("%TAG" :: _) => Left (BadDirective ln)
314 | _ => Right (env, sy)
317 | versionOk : List Char -> Bool
318 | versionOk ('1' :: '.' :: ds@(_ :: _)) = all isDigit ds
319 | versionOk _ = False
321 | inner : List Char -> Bool
323 | inner (c :: t) = isWordChar c && inner t
326 | handleOk : List Char -> Bool
327 | handleOk ['!'] = True
328 | handleOk ('!' :: t) = inner t
348 | -> (pos : Position)
349 | -> (cs : List Char)
350 | -> (0 a : SuffixAcc cs)
351 | -> Result0 False Char cs (BoundedErr YErr) (String, Position)
352 | plainMore inFlow mi acc pos cs (SA r) = case plainCont inFlow mi cs of
353 | Stop => Succ0 (acc, pos) cs
354 | More k rem prf => case plainSegment inFlow rem of
355 | Succ s rem2 @{p2} =>
356 | let acc2 := acc ++ fold k ++ s
357 | pos2 := move (endPos pos prf) p2
358 | 0 pp := trans p2 prf
359 | in trans (plainMore inFlow mi acc2 pos2 rem2 (r @{pp})) (weaken pp)
360 | Fail start errEnd err => Fail0 (boundedErr (endPos pos prf) start errEnd err)
363 | fold : Nat -> String
365 | fold k = replicate k '\n'
376 | -> (cs : List Char)
377 | -> (0 a : SuffixAcc cs)
378 | -> Result0 True Char cs (BoundedErr YErr) (Pending, Position)
379 | cand inFlow mi env pr pos [] _ = eoi
380 | cand inFlow mi env pr pos (c :: cs) sa@(SA r) =
381 | if c == '&' || c == '!'
382 | then case pProps env pr pos (c :: cs) sa of
384 | Succ0 (pr2, p1) r1 @{q1} =>
385 | if candStart inFlow r1
386 | then succT (cand inFlow mi env pr2 p1 r1 (r @{q1})) @{q1}
387 | else Succ0 (PProps pr2, p1) r1 @{q1}
391 | then case anchorName (c :: cs) of
392 | Succ nm rem @{prf} => Succ0 (PAlias nm, move pos prf) rem
393 | Fail start errEnd err => Fail0 (boundedErr pos start errEnd err)
394 | else parseFail (oneChar pos) (Unknown "properties on alias node")
395 | else if c == '[' || c == '{'
396 | then case flowNode inFlow mi env pr pos (YS pos [<]) (c :: cs) sa of
398 | Succ0 st1 r1 => Succ0 (PFlow st1.evs, st1.pos) r1
399 | else if c == '\'' || c == '"'
401 | let (tok, sty) := if c == '"'
402 | then (doubleQuoted mi, DoubleQ)
403 | else (singleQuoted mi, SingleQ)
404 | in case tok (c :: cs) of
405 | Succ s rem @{prf} => Succ0 (PScalar pr sty s, endPos pos prf) rem
406 | Fail start errEnd err => Fail0 (boundedErr pos start errEnd err)
407 | else if isPlainFirst inFlow c cs
408 | then case plainSegment inFlow (c :: cs) of
409 | Succ s rem @{prf} => Succ0 (PScalar pr Plain s, move pos prf) rem
410 | Fail start errEnd err => Fail0 (boundedErr pos start errEnd err)
411 | else parseFail (oneChar pos) (Unknown $
pack [c])
417 | flowNode : (inFlow : Bool) -> (mi : Nat) -> TagEnv -> Props -> (sp : Position) -> Rule True YState
418 | flowNode inFlow mi env pr sp st [] _ = eoi
419 | flowNode inFlow mi env pr sp st (c :: cs) sa@(SA r) = case c of
420 | '&' => flowProps inFlow mi env pr sp st (c :: cs) sa
421 | '!' => flowProps inFlow mi env pr sp st (c :: cs) sa
424 | then case anchorName ('*' :: cs) of
425 | Succ nm rem @{prf} =>
426 | let pe := move st.pos prf
427 | in Succ0 (YS pe (st.evs :< bounded (Alias nm) st.pos pe)) rem @{prf}
428 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
429 | else parseFail (oneChar st.pos) (Unknown "properties on alias node")
430 | '[' => case flowSkip "[" (oneChar st.pos) mi False (incCol st.pos) cs of
432 | Succ0 p1 r1 @{q1} =>
433 | let 0 pp := trans q1 (uncons Same)
434 | st1 := YS p1 (st.evs :< oneChar (SeqStart True pr.anchor pr.tag) st.pos)
435 | in succT (flowSeq env mi (oneChar st.pos) st1 r1 (r @{pp})) @{pp}
436 | '{' => case flowSkip "{" (oneChar st.pos) mi False (incCol st.pos) cs of
438 | Succ0 p1 r1 @{q1} =>
439 | let 0 pp := trans q1 (uncons Same)
440 | st1 := YS p1 (st.evs :< oneChar (MapStart True pr.anchor pr.tag) st.pos)
441 | in succT (flowMap env mi (oneChar st.pos) st1 r1 (r @{pp})) @{pp}
442 | '\'' => case singleQuoted mi (c :: cs) of
443 | Succ s rem @{prf} =>
444 | let pe := endPos st.pos prf
445 | in Succ0 (YS pe (st.evs :< bounded (Scalar pr.anchor pr.tag SingleQ s) sp pe)) rem
446 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
447 | '"' => case doubleQuoted mi (c :: cs) of
448 | Succ s rem @{prf} =>
449 | let pe := endPos st.pos prf
450 | in Succ0 (YS pe (st.evs :< bounded (Scalar pr.anchor pr.tag DoubleQ s) sp pe)) rem
451 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
453 | if isPlainFirst inFlow c cs
454 | then case plainSegment inFlow (c :: cs) of
455 | Succ s rem @{prf} =>
456 | case plainMore inFlow mi s (move st.pos prf) rem (r @{prf}) of
458 | Succ0 (s2, p2) rem2 @{q2} =>
459 | Succ0 (YS p2 (st.evs :< bounded (Scalar pr.anchor pr.tag Plain s2) sp p2)) rem2
461 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
462 | else parseFail (oneChar st.pos) (Unknown $
pack [c])
466 | flowProps : (inFlow : Bool) -> (mi : Nat) -> TagEnv -> Props -> (sp : Position) -> Rule True YState
467 | flowProps inFlow mi env pr sp st cs sa@(SA r) = case pProps env pr st.pos cs sa of
469 | Succ0 (pr2, p1) r1 @{q1} =>
470 | if candStart inFlow r1
471 | then succT (flowNode inFlow mi env pr2 sp (YS p1 st.evs) r1 (r @{q1})) @{q1}
472 | else if breakStart r1
473 | then case skipToContent r1 of
474 | SR (L ind LContent tb) r2 prf2 =>
477 | let 0 pp := trans prf2 q1
478 | pc := endPos p1 prf2
479 | in succT (flowNode inFlow mi env pr2 pc (YS pc st.evs) r2 (r @{pp})) @{pp}
480 | else custom (oneChar $
endPos p1 prf2) BadIndent
481 | SR _ _ _ => Succ0 (YS p1 (emptyScalarP pr2 sp st.evs)) r1 @{q1}
482 | else Succ0 (YS p1 (emptyScalarP pr2 sp st.evs)) r1 @{q1}
487 | flowSeq : TagEnv -> (mi : Nat) -> (b : Bounds) -> Rule True YState
488 | flowSeq env mi b st (']' :: cs) _ =
489 | Succ0 (emit (oneChar st.pos) SeqEnd $
{pos $= incCol} st) cs
490 | flowSeq env mi b st [] _ = unclosed b "["
491 | flowSeq env mi b st (':' :: cs) sa@(SA r) =
493 | if plainSafeNext cs
494 | then seqItem env mi b st (':' :: cs) sa
496 | let evs1 := emptyScalar st.pos (st.evs :< oneChar (MapStart True Nothing NoTag) st.pos)
497 | in case flowSkip "[" b mi False (incCol st.pos) cs of
499 | Succ0 p1 r1 @{q1} =>
500 | let 0 pp := trans q1 (uncons Same)
501 | in case flowVal env mi (YS p1 evs1) r1 (r @{pp}) of
503 | Succ0 st2 r2 @{q2} =>
504 | let 0 p2c := trans q2 pp
505 | in succT (seqTail env mi b False (emit (oneChar st2.pos) MapEnd st2) r2 (r @{p2c})) @{p2c}
506 | flowSeq env mi b st ('?' :: cs) sa@(SA r) =
508 | if plainSafeNext cs
509 | then seqItem env mi b st ('?' :: cs) sa
511 | let evs1 := st.evs :< oneChar (MapStart True Nothing NoTag) st.pos
512 | in case flowSkip "[" b mi False (incCol st.pos) cs of
514 | Succ0 p1 r1 @{q1} =>
515 | let 0 pp := trans q1 (uncons Same)
516 | in case pairKey env mi b (YS p1 evs1) r1 (r @{pp}) of
518 | Succ0 st2 r2 @{q2} =>
519 | let 0 p2c := trans q2 pp
520 | in succT (seqTail env mi b False st2 r2 (r @{p2c})) @{p2c}
521 | flowSeq env mi b st cs sa = seqItem env mi b st cs sa
526 | pairKey : TagEnv -> (mi : Nat) -> (b : Bounds) -> Rule False YState
527 | pairKey env mi b st cs sa@(SA r) =
529 | then Succ0 ({evs $= (:< oneChar MapEnd st.pos) . emptyScalar st.pos . emptyScalar st.pos} st) cs
530 | else case flowNode True mi env noProps st.pos st cs sa of
532 | Succ0 st1 r1 @{q1} => case flowSkip "[" b mi False st1.pos r1 of
534 | Succ0 p2 (':' :: r2) @{q2} =>
535 | case flowSkip "[" b mi False (incCol p2) r2 of
537 | Succ0 p3 r3 @{q3} =>
538 | let 0 pp := trans q3 (trans (uncons Same) (trans q2 q1))
539 | in case flowVal env mi (YS p3 st1.evs) r3 (r @{pp}) of
541 | Succ0 st4 r4 @{q4} =>
542 | Succ0 (emit (oneChar st4.pos) MapEnd st4) r4 @{weaken $
trans q4 pp}
543 | Succ0 p2 r2 @{q2} =>
544 | Succ0 (YS p2 (st1.evs :< oneChar (Scalar Nothing NoTag Plain "") p2 :< oneChar MapEnd p2)) r2
545 | @{weaken $
trans q2 q1}
548 | emptyNext : List Char -> Bool
549 | emptyNext (c :: _) = c == ']' || c == ','
550 | emptyNext [] = False
554 | seqItem : TagEnv -> (mi : Nat) -> (b : Bounds) -> Rule True YState
555 | seqItem env mi b st cs sa@(SA r) =
556 | case cand True mi env noProps st.pos cs sa of
558 | Succ0 (pend, p1) r1 @{q1} =>
559 | let IL cnt tbw r2 w := inlineWhite r1
560 | p2 := addCol cnt p1
562 | in if colonFlow r2 || (jsonLike pend && colonNext r2)
564 | if p1.line /= st.pos.line
565 | then custom (BS st.pos p1) InvalidKey
568 | let evs1 := flushPend st.pos p1 (st.evs :< oneChar (MapStart True Nothing NoTag) st.pos) pend
569 | 0 pc := trans (uncons Same) (trans w q1)
570 | in case flowSkip "[" b mi False (incCol p2) r3 of
572 | Succ0 p4 r4 @{q4} =>
573 | let 0 p4c := trans q4 pc
574 | in case flowVal env mi (YS p4 evs1) r4 (r @{p4c}) of
576 | Succ0 st5 r5 @{q5} =>
577 | let 0 p5c := trans q5 p4c
578 | in succT (seqTail env mi b False (emit (oneChar st5.pos) MapEnd st5) r5 (r @{p5c})) @{p5c}
579 | _ => unclosed b "["
582 | succT (seqTail env mi b (cnt > 0) (YS p2 (st.evs ++ d)) r2 (r @{pw})) @{pw}
584 | succT (seqTail env mi b (cnt > 0) (YS p2 (st.evs :< bounded (Alias a) st.pos p1)) r2 (r @{pw})) @{pw}
586 | succT (seqTail env mi b (cnt > 0) (YS p2 (emptyScalarP pr st.pos st.evs)) r2 (r @{pw})) @{pw}
587 | PScalar pr Plain s =>
588 | case plainMore True mi s p2 r2 (r @{pw}) of
590 | Succ0 (s2, p3) r3 @{q3} =>
591 | let 0 pp := trans q3 pw
592 | st3 := YS p3 (st.evs :< bounded (Scalar pr.anchor pr.tag Plain s2) st.pos p3)
593 | in succT (seqTail env mi b (cnt > 0) st3 r3 (r @{pp})) @{pp}
594 | PScalar pr sty s =>
595 | let st2 := YS p2 (st.evs :< bounded (Scalar pr.anchor pr.tag sty s) st.pos p1)
596 | in succT (seqTail env mi b (cnt > 0) st2 r2 (r @{pw})) @{pw}
600 | seqTail : TagEnv -> (mi : Nat) -> (b : Bounds) -> (sw : Bool) -> Rule True YState
601 | seqTail env mi b sw st cs (SA r) = case flowSkip "[" b mi sw st.pos cs of
603 | Succ0 p2 (']' :: r2) @{q2} =>
604 | Succ0 (YS (incCol p2) (st.evs :< oneChar SeqEnd p2)) r2 @{trans (uncons Same) q2}
605 | Succ0 p2 (',' :: r2) @{q2} =>
606 | case flowSkip "[" b mi False (incCol p2) r2 of
608 | Succ0 p3 r3 @{q3} =>
609 | let 0 pp := trans q3 (trans (uncons Same) q2)
610 | in succT (flowSeq env mi b (YS p3 st.evs) r3 (r @{pp})) @{pp}
611 | Succ0 p2 [] => unclosed b "["
612 | Succ0 p2 (x :: _) =>
613 | parseFail (oneChar p2) (Expected ["','", "']'"] (pack [x]))
617 | flowMap : TagEnv -> (mi : Nat) -> (b : Bounds) -> Rule True YState
618 | flowMap env mi b st ('}' :: cs) _ =
619 | Succ0 (emit (oneChar st.pos) MapEnd $
{pos $= incCol} st) cs
620 | flowMap env mi b st [] _ = unclosed b "{"
621 | flowMap env mi b st ('?' :: cs) sa@(SA r) =
624 | if plainSafeNext cs
625 | then flowEntry env mi b st ('?' :: cs) sa
626 | else case flowSkip "{" b mi False (incCol st.pos) cs of
628 | Succ0 p1 r1 @{q1} =>
629 | let 0 pp := trans q1 (uncons Same)
631 | then succT (mapTail env mi b (YS p1 ({evs $= emptyScalar st.pos . emptyScalar st.pos} st).evs) r1 (r @{pp})) @{pp}
632 | else succT (flowEntry env mi b (YS p1 st.evs) r1 (r @{pp})) @{pp}
635 | emptyNext : List Char -> Bool
636 | emptyNext (c2 :: _) = c2 == '}' || c2 == ','
637 | emptyNext [] = False
639 | flowMap env mi b st cs sa = flowEntry env mi b st cs sa
642 | flowEntry : TagEnv -> (mi : Nat) -> (b : Bounds) -> Rule True YState
643 | flowEntry env mi b st [] _ = unclosed b "{"
644 | flowEntry env mi b st (c :: cs) sa@(SA r) =
645 | if c == ':' && not (plainSafeNext cs)
647 | case flowSkip "{" b mi False (incCol st.pos) cs of
649 | Succ0 p1 r1 @{q1} =>
650 | let 0 pp := trans q1 (uncons Same)
651 | in case flowVal env mi (YS p1 (emptyScalar st.pos st.evs)) r1 (r @{pp}) of
653 | Succ0 st2 r2 @{q2} => case flowSkip "{" b mi False st2.pos r2 of
655 | Succ0 p3 r3 @{q3} =>
656 | let 0 pp3 := trans (trans q3 (trans q2 q1)) (uncons Same)
657 | in succT (mapTail env mi b (YS p3 st2.evs) r3 (r @{pp3})) @{pp3}
659 | case flowNode True mi env noProps st.pos st (c :: cs) sa of
661 | Succ0 st1 r1 @{q1} => case flowSkip "{" b mi False st1.pos r1 of
663 | Succ0 p2 (':' :: r2) @{q2} =>
664 | case flowSkip "{" b mi False (incCol p2) r2 of
666 | Succ0 p3 r3 @{q3} =>
667 | let 0 pp := trans q3 (trans (uncons Same) (trans q2 q1))
668 | in case flowVal env mi (YS p3 st1.evs) r3 (r @{pp}) of
670 | Succ0 st4 r4 @{q4} =>
671 | case flowSkip "{" b mi False st4.pos r4 of
673 | Succ0 p5 r5 @{q5} =>
674 | let 0 pp5 := trans q5 (trans q4 pp)
675 | in succT (mapTail env mi b (YS p5 st4.evs) r5 (r @{pp5})) @{pp5}
676 | Succ0 p2 r2 @{q2} =>
678 | let 0 pp := trans q2 q1
679 | in succT (mapTail env mi b (YS p2 (emptyScalar p2 st1.evs)) r2 (r @{pp})) @{pp}
683 | flowVal : TagEnv -> (mi : Nat) -> Rule False YState
684 | flowVal env mi st [] _ = Succ0 ({evs $= emptyScalar st.pos} st) []
685 | flowVal env mi st (',' :: cs) _ = Succ0 ({evs $= emptyScalar st.pos} st) (',' :: cs)
686 | flowVal env mi st ('}' :: cs) _ = Succ0 ({evs $= emptyScalar st.pos} st) ('}' :: cs)
687 | flowVal env mi st (']' :: cs) _ = Succ0 ({evs $= emptyScalar st.pos} st) (']' :: cs)
688 | flowVal env mi st cs acc = weaken $
flowNode True mi env noProps st.pos st cs acc
692 | mapTail : TagEnv -> (mi : Nat) -> (b : Bounds) -> Rule True YState
693 | mapTail env mi b st ('}' :: cs) _ =
694 | Succ0 (emit (oneChar st.pos) MapEnd $
{pos $= incCol} st) cs
695 | mapTail env mi b st (',' :: cs) (SA r) =
696 | case flowSkip "{" b mi False (incCol st.pos) cs of
698 | Succ0 p1 r1 @{q1} =>
699 | let 0 pp := trans q1 (uncons Same)
700 | in succT (flowMap env mi b (YS p1 st.evs) r1 (r @{pp})) @{pp}
701 | mapTail env mi b st [] _ = unclosed b "{"
702 | mapTail env mi b st (x :: _) _ =
703 | parseFail (oneChar st.pos) (Expected ["','", "'}'"] (pack [x]))
712 | blockNode : (mi : Nat) -> (nOv : Maybe Nat) -> (tabSep : Bool) -> TagEnv -> Props -> Rule True YState
713 | blockNode mi nOv tabSep env oprops st [] _ = eoi
714 | blockNode mi nOv tabSep env oprops st (c :: cs) sa@(SA r) =
715 | let n := maybe st.pos.col id nOv
716 | in if c == '-' && wordEnd cs
719 | then custom (oneChar st.pos) TabIndent
720 | else seqLoop env n (emit (oneChar st.pos) (SeqStart False oprops.anchor oprops.tag) st) (c :: cs) sa
721 | else if c == '?' && wordEnd cs
724 | then custom (oneChar st.pos) TabIndent
725 | else case expEntry env n (emit (oneChar st.pos) (MapStart False oprops.anchor oprops.tag) st) (c :: cs) sa of
727 | Succ0 st1 r1 @{q1} => trans (blockMap env n st1 r1 (r @{q1})) q1
728 | else if c == ':' && wordEnd cs
731 | then custom (oneChar st.pos) TabIndent
733 | let evs1 := emptyScalar st.pos (st.evs :< oneChar (MapStart False oprops.anchor oprops.tag) st.pos)
734 | in case afterKey env n False noProps (YS (incCol st.pos) evs1) cs (r @{uncons Same}) of
736 | Succ0 st1 r1 @{q1} =>
737 | let 0 p1 := trans q1 (uncons Same)
738 | in trans (blockMap env n st1 r1 (r @{p1})) p1
739 | else if c == '|' || c == '>'
740 | then case blockScalar (c == '>') mi (c :: cs) of
741 | Succ s rem @{prf} =>
742 | let sty := if c == '>' then Folded else Literal
743 | in let pe := endPos st.pos prf
744 | in Succ0 (YS pe (st.evs :< bounded (Scalar oprops.anchor oprops.tag sty s) st.pos pe)) rem
745 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
746 | else case cand False mi env noProps st.pos (c :: cs) sa of
748 | Succ0 (pend, p1) r1 @{q1} =>
749 | let IL cnt tbw r2 w := inlineWhite r1
750 | p2 := addCol cnt p1
752 | in if colonBlock r2
755 | then custom (oneChar st.pos) TabIndent
756 | else if p1.line /= st.pos.line
757 | then custom (BS st.pos p1) InvalidKey
758 | else if isJust nOv && pendProps pend
759 | then custom (BS st.pos p1) InvalidKey
762 | let evs1 := flushPend st.pos p1 (st.evs :< oneChar (MapStart False oprops.anchor oprops.tag) st.pos) pend
763 | 0 pc := trans (uncons Same) (trans w q1)
764 | in case afterKey env n False noProps (YS (incCol p2) evs1) r3 (r @{pc}) of
766 | Succ0 st4 r4 @{q4} =>
767 | let 0 p4 := trans q4 pc
768 | in trans (blockMap env n st4 r4 (r @{p4})) p4
771 | PFlow d => case patchFlow oprops d of
772 | Left e => custom (BS st.pos p1) e
773 | Right d2 => case lineEnd (cnt > 0) p2 r2 of
775 | Succ0 p3 r3 @{q3} =>
776 | Succ0 (YS p3 (st.evs ++ d2)) r3 @{trans q3 pw}
778 | if isNoProps oprops
779 | then case lineEnd (cnt > 0) p2 r2 of
781 | Succ0 p3 r3 @{q3} =>
782 | Succ0 (YS p3 (st.evs :< bounded (Alias a) st.pos p1)) r3 @{trans q3 pw}
783 | else parseFail (oneChar st.pos) (Unknown "properties on alias node")
784 | PProps pr => case mergeProps oprops pr of
785 | Left e => custom (BS st.pos p1) e
786 | Right prm => case bsStart r2 of
787 | Just f => case blockScalar f mi r2 of
788 | Succ s rem @{prf} =>
789 | let sty := if f then Folded else Literal
790 | in let pe := endPos p2 prf
791 | in Succ0 (YS pe (st.evs :< bounded (Scalar prm.anchor prm.tag sty s) st.pos pe)) rem
793 | Fail start errEnd err => Fail0 (boundedErr p2 start errEnd err)
796 | then case skipToContent r2 of
797 | SR (L ind LContent tb) r3 prf3 =>
800 | let 0 p3 := trans prf3 pw
801 | in succT (blockNode mi Nothing tb env prm (YS (endPos p2 prf3) st.evs) r3 (r @{p3})) @{p3}
802 | else Succ0 (YS p2 (emptyScalarP prm st.pos st.evs)) r2 @{pw}
803 | SR _ _ _ => Succ0 (YS p2 (emptyScalarP prm st.pos st.evs)) r2 @{pw}
805 | then Succ0 (YS p2 (emptyScalarP prm st.pos st.evs)) r2 @{pw}
806 | else parseFail (oneChar p2) (Unknown "content after node properties")
807 | PScalar pr Plain s => case mergeProps oprops pr of
808 | Left e => custom (BS st.pos p1) e
809 | Right prm => case plainMore False mi s p2 r2 (r @{pw}) of
811 | Succ0 (s2, p3) r3 @{q3} =>
813 | then custom (BS st.pos p3) InvalidKey
815 | Succ0 (YS p3 (st.evs :< bounded (Scalar prm.anchor prm.tag Plain s2) st.pos p3)) r3
817 | PScalar pr sty s => case mergeProps oprops pr of
818 | Left e => custom (BS st.pos p1) e
819 | Right prm => case lineEnd (cnt > 0) p2 r2 of
821 | Succ0 p3 r3 @{q3} =>
822 | Succ0 (YS p3 (st.evs :< bounded (Scalar prm.anchor prm.tag sty s) st.pos p1)) r3
828 | seqLoop : TagEnv -> (n : Nat) -> Rule True YState
829 | seqLoop env n st ('-' :: cs) (SA r) =
830 | case seqEntry env n (YS (incCol st.pos) st.evs) cs (r @{uncons Same}) of
832 | Succ0 st1 r1 @{q1} =>
833 | let 0 p1 := trans q1 (uncons Same)
834 | in case skipToContent r1 of
835 | SR (L ind LContent tb) r2 prf2 =>
836 | if ind == n && dashNext r2
839 | then custom (oneChar $
endPos st1.pos prf2) TabIndent
841 | let 0 pp := trans prf2 p1
842 | in succT (seqLoop env n (YS (endPos st1.pos prf2) st1.evs) r2 (r @{pp})) @{pp}
843 | else Succ0 (emit (oneChar st1.pos) SeqEnd st1) r1 @{p1}
844 | SR _ _ _ => Succ0 (emit (oneChar st1.pos) SeqEnd st1) r1 @{p1}
845 | seqLoop env n st (x :: _) _ = parseFail (oneChar st.pos) (Expected ["'-'"] (pack [x]))
846 | seqLoop env n st [] _ = eoi
851 | seqEntry : TagEnv -> (n : Nat) -> Rule False YState
852 | seqEntry env n st cs sa@(SA r) =
853 | let IL cnt tbw r2 w := inlineWhite cs
854 | p2 := addCol cnt st.pos
856 | [] => Succ0 (YS p2 (emptyScalar p2 st.evs)) [] @{w}
858 | if isBreak x || x == '#'
859 | then case skipToContent (x :: xs) of
860 | SR (L ind LContent tb) r3 prf3 =>
863 | let st3 := YS (endPos p2 prf3) st.evs
864 | in case trans prf3 w of
865 | Same => weaken $
blockNode (S n) Nothing tb env noProps st3 r3 sa
867 | weaken $
trans (blockNode (S n) Nothing tb env noProps st3 r3 (r @{uncons u}))
868 | (weaken (uncons u))
869 | else Succ0 (YS p2 (emptyScalar p2 st.evs)) (x :: xs) @{w}
870 | SR _ _ _ => Succ0 (YS p2 (emptyScalar p2 st.evs)) (x :: xs) @{w}
872 | let st2 := YS p2 st.evs
874 | Same => weaken $
blockNode (S n) Nothing tbw env noProps st2 (x :: xs) sa
876 | weaken $
trans (blockNode (S n) Nothing tbw env noProps st2 (x :: xs) (r @{uncons u}))
877 | (weaken (uncons u))
881 | blockMap : TagEnv -> (n : Nat) -> Rule False YState
882 | blockMap env n st cs sa@(SA r) = case skipToContent cs of
883 | SR (L ind LContent tb) r2 prf2 =>
886 | if tb then custom (oneChar $
endPos st.pos prf2) TabIndent else
887 | let st2 := YS (endPos st.pos prf2) st.evs
889 | Same => case mapEntry env n st2 r2 sa of
891 | Succ0 st3 r3 @{q3} =>
892 | trans (blockMap env n st3 r3 (r @{q3})) (weaken q3)
893 | Uncons u => case mapEntry env n st2 r2 (r @{uncons u}) of
895 | Succ0 st3 r3 @{q3} =>
896 | let 0 p3 := trans q3 (uncons u)
897 | in trans (blockMap env n st3 r3 (r @{p3})) (weaken p3)
898 | else Succ0 (emit (oneChar st.pos) MapEnd st) cs
899 | SR _ _ _ => Succ0 (emit (oneChar st.pos) MapEnd st) cs
904 | mapEntry : TagEnv -> (n : Nat) -> Rule True YState
905 | mapEntry env n st [] _ = eoi
906 | mapEntry env n st (c :: cs) sa@(SA r) =
907 | if c == '?' && wordEnd cs
908 | then expEntry env n st (c :: cs) sa
909 | else if c == ':' && wordEnd cs
910 | then case afterKey env n False noProps (YS (incCol st.pos) (emptyScalar st.pos st.evs)) cs (r @{uncons Same}) of
912 | Succ0 st1 r1 @{q1} => Succ0 st1 r1 @{trans q1 (uncons Same)}
913 | else case cand False (S n) env noProps st.pos (c :: cs) sa of
915 | Succ0 (pend, p1) r1 @{q1} =>
916 | let IL cnt tbw r2 w := inlineWhite r1
917 | p2 := addCol cnt p1
919 | in if colonBlock r2
921 | if p1.line /= st.pos.line
922 | then custom (BS st.pos p1) InvalidKey
925 | let 0 pc := trans (uncons Same) (trans w q1)
926 | in case afterKey env n False noProps (YS (incCol p2) (flushPend st.pos p1 st.evs pend)) r3 (r @{pc}) of
928 | Succ0 st4 r4 @{q4} => Succ0 st4 r4 @{trans q4 pc}
931 | x :: _ => parseFail (oneChar p2) (Expected ["':'"] (pack [x]))
938 | expEntry : TagEnv -> (n : Nat) -> Rule True YState
939 | expEntry env n st ('?' :: cs) sa@(SA r) =
940 | let IL cnt tbw r2 w := inlineWhite cs
941 | p2 := addCol cnt (incCol st.pos)
942 | keyRes : Result0 True Char ('?' :: cs) (BoundedErr YErr) YState :=
944 | [] => Succ0 (YS p2 (emptyScalar p2 st.evs)) [] @{trans w (uncons Same)}
946 | if isBreak x || x == '#'
947 | then case skipToContent (x :: xs) of
948 | SR (L ind LContent tb) r3 prf3 =>
951 | if ind >= S n || (ind == n && dashNext r3)
953 | let 0 p3 := trans prf3 (trans w (uncons Same))
954 | in succT (blockNode (S n) Nothing tb env noProps (YS (endPos p2 prf3) st.evs) r3 (r @{p3})) @{p3}
955 | else Succ0 (YS p2 (emptyScalar p2 st.evs)) (x :: xs) @{trans w (uncons Same)}
956 | SR _ _ _ => Succ0 (YS p2 (emptyScalar p2 st.evs)) (x :: xs) @{trans w (uncons Same)}
958 | let 0 pw := trans w (uncons Same)
959 | in succT (blockNode (S n) Nothing tbw env noProps (YS p2 st.evs) (x :: xs) (r @{pw})) @{pw}
962 | Succ0 stK remK @{qK} => case skipToContent remK of
963 | SR (L ind LContent tb) rV prfV =>
964 | if ind == n && colonBlock rV
966 | if tb then custom (oneChar $
endPos stK.pos prfV) TabIndent else
969 | let pV := incCol (endPos stK.pos prfV)
970 | 0 pc := trans (uncons Same) (trans prfV qK)
971 | in case afterKey env n True noProps (YS pV stK.evs) rV2 (r @{pc}) of
973 | Succ0 stF rF @{qF} => Succ0 stF rF @{trans qF pc}
975 | else Succ0 ({evs $= emptyScalar stK.pos} stK) remK @{qK}
976 | SR _ _ _ => Succ0 ({evs $= emptyScalar stK.pos} stK) remK @{qK}
977 | expEntry env n st (x :: _) _ = parseFail (oneChar st.pos) (Expected ["'?'"] (pack [x]))
978 | expEntry env n st [] _ = eoi
985 | afterKey : TagEnv -> (n : Nat) -> (cpt : Bool) -> Props -> Rule False YState
986 | afterKey env n cpt pr st cs sa@(SA r) =
987 | let IL cnt tbw r2 w := inlineWhite cs
988 | p2 := addCol cnt st.pos
990 | [] => Succ0 (YS p2 (emptyScalarP pr p2 st.evs)) [] @{w}
992 | if x == '&' || x == '!'
994 | Same => case pProps env pr p2 (x :: xs) sa of
996 | Succ0 (pr2, p3) r3 @{q3} =>
997 | trans (afterKey env n cpt pr2 (YS p3 st.evs) r3 (r @{q3})) (weaken q3)
998 | Uncons u => case pProps env pr p2 (x :: xs) (r @{uncons u}) of
1000 | Succ0 (pr2, p3) r3 @{q3} =>
1001 | let 0 pc := trans q3 (uncons u)
1002 | in trans (afterKey env n cpt pr2 (YS p3 st.evs) r3 (r @{pc})) (weaken pc)
1003 | else if isBreak x || x == '#'
1004 | then case skipToContent (x :: xs) of
1005 | SR (L ind LContent tb) r3 prf3 =>
1006 | let st3 := YS (endPos p2 prf3) st.evs
1007 | in if ind >= S n && propStart r3 && propsOnlyLine r3
1011 | then case trans prf3 w of
1012 | Same => case pProps env pr st3.pos r3 sa of
1014 | Succ0 (pr2, p4) r4 @{q4} =>
1015 | trans (afterKey env n cpt pr2 (YS p4 st.evs) r4 (r @{q4})) (weaken q4)
1016 | Uncons u => case pProps env pr st3.pos r3 (r @{uncons u}) of
1018 | Succ0 (pr2, p4) r4 @{q4} =>
1019 | let 0 pc := trans q4 (uncons u)
1020 | in trans (afterKey env n cpt pr2 (YS p4 st.evs) r4 (r @{pc})) (weaken pc)
1022 | then case trans prf3 w of
1023 | Same => weaken $
blockNode (S n) Nothing tb env pr st3 r3 sa
1025 | weaken $
trans (blockNode (S n) Nothing tb env pr st3 r3 (r @{uncons u}))
1027 | else if ind == n && dashNext r3
1029 | let st3s := emit (oneChar st3.pos) (SeqStart False pr.anchor pr.tag) st3
1030 | in case trans prf3 w of
1031 | Same => weaken $
seqLoop env n st3s r3 sa
1033 | weaken $
trans (seqLoop env n st3s r3 (r @{uncons u}))
1035 | else Succ0 (YS p2 (emptyScalarP pr p2 st.evs)) (x :: xs) @{w}
1036 | SR _ _ _ => Succ0 (YS p2 (emptyScalarP pr p2 st.evs)) (x :: xs) @{w}
1041 | Same => weaken $
blockNode (S n) Nothing tbw env pr (YS p2 st.evs) (x :: xs) sa
1043 | weaken $
trans (blockNode (S n) Nothing tbw env pr (YS p2 st.evs) (x :: xs) (r @{uncons u}))
1046 | Same => weaken $
inlineVal env n pr (YS p2 st.evs) (x :: xs) sa
1048 | weaken $
trans (inlineVal env n pr (YS p2 st.evs) (x :: xs) (r @{uncons u}))
1053 | inlineVal : TagEnv -> (n : Nat) -> Props -> Rule True YState
1054 | inlineVal env n pr st [] _ = eoi
1055 | inlineVal env n pr st (c :: cs) sa@(SA r) =
1056 | if c == '[' || c == '{' || c == '\'' || c == '"' || c == '*'
1057 | then case flowNode False (S n) env pr st.pos st (c :: cs) sa of
1059 | Succ0 st1 r1 @{q1} => case lineEnd False st1.pos r1 of
1061 | Succ0 p2 r2 @{q2} => Succ0 (YS p2 st1.evs) r2 @{trans q2 q1}
1062 | else if c == '|' || c == '>'
1063 | then case blockScalar (c == '>') (S n) (c :: cs) of
1065 | let sty := if c == '>' then Folded else Literal
1066 | in let pe := endPos st.pos prf
1067 | in Succ0 (YS pe (st.evs :< bounded (Scalar pr.anchor pr.tag sty s) st.pos pe)) rem
1068 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
1069 | else if isPlainFirst False c cs
1070 | then case plainSegment False (c :: cs) of
1072 | case plainMore False (S n) s (move st.pos prf) rem (r @{prf}) of
1074 | Succ0 (s2, p2) r2 @{q2} =>
1076 | then custom (BS st.pos p2) InvalidKey
1078 | Succ0 (YS p2 (st.evs :< bounded (Scalar pr.anchor pr.tag Plain s2) st.pos p2)) r2
1080 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
1081 | else parseFail (oneChar st.pos) (Unknown $
pack [c])
1091 | stream : (ab : Bool) -> TagEnv -> (sawYaml : Bool) -> Rule False YState
1092 | stream ab env sy st cs sa@(SA r) = case skipToContent cs of
1093 | SR (L _ LEnd _) rem prf =>
1095 | then parseFail (oneChar $
endPos st.pos prf) (Expected ["'---'"] "end of input")
1096 | else Succ0 ({pos := endPos st.pos prf} st) rem @{prf}
1097 | SR (L _ LDocEnd _) rem prf =>
1102 | then parseFail (oneChar $
endPos st.pos prf) (Expected ["'---'"] "'...'")
1104 | let st1 := YS (endPos st.pos prf) st.evs
1106 | Same => weaken $
docSuffix False st1 cs sa
1108 | weaken $
trans (docSuffix False st1 rem (r @{uncons u})) (weaken (uncons u))
1109 | SR (L _ LDocStart _) rem prf =>
1110 | let pM := endPos st.pos prf
1111 | st1 := emit (BS pM (addCol 3 pM)) (DocStart True) ({pos := pM} st)
1113 | Same => weaken $
docStart env st1 cs sa
1115 | weaken $
trans (docStart env st1 rem (r @{uncons u})) (weaken (uncons u))
1116 | SR (L ind LContent tb) rem prf =>
1117 | let pC := endPos st.pos prf
1119 | in if bomStart rem && ind == 0
1121 | Same => weaken $
bomDoc ab env sy st1 cs sa
1123 | weaken $
trans (bomDoc ab env sy st1 rem (r @{uncons u})) (weaken (uncons u))
1124 | else if dirStart rem && ind == 0
1128 | Same => weaken $
dirDoc ab env sy st1 cs sa
1130 | weaken $
trans (dirDoc ab env sy st1 rem (r @{uncons u})) (weaken (uncons u))
1131 | else custom (oneChar pC) TrailingContent
1132 | else if ab && not dirty
1134 | let st2 := emit (oneChar st1.pos) (DocStart False) st1
1136 | Same => weaken $
bareDoc tb env st2 cs sa
1138 | weaken $
trans (bareDoc tb env st2 rem (r @{uncons u})) (weaken (uncons u))
1139 | else custom (oneChar pC) TrailingContent
1143 | dirty = sy || not (null env.handles)
1145 | bomStart : List Char -> Bool
1146 | bomStart ('\xfeff' :: _) = True
1149 | dirStart : List Char -> Bool
1150 | dirStart ('%' :: _) = True
1154 | bomDoc : (ab : Bool) -> TagEnv -> (sawYaml : Bool) -> Rule True YState
1155 | bomDoc ab env sy st ('\xfeff' :: t) (SA r) =
1156 | succT (stream ab env sy ({pos $= incCol} st) t (r @{uncons Same})) @{uncons Same}
1157 | bomDoc _ _ _ st _ _ = eoi
1160 | dirDoc : (ab : Bool) -> TagEnv -> (sawYaml : Bool) -> Rule True YState
1161 | dirDoc ab env sy st cs (SA r) = case dirLine cs of
1163 | let pos2 := endPos st.pos prf
1164 | in case parseDirective env sy ln of
1165 | Left e => custom (BS st.pos pos2) e
1167 | succT (stream ab env2 sy2 (YS pos2 st.evs) rem (r @{prf})) @{prf}
1168 | Fail start errEnd err => Fail0 (boundedErr st.pos start errEnd err)
1172 | docStart : TagEnv -> Rule True YState
1173 | docStart env st ('-' :: '-' :: '-' :: t) (SA r) =
1174 | let IL cnt tbw r2 w := inlineWhite t
1175 | p2 := addCol cnt (addCol 3 st.pos)
1180 | let 0 p3 := trans w (uncons $
uncons $
uncons Same)
1181 | in trans (docTail (YS p2 (emptyScalar p2 st.evs)) [] (r @{p3})) p3
1183 | if isBreak x || x == '#'
1184 | then case skipToContent (x :: xs) of
1185 | SR (L ind LContent tb) r3 prf3 =>
1186 | let 0 pc := trans prf3 (trans w (uncons $
uncons $
uncons Same))
1187 | in case blockNode 0 Nothing tb env noProps (YS (endPos p2 prf3) st.evs) r3 (r @{pc}) of
1190 | let 0 p4 := trans q4 pc
1191 | in trans (docTail st4 r4 (r @{p4})) p4
1194 | let 0 p3 := trans w (uncons $
uncons $
uncons Same)
1195 | in trans (docTail (YS p2 (emptyScalar p2 st.evs)) (x :: xs) (r @{p3})) p3
1197 | let 0 p3 := trans w (uncons $
uncons $
uncons Same)
1198 | in case blockNode 0 (Just 0) tbw env noProps (YS p2 st.evs) (x :: xs) (r @{p3}) of
1201 | let 0 p4 := trans q4 p3
1202 | in trans (docTail st4 r4 (r @{p4})) p4
1203 | docStart env st _ _ = eoi
1207 | bareDoc : (tabSep : Bool) -> TagEnv -> Rule True YState
1208 | bareDoc tabSep env st cs sa@(SA r) = case blockNode 0 Nothing tabSep env noProps st cs sa of
1210 | Succ0 st1 r1 @{q1} => trans (docTail st1 r1 (r @{q1})) q1
1214 | docTail : Rule False YState
1215 | docTail st cs sa@(SA r) = case skipToContent cs of
1216 | SR (L _ LEnd _) rem prf =>
1217 | Succ0 (YS (endPos st.pos prf) (st.evs :< oneChar (DocEnd False) st.pos)) rem @{prf}
1218 | SR (L _ LDocStart _) rem prf =>
1219 | let st1 := emit (oneChar st.pos) (DocEnd False) ({pos := endPos st.pos prf} st)
1221 | Same => stream False defaultEnv False st1 cs sa
1223 | trans (stream False defaultEnv False st1 rem (r @{uncons u})) (weaken (uncons u))
1224 | SR (L _ LDocEnd _) rem prf =>
1225 | let st1 := YS (endPos st.pos prf) st.evs
1227 | Same => weaken $
docSuffix True st1 cs sa
1229 | weaken $
trans (docSuffix True st1 rem (r @{uncons u})) (weaken (uncons u))
1230 | SR (L _ LContent tb) rem prf =>
1231 | custom (oneChar $
endPos st.pos prf) TrailingContent
1235 | docSuffix : (emitEnd : Bool) -> Rule True YState
1236 | docSuffix emitEnd st ('.' :: '.' :: '.' :: t) (SA r) =
1237 | let evs1 := if emitEnd then st.evs :< bounded (DocEnd True) st.pos (addCol 3 st.pos) else st.evs
1238 | st1 := YS (addCol 3 st.pos) evs1
1239 | in case lineEnd False st1.pos t of
1242 | let 0 pp := trans q2 (uncons $
uncons $
uncons Same)
1243 | in succT (stream True defaultEnv False (YS p2 st1.evs) r2 (r @{pp})) @{pp}
1244 | docSuffix _ st _ _ = eoi
1251 | normalize : List Char -> List Char
1252 | normalize ('\r' :: '\n' :: cs) = '\n' :: normalize cs
1253 | normalize ('\r' :: cs) = '\n' :: normalize cs
1254 | normalize (c :: cs) = c :: normalize cs
1260 | normalized : String -> String
1261 | normalized = pack . normalize . unpack
1266 | parseEvents : Origin -> String -> Either (ParseError YErr) (List (Bounded Event))
1268 | let ns := normalized str
1269 | in case stream True defaultEnv False (YS begin [<oneChar StreamStart begin]) (unpack ns) suffixAcc of
1270 | Succ0 st _ => Right (st.evs <>> [oneChar StreamEnd st.pos])
1271 | Fail0 err => Left (toParseError o ns err)