module Bookhound.Format.Parsers.Yaml (yaml, nil, integer, float, bool, string,
list, mapping) where
import Bookhound.Parser (Parser, andThen, check, exactly,
withError)
import Bookhound.ParserCombinators (IsMatch (..), maybeWithin, (<#>), (<|>),
(->>-), (|*), (|+), (|++), (|?))
import Bookhound.Parsers.Char (char, colon, dash, dot, doubleQuote,
hashTag, newLine, question, quote, space,
whiteSpace)
import Bookhound.Parsers.Collections (listOf, mapOf)
import Bookhound.Parsers.Number (double, hexInt, int, octInt)
import Bookhound.Parsers.String (blankLine, blankLines, spaces,
spacesOrTabs, tabs, withinDoubleQuotes,
withinQuotes)
import Bookhound.Format.SyntaxTrees.Yaml (CollectionType (..), YamlExpression (..))
import qualified Bookhound.Parsers.DateTime as Dt
import Data.List (nub)
import qualified Data.Map as Map
yaml :: Parser YamlExpression
yaml :: Parser YamlExpression
yaml = Parser [Char]
normalize forall a. Parser [Char] -> Parser a -> Parser a
`andThen` Int -> Parser YamlExpression
yamlWithIndent (-Int
1)
nil :: Parser YamlExpression
nil :: Parser YamlExpression
nil = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Null"
forall a b. (a -> b) -> a -> b
$ YamlExpression
YamlNull forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall a. IsMatch a => [a] -> Parser a
oneOf [[Char]
"null", [Char]
"Null", [Char]
"NULL"]
integer :: Parser YamlExpression
integer :: Parser YamlExpression
integer = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Integer"
forall a b. (a -> b) -> a -> b
$ Integer -> YamlExpression
YamlInteger forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Integer
hexInt forall a. Parser a -> Parser a -> Parser a
<|> Parser Integer
octInt forall a. Parser a -> Parser a -> Parser a
<|> Parser Integer
int)
float :: Parser YamlExpression
float :: Parser YamlExpression
float = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Float"
forall a b. (a -> b) -> a -> b
$ Double -> YamlExpression
YamlFloat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Double
double
bool :: Parser YamlExpression
bool :: Parser YamlExpression
bool = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Bool"
forall a b. (a -> b) -> a -> b
$ Bool -> YamlExpression
YamlBool forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Bool
True forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall a. IsMatch a => [a] -> Parser a
oneOf [[Char]
"true", [Char]
"True", [Char]
"TRUE"] forall a. Parser a -> Parser a -> Parser a
<|>
Bool
False forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall a. IsMatch a => [a] -> Parser a
oneOf [[Char]
"false", [Char]
"False", [Char]
"FALSE"])
dateTime :: Parser YamlExpression
dateTime :: Parser YamlExpression
dateTime = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml DateTime"
forall a b. (a -> b) -> a -> b
$ ZonedTime -> YamlExpression
YamlDateTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ZonedTime
Dt.dateTime
date :: Parser YamlExpression
date :: Parser YamlExpression
date = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Date"
forall a b. (a -> b) -> a -> b
$ Day -> YamlExpression
YamlDate forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Day
Dt.date
time :: Parser YamlExpression
time :: Parser YamlExpression
time = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Time"
forall a b. (a -> b) -> a -> b
$ TimeOfDay -> YamlExpression
YamlTime forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser TimeOfDay
Dt.time
string :: Int -> Parser YamlExpression
string :: Int -> Parser YamlExpression
string Int
indent = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml String"
forall a b. (a -> b) -> a -> b
$ [Char] -> YamlExpression
YamlString forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser [Char]
text Int
indent
sequential :: Parser a -> Int -> Parser [YamlExpression]
sequential :: forall a. Parser a -> Int -> Parser [YamlExpression]
sequential Parser a
sep Int
indent = Parser [YamlExpression]
listParser
where
listParser :: Parser [YamlExpression]
listParser = forall a. Parser (Int, a) -> Int -> Parser [a]
indentationCheck Parser (Int, YamlExpression)
elemParser Int
indent
elemParser :: Parser (Int, YamlExpression)
elemParser = do Int
n <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Char
space |*)
Parser a
sep forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Char
whiteSpace
YamlExpression
elm <- Int -> Parser YamlExpression
yamlWithIndent Int
n
pure (Int
n, YamlExpression
elm)
list :: Int -> Parser YamlExpression
list :: Int -> Parser YamlExpression
list Int
indent = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Json List"
forall a b. (a -> b) -> a -> b
$ (CollectionType -> [YamlExpression] -> YamlExpression
YamlList CollectionType
Inline forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [YamlExpression]
jsonList)
forall a. Parser a -> Parser a -> Parser a
<|> (CollectionType -> [YamlExpression] -> YamlExpression
YamlList CollectionType
Standard forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [YamlExpression]
yamlList)
where
yamlList :: Parser [YamlExpression]
yamlList = forall a. Parser a -> Int -> Parser [YamlExpression]
sequential Parser Char
dash Int
indent
jsonList :: Parser [YamlExpression]
jsonList = forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser [Char]
spacesOrTabs forall a b. (a -> b) -> a -> b
$ forall a. Parser a -> Parser [a]
listOf forall a b. (a -> b) -> a -> b
$ Int -> Parser YamlExpression
yamlWithIndent (-Int
1)
set :: Int -> Parser YamlExpression
set :: Int -> Parser YamlExpression
set Int
indent = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Set"
forall a b. (a -> b) -> a -> b
$ CollectionType -> [YamlExpression] -> YamlExpression
YamlList CollectionType
Standard forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Eq a => [a] -> [a]
nub forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Parser a -> Int -> Parser [YamlExpression]
sequential Parser Char
question Int
indent
mapping :: Int -> Parser YamlExpression
mapping :: Int -> Parser YamlExpression
mapping Int
indent = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Yaml Mapping"
forall a b. (a -> b) -> a -> b
$ (CollectionType -> Map [Char] YamlExpression -> YamlExpression
YamlMap CollectionType
Inline forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Map [Char] YamlExpression)
jsonMap)
forall a. Parser a -> Parser a -> Parser a
<|> (CollectionType -> Map [Char] YamlExpression -> YamlExpression
YamlMap CollectionType
Standard forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Map [Char] YamlExpression)
yamlMap)
where
yamlMap :: Parser (Map [Char] YamlExpression)
yamlMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [([Char], YamlExpression)]
mapParser
jsonMap :: Parser (Map [Char] YamlExpression)
jsonMap = forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser [Char]
spacesOrTabs forall a b. (a -> b) -> a -> b
$ forall b a c.
Ord b =>
Parser a -> Parser b -> Parser c -> Parser (Map b c)
mapOf Parser Char
colon (Int -> Parser [Char]
text Int
100) forall a b. (a -> b) -> a -> b
$ Int -> Parser YamlExpression
yamlWithIndent (-Int
1)
mapParser :: Parser [([Char], YamlExpression)]
mapParser = forall a. Parser (Int, a) -> Int -> Parser [a]
indentationCheck Parser (Int, ([Char], YamlExpression))
keyValueParser Int
indent
keyValueParser :: Parser (Int, ([Char], YamlExpression))
keyValueParser = do Int
n <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Char
space |*)
[Char]
key <- forall a. Show a => a -> [Char]
show forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Parser YamlExpression
element Int
indent
(Parser [Char]
spacesOrTabs |?)
Parser Char
colon forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Char
whiteSpace
YamlExpression
value <- Int -> Parser YamlExpression
yamlWithIndent Int
n
pure (Int
n, ([Char]
key, YamlExpression
value))
element :: Int -> Parser YamlExpression
element :: Int -> Parser YamlExpression
element Int
indent = forall a. Parser a -> Parser a
exactly (Parser YamlExpression
dateTime forall a. Parser a -> Parser a -> Parser a
<|> Parser YamlExpression
date forall a. Parser a -> Parser a -> Parser a
<|> Parser YamlExpression
time forall a. Parser a -> Parser a -> Parser a
<|> Parser YamlExpression
float forall a. Parser a -> Parser a -> Parser a
<|>
Parser YamlExpression
integer forall a. Parser a -> Parser a -> Parser a
<|> Parser YamlExpression
bool forall a. Parser a -> Parser a -> Parser a
<|> Parser YamlExpression
nil) forall a. Parser a -> Parser a -> Parser a
<|>
Int -> Parser YamlExpression
string Int
indent
container :: Int -> Parser YamlExpression
container :: Int -> Parser YamlExpression
container Int
indent = Int -> Parser YamlExpression
list Int
indent forall a. Parser a -> Parser a -> Parser a
<|> Int -> Parser YamlExpression
mapping Int
indent forall a. Parser a -> Parser a -> Parser a
<|> Int -> Parser YamlExpression
set Int
indent
yamlWithIndent :: Int -> Parser YamlExpression
yamlWithIndent :: Int -> Parser YamlExpression
yamlWithIndent Int
indent = forall a b. Parser a -> Parser b -> Parser b
maybeWithin ((Parser [Char]
blankLine forall a. Parser a -> Parser a -> Parser a
<|> Parser [Char]
comment forall a. Parser a -> Parser a -> Parser a
<|> Parser [Char]
directive forall a. Parser a -> Parser a -> Parser a
<|>
Parser [Char]
docStart forall a. Parser a -> Parser a -> Parser a
<|> Parser [Char]
docEnd) |+)
Parser YamlExpression
yamlValue
where
yamlValue :: Parser YamlExpression
yamlValue = Int -> Parser YamlExpression
container Int
indent forall a. Parser a -> Parser a -> Parser a
<|> forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser [Char]
spacesOrTabs (Int -> Parser YamlExpression
element Int
indent)
comment :: Parser [Char]
comment = Parser Char
hashTag forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (forall a. IsMatch a => Parser a -> Parser a
inverse Parser Char
newLine |+) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Char
newLine
directive :: Parser [Char]
directive = forall a. IsMatch a => a -> Parser a
is [Char]
"%" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (forall a. IsMatch a => Parser a -> Parser a
inverse Parser Char
space forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (forall a. IsMatch a => Parser a -> Parser a
inverse Parser Char
newLine |+)) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Char
newLine
docStart :: Parser [Char]
docStart = Parser Char
dash forall a. Parser a -> Integer -> Parser [a]
<#> Integer
3
docEnd :: Parser [Char]
docEnd = Parser Char
dot forall a. Parser a -> Integer -> Parser [a]
<#> Integer
3
text :: Int -> Parser String
text :: Int -> Parser [Char]
text Int
indent = forall a. Parser a -> Parser a
withinDoubleQuotes (Parser [Char] -> Parser [Char]
quotedParser (forall a. IsMatch a => Parser a -> Parser a
inverse Parser Char
doubleQuote |*)) forall a. Parser a -> Parser a -> Parser a
<|>
forall a. Parser a -> Parser a
withinQuotes (Parser [Char] -> Parser [Char]
quotedParser (forall a. IsMatch a => Parser a -> Parser a
inverse Parser Char
quote |*)) forall a. Parser a -> Parser a -> Parser a
<|>
(forall a. IsMatch a => a -> Parser a
is [Char]
"|" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser [Char]
blankLine forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser [Char] -> Parser (Int, [Char])) -> Parser [Char]
plainTextParser Parser [Char] -> Parser (Int, [Char])
literalLineParser) forall a. Parser a -> Parser a -> Parser a
<|>
(forall a. IsMatch a => a -> Parser a
is [Char]
">" forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser [Char]
blankLine forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser [Char]
spacesOrTabs |?) forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Parser [Char] -> Parser (Int, [Char])) -> Parser [Char]
plainTextParser Parser [Char] -> Parser (Int, [Char])
foldingLineParser) forall a. Parser a -> Parser a -> Parser a
<|>
(Parser [Char] -> Parser (Int, [Char])) -> Parser [Char]
plainTextParser Parser [Char] -> Parser (Int, [Char])
foldingLineParser
where
quotedParser :: Parser [Char] -> Parser [Char]
quotedParser Parser [Char]
parser = forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [Char] -> Parser (Int, [Char])
foldingLineParser Parser [Char]
parser) |*)
plainTextParser :: (Parser [Char] -> Parser (Int, [Char])) -> Parser [Char]
plainTextParser Parser [Char] -> Parser (Int, [Char])
styleParser = Parser Char
allowedStart forall a b.
(ToString a, ToString b) =>
Parser a -> Parser b -> Parser [Char]
->>- Parser [Char]
allowedString forall a b.
(ToString a, ToString b) =>
Parser a -> Parser b -> Parser [Char]
->>-
(forall a. Parser (Int, a) -> Int -> Parser [a]
indentationCheck (Parser [Char] -> Parser (Int, [Char])
styleParser Parser [Char]
allowedString) Int
indent |*)
foldingLineParser :: Parser [Char] -> Parser (Int, [Char])
foldingLineParser Parser [Char]
parser = do [Char]
sep <- ([Char]
"\n" forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Char
newLine forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser [Char]
blankLines) forall a. Parser a -> Parser a -> Parser a
<|> ([Char]
" " forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Char
newLine)
Int
n <- forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser [Char]
tabs forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Char
space |*)
[Char]
str <- Parser [Char]
parser
pure (Int
n, [Char]
sep forall a. Semigroup a => a -> a -> a
<> [Char]
str)
literalLineParser :: Parser [Char] -> Parser (Int, [Char])
literalLineParser Parser [Char]
parser = do [Char]
sep <- forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Char
newLine
Int
n <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser Char
space |*)
[Char]
str <- Parser [Char]
parser
pure (Int
n, [Char]
sep forall a. Semigroup a => a -> a -> a
<> forall a. Int -> a -> [a]
replicate (Int
n forall a. Num a => a -> a -> a
- Int
indent) Char
' ' forall a. Semigroup a => a -> a -> a
<> [Char]
str)
allowedStart :: Parser Char
allowedStart = forall a. IsMatch a => [a] -> Parser a
noneOf forall a b. (a -> b) -> a -> b
$ [Char]
forbiddenChar forall a. Semigroup a => a -> a -> a
<> [Char
'>', Char
'|', Char
':', Char
'!']
allowedString :: Parser [Char]
allowedString = (forall a. IsMatch a => [a] -> Parser a
noneOf [Char]
forbiddenChar |*)
forbiddenChar :: [Char]
forbiddenChar = [Char
'\n', Char
'#', Char
'&', Char
'*', Char
',', Char
'?', Char
'-', Char
':', Char
'[', Char
']', Char
'{', Char
'}']
indentationCheck :: Parser (Int, a) -> Int -> Parser [a]
indentationCheck :: forall a. Parser (Int, a) -> Int -> Parser [a]
indentationCheck Parser (Int, a)
parser Int
indent = ((forall a b. (a, b) -> b
snd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. [Char] -> (a -> Bool) -> Parser a -> Parser a
check [Char]
"indentation"
(\(Int
n, a
_) -> Int
n forall a. Ord a => a -> a -> Bool
> Int
indent) Parser (Int, a)
parser) |+)
normalize :: Parser String
normalize :: Parser [Char]
normalize = forall a. [Char] -> Parser a -> Parser a
withError [Char]
"Normalize Yaml"
forall a b. (a -> b) -> a -> b
$ (Parser [Char]
parserActions forall a b.
(ToString a, ToString b) =>
Parser a -> Parser b -> Parser [Char]
->>- Parser [Char]
normalize) forall a. Parser a -> Parser a -> Parser a
<|> (Parser Char
char |*)
where
parserActions :: Parser [Char]
parserActions = Parser [Char]
spreadDashes forall a. Parser a -> Parser a -> Parser a
<|>
Parser [Char]
spreadDashKey forall a. Parser a -> Parser a -> Parser a
<|>
Parser [Char]
spreadKeyDash forall a. Parser a -> Parser a -> Parser a
<|>
Parser [Char]
next
next :: Parser [Char]
next = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Char
char
spreadDashes :: Parser [Char]
spreadDashes = (forall a. Semigroup a => a -> a -> a
(<>) [Char]
"- ") forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> [Char]
genDashes forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Int, Int)
dashesParser
genDashes :: (Int, Int) -> [Char]
genDashes (Int
offset, Int
n) = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\Int
x -> [Char]
"- " forall a. Semigroup a => a -> a -> a
<> forall a. Int -> a -> [a]
replicate (Int
offset forall a. Num a => a -> a -> a
+ Int
2 forall a. Num a => a -> a -> a
* Int
x) Char
' ')
[Int
1 .. Int
n forall a. Num a => a -> a -> a
- Int
1]
dashesParser :: Parser (Int, Int)
dashesParser = do Int
offset <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser [Char]
spaces |?)
Int
n <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Parser Char
dash forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser [Char]
spacesOrTabs) |++)
pure (Int
offset, Int
n)
spreadDashKey :: Parser [Char]
spreadDashKey = (\(Int
offset, [Char]
key) -> forall a. Int -> a -> [a]
replicate Int
offset Char
' ' forall a. Semigroup a => a -> a -> a
<> [Char]
"- " forall a. Semigroup a => a -> a -> a
<>
forall a. Int -> a -> [a]
replicate (Int
offset forall a. Num a => a -> a -> a
+ Int
2) Char
' ' forall a. Semigroup a => a -> a -> a
<> [Char]
key forall a. Semigroup a => a -> a -> a
<> [Char]
": ")
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Int, [Char])
dashKeyParser
dashKeyParser :: Parser (Int, [Char])
dashKeyParser = do Int
offset <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser [Char]
spaces |?)
Parser Char
dash forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser [Char]
spacesOrTabs
[Char]
key <- Int -> Parser [Char]
text Int
100 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser [Char]
spacesOrTabs Parser Char
colon
pure (Int
offset, [Char]
key)
spreadKeyDash :: Parser [Char]
spreadKeyDash = (\(Int
offset, [Char]
key) -> forall a. Int -> a -> [a]
replicate Int
offset Char
' ' forall a. Semigroup a => a -> a -> a
<> [Char]
key forall a. Semigroup a => a -> a -> a
<> [Char]
": " forall a. Semigroup a => a -> a -> a
<>
forall a. Int -> a -> [a]
replicate (Int
offset forall a. Num a => a -> a -> a
+ Int
2) Char
' ' forall a. Semigroup a => a -> a -> a
<> [Char]
"- ")
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (Int, [Char])
keyDashParser
keyDashParser :: Parser (Int, [Char])
keyDashParser = do Int
offset <- forall (t :: * -> *) a. Foldable t => t a -> Int
length forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser [Char]
spaces |?)
[Char]
key <- Int -> Parser [Char]
text Int
100 forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall a b. Parser a -> Parser b -> Parser b
maybeWithin Parser [Char]
spacesOrTabs Parser Char
colon
Parser Char
dash forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser [Char]
spacesOrTabs
pure (Int
offset, [Char]
key)