{-|
Module      : Text.Jira.Parser.Block
Copyright   : © 2019–2021 Albert Krewinkel
License     : MIT

Maintainer  : Albert Krewinkel <tarleb@zeitkraut.de>
Stability   : alpha
Portability : portable

Parse Jira wiki blocks.
-}
module Text.Jira.Parser.Block
  ( block
    -- * Parsers for block types
  , blockQuote
  , code
  , color
  , header
  , horizontalRule
  , list
  , noformat
  , panel
  , para
  , table
  ) where

import Control.Monad (guard, void, when)
import Data.Char (digitToInt)
import Data.Text (pack)
import Text.Jira.Markup
import Text.Jira.Parser.Core
import Text.Jira.Parser.Inline
import Text.Jira.Parser.Shared (colorName)
import Text.Parsec

-- | Parses any block element.
block :: JiraParser Block
block :: JiraParser Block
block = [JiraParser Block] -> JiraParser Block
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice
  [ JiraParser Block
header
  , JiraParser Block
list
  , JiraParser Block
table
  , JiraParser Block
blockQuote
  , JiraParser Block
horizontalRule
  , JiraParser Block
code
  , JiraParser Block
noformat
  , JiraParser Block
panel
  , JiraParser Block
color
  , JiraParser Block
para
  ] JiraParser Block
-> ParsecT Text ParserState Identity () -> JiraParser Block
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text ParserState Identity ()
skipWhitespace

-- | Parses a paragraph into a @Para@.
para :: JiraParser Block
para :: JiraParser Block
para = (JiraParser Block -> String -> JiraParser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"para") (JiraParser Block -> JiraParser Block)
-> (JiraParser Block -> JiraParser Block)
-> JiraParser Block
-> JiraParser Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  Bool
isInList <- ParserState -> Bool
stateInList (ParserState -> Bool)
-> ParsecT Text ParserState Identity ParserState
-> ParsecT Text ParserState Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  Bool
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
isInList (ParsecT Text ParserState Identity ()
 -> ParsecT Text ParserState Identity ())
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall a b. (a -> b) -> a -> b
$ do
    ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall a.
Show a =>
JiraParser a -> ParsecT Text ParserState Identity ()
notFollowedBy' ParsecT Text ParserState Identity ()
blankline
    JiraParser Block -> ParsecT Text ParserState Identity ()
forall a.
Show a =>
JiraParser a -> ParsecT Text ParserState Identity ()
notFollowedBy' JiraParser Block
horizontalRule
  [Inline] -> Block
Para ([Inline] -> Block) -> ([Inline] -> [Inline]) -> [Inline] -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> [Inline]
normalizeInlines ([Inline] -> Block)
-> ParsecT Text ParserState Identity [Inline] -> JiraParser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity Inline
-> ParsecT Text ParserState Identity [Inline]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Text ParserState Identity Inline
inline

-- | Parses a header line into a @Header@.
header :: JiraParser Block
header :: JiraParser Block
header = (JiraParser Block -> String -> JiraParser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"header") (JiraParser Block -> JiraParser Block)
-> (JiraParser Block -> JiraParser Block)
-> JiraParser Block
-> JiraParser Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  Int
level <- Char -> Int
digitToInt (Char -> Int)
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'h' ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"123456" ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'.')
  [Inline]
content <- ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
' ') ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Inline
inline ParsecT Text ParserState Identity Inline
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity [Inline]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` (ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof)
  Block -> JiraParser Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> JiraParser Block) -> Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ Int -> [Inline] -> Block
Header Int
level ([Inline] -> [Inline]
normalizeInlines [Inline]
content)

-- | Parses a list into @List@.
list :: JiraParser Block
list :: JiraParser Block
list = (JiraParser Block -> String -> JiraParser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"list") (JiraParser Block -> JiraParser Block)
-> (JiraParser Block -> JiraParser Block)
-> JiraParser Block
-> JiraParser Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  Bool -> ParsecT Text ParserState Identity ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT Text ParserState Identity ())
-> (ParserState -> Bool)
-> ParserState
-> ParsecT Text ParserState Identity ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Bool) -> (ParserState -> Bool) -> ParserState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParserState -> Bool
stateInList (ParserState -> ParsecT Text ParserState Identity ())
-> ParsecT Text ParserState Identity ParserState
-> ParsecT Text ParserState Identity ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ParsecT Text ParserState Identity ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  (Bool -> ParserState -> ParserState)
-> JiraParser Block -> JiraParser Block
forall a.
(Bool -> ParserState -> ParserState)
-> JiraParser a -> JiraParser a
withStateFlag (\Bool
b ParserState
st -> ParserState
st { stateInList :: Bool
stateInList = Bool
b }) (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$
    Int -> JiraParser Block
listAtDepth Int
0
  where
    listAtDepth :: Int -> JiraParser Block
    listAtDepth :: Int -> JiraParser Block
listAtDepth Int
depth = JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ Int -> ParsecT Text ParserState Identity ()
atDepth Int
depth ParsecT Text ParserState Identity ()
-> JiraParser Block -> JiraParser Block
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> JiraParser Block
listAtDepth' Int
depth

    listAtDepth' :: Int -> JiraParser Block
    listAtDepth' :: Int -> JiraParser Block
listAtDepth' Int
depth = JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
      Char
bulletChar <- ParsecT Text ParserState Identity Char
anyBulletMarker
      [Block]
first <- Int -> JiraParser [Block]
firstItemAtDepth Int
depth
      [[Block]]
rest  <- JiraParser [Block] -> ParsecT Text ParserState Identity [[Block]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser [Block] -> JiraParser [Block])
-> JiraParser [Block] -> JiraParser [Block]
forall a b. (a -> b) -> a -> b
$ Int -> ParsecT Text ParserState Identity Char -> JiraParser [Block]
listItemAtDepth Int
depth (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
bulletChar))
      Block -> JiraParser Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> JiraParser Block) -> Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ ListStyle -> [[Block]] -> Block
List (Char -> ListStyle
style Char
bulletChar) ([Block]
first[Block] -> [[Block]] -> [[Block]]
forall a. a -> [a] -> [a]
:[[Block]]
rest)

    style :: Char -> ListStyle
    style :: Char -> ListStyle
style Char
c = case Char
c of
      Char
'-' -> ListStyle
SquareBullets
      Char
'*' -> ListStyle
CircleBullets
      Char
'#' -> ListStyle
Enumeration
      Char
_   -> String -> ListStyle
forall a. HasCallStack => String -> a
error (String
"the impossible happened: unknown style for bullet " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c])

    atDepth :: Int -> JiraParser ()
    atDepth :: Int -> ParsecT Text ParserState Identity ()
atDepth Int
depth = ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text ParserState Identity ()
 -> ParsecT Text ParserState Identity ())
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall a b. (a -> b) -> a -> b
$ ParsecT Text ParserState Identity ()
skipSpaces ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Int
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
Int -> ParsecT s u m a -> ParsecT s u m [a]
count Int
depth ParsecT Text ParserState Identity Char
anyBulletMarker

    firstItemAtDepth :: Int -> JiraParser [Block]
    firstItemAtDepth :: Int -> JiraParser [Block]
firstItemAtDepth Int
depth = JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser [Block] -> JiraParser [Block])
-> JiraParser [Block] -> JiraParser [Block]
forall a b. (a -> b) -> a -> b
$ Int -> JiraParser [Block]
listContent (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) JiraParser [Block] -> JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
      do
        [Block]
blocks <- Int -> JiraParser [Block]
nonListContent Int
depth
        [Block]
nestedLists <- JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser [Block] -> JiraParser [Block])
-> (JiraParser Block -> JiraParser [Block])
-> JiraParser Block
-> JiraParser [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JiraParser Block -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (JiraParser Block -> JiraParser [Block])
-> JiraParser Block -> JiraParser [Block]
forall a b. (a -> b) -> a -> b
$ Int -> JiraParser Block
listAtDepth (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        [Block] -> JiraParser [Block]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Block] -> JiraParser [Block]) -> [Block] -> JiraParser [Block]
forall a b. (a -> b) -> a -> b
$ [Block]
blocks [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block]
nestedLists

    listItemAtDepth :: Int -> JiraParser Char -> JiraParser [Block]
    listItemAtDepth :: Int -> ParsecT Text ParserState Identity Char -> JiraParser [Block]
listItemAtDepth Int
depth ParsecT Text ParserState Identity Char
bulletChar = Int -> ParsecT Text ParserState Identity ()
atDepth Int
depth ParsecT Text ParserState Identity ()
-> JiraParser [Block] -> JiraParser [Block]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
      (JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text ParserState Identity Char
bulletChar ParsecT Text ParserState Identity Char
-> JiraParser [Block] -> JiraParser [Block]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> JiraParser [Block]
nonListContent Int
depth) JiraParser [Block] -> JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
       JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text ParserState Identity Char
anyBulletMarker ParsecT Text ParserState Identity Char
-> JiraParser [Block] -> JiraParser [Block]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> JiraParser [Block]
listContent Int
depth))

    listContent :: Int -> JiraParser [Block]
    listContent :: Int -> JiraParser [Block]
listContent Int
depth = do
        Block
first <- Int -> JiraParser Block
listAtDepth' Int
depth
        [Block]
rest <- JiraParser Block -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Int -> JiraParser Block
listAtDepth Int
depth)
        [Block] -> JiraParser [Block]
forall (m :: * -> *) a. Monad m => a -> m a
return (Block
first Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
rest)

    anyBulletMarker :: JiraParser Char
    anyBulletMarker :: ParsecT Text ParserState Identity Char
anyBulletMarker = String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"*-#"

    nonListContent :: Int -> JiraParser [Block]
    nonListContent :: Int -> JiraParser [Block]
nonListContent Int
depth = JiraParser [Block] -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser [Block] -> JiraParser [Block])
-> JiraParser [Block] -> JiraParser [Block]
forall a b. (a -> b) -> a -> b
$
      let nonListBlock :: JiraParser Block
nonListBlock = do
            ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
forall a.
Show a =>
JiraParser a -> ParsecT Text ParserState Identity ()
notFollowedBy' (ParsecT Text ParserState Identity ()
skipSpaces ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"#-*"))
            JiraParser Block
block
      in Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
' ' ParsecT Text ParserState Identity Char
-> JiraParser [Block] -> JiraParser [Block]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> do
        Block
first   <- JiraParser Block
block
        [Block]
nonList <- JiraParser Block -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many JiraParser Block
nonListBlock
        [Block]
lists   <- JiraParser Block -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Int -> JiraParser Block
listAtDepth (Int
depth Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1))
        [Block] -> JiraParser [Block]
forall (m :: * -> *) a. Monad m => a -> m a
return (Block
first Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
nonList [Block] -> [Block] -> [Block]
forall a. [a] -> [a] -> [a]
++ [Block]
lists)

-- | Parses a table into a @Table@ element.
table :: JiraParser Block
table :: JiraParser Block
table = do
  Bool -> ParsecT Text ParserState Identity ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT Text ParserState Identity ())
-> (ParserState -> Bool)
-> ParserState
-> ParsecT Text ParserState Identity ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Bool
not (Bool -> Bool) -> (ParserState -> Bool) -> ParserState -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParserState -> Bool
stateInTable (ParserState -> ParsecT Text ParserState Identity ())
-> ParsecT Text ParserState Identity ParserState
-> ParsecT Text ParserState Identity ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ParsecT Text ParserState Identity ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  (Bool -> ParserState -> ParserState)
-> JiraParser Block -> JiraParser Block
forall a.
(Bool -> ParserState -> ParserState)
-> JiraParser a -> JiraParser a
withStateFlag (\Bool
b ParserState
st -> ParserState
st { stateInTable :: Bool
stateInTable = Bool
b }) (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$
    [Row] -> Block
Table ([Row] -> Block)
-> ParsecT Text ParserState Identity [Row] -> JiraParser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity Row
-> ParsecT Text ParserState Identity [Row]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Text ParserState Identity Row
row

-- | Parses a table row.
row :: JiraParser Row
row :: ParsecT Text ParserState Identity Row
row = ([Cell] -> Row)
-> ParsecT Text ParserState Identity [Cell]
-> ParsecT Text ParserState Identity Row
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Cell] -> Row
Row (ParsecT Text ParserState Identity [Cell]
 -> ParsecT Text ParserState Identity Row)
-> (ParsecT Text ParserState Identity [Cell]
    -> ParsecT Text ParserState Identity [Cell])
-> ParsecT Text ParserState Identity [Cell]
-> ParsecT Text ParserState Identity Row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Text ParserState Identity [Cell]
-> ParsecT Text ParserState Identity [Cell]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text ParserState Identity [Cell]
 -> ParsecT Text ParserState Identity Row)
-> ParsecT Text ParserState Identity [Cell]
-> ParsecT Text ParserState Identity Row
forall a b. (a -> b) -> a -> b
$
  ParsecT Text ParserState Identity Cell
-> ParsecT Text ParserState Identity [Cell]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Text ParserState Identity Cell
cell ParsecT Text ParserState Identity [Cell]
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity [Cell]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
" |") ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline)

-- | Parses a table cell.
cell :: JiraParser Cell
cell :: ParsecT Text ParserState Identity Cell
cell = ParsecT Text ParserState Identity Cell
-> ParsecT Text ParserState Identity Cell
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text ParserState Identity Cell
 -> ParsecT Text ParserState Identity Cell)
-> ParsecT Text ParserState Identity Cell
-> ParsecT Text ParserState Identity Cell
forall a b. (a -> b) -> a -> b
$ do
  [Block] -> Cell
mkCell <- JiraParser ([Block] -> Cell)
cellStart
  [Block]
bs     <- JiraParser Block -> JiraParser [Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many JiraParser Block
block
  Cell -> ParsecT Text ParserState Identity Cell
forall (m :: * -> *) a. Monad m => a -> m a
return (Cell -> ParsecT Text ParserState Identity Cell)
-> Cell -> ParsecT Text ParserState Identity Cell
forall a b. (a -> b) -> a -> b
$ [Block] -> Cell
mkCell [Block]
bs

-- | Parses the beginning of a table cell and returns a function which
-- constructs a cell of the appropriate type when given the cell's content.
cellStart :: JiraParser ([Block] -> Cell)
cellStart :: JiraParser ([Block] -> Cell)
cellStart = JiraParser ([Block] -> Cell) -> JiraParser ([Block] -> Cell)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try
  (JiraParser ([Block] -> Cell) -> JiraParser ([Block] -> Cell))
-> JiraParser ([Block] -> Cell) -> JiraParser ([Block] -> Cell)
forall a b. (a -> b) -> a -> b
$  ParsecT Text ParserState Identity ()
skipSpaces
  ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'
  ParsecT Text ParserState Identity Char
-> JiraParser ([Block] -> Cell) -> JiraParser ([Block] -> Cell)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ([Block] -> Cell)
-> JiraParser ([Block] -> Cell) -> JiraParser ([Block] -> Cell)
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [Block] -> Cell
BodyCell ([Block] -> Cell
HeaderCell ([Block] -> Cell)
-> ParsecT Text ParserState Identity String
-> JiraParser ([Block] -> Cell)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'|'))
  JiraParser ([Block] -> Cell)
-> ParsecT Text ParserState Identity ()
-> JiraParser ([Block] -> Cell)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text ParserState Identity ()
skipSpaces
  JiraParser ([Block] -> Cell)
-> ParsecT Text ParserState Identity ()
-> JiraParser ([Block] -> Cell)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall a.
Show a =>
JiraParser a -> ParsecT Text ParserState Identity ()
notFollowedBy' ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline

-- | Parses a code block into a @Code@ element.
code :: JiraParser Block
code :: JiraParser Block
code = JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  (Maybe Text
langName, [Parameter]
params) <- String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{code" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
parameters ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}' ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text ParserState Identity ()
blankline
  let lang :: Language
lang = Language -> (Text -> Language) -> Maybe Text -> Language
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Language
defaultLanguage Text -> Language
Language Maybe Text
langName
  String
content <- ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{code}" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity ()
blankline)
  Block -> JiraParser Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> JiraParser Block) -> Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ Language -> [Parameter] -> Text -> Block
Code Language
lang [Parameter]
params (String -> Text
pack String
content)
  where
    defaultLanguage :: Language
defaultLanguage = Text -> Language
Language (String -> Text
pack String
"java")

-- | Parses a block quote into a @'Quote'@ element.
blockQuote :: JiraParser Block
blockQuote :: JiraParser Block
blockQuote = JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ JiraParser Block
singleLineBq JiraParser Block -> JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> JiraParser Block
multiLineBq
  where
    singleLineBq :: JiraParser Block
singleLineBq = [Block] -> Block
BlockQuote ([Block] -> Block) -> ([Inline] -> [Block]) -> [Inline] -> Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:[]) (Block -> [Block]) -> ([Inline] -> Block) -> [Inline] -> [Block]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> Block
Para ([Inline] -> Block)
-> ParsecT Text ParserState Identity [Inline] -> JiraParser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                   (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"bq." ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
' ') ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*>
                    ParsecT Text ParserState Identity Inline
inline ParsecT Text ParserState Identity Inline
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity [Inline]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` (ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof))
    multiLineBq :: JiraParser Block
multiLineBq = [Block] -> Block
BlockQuote ([Block] -> Block) -> JiraParser [Block] -> JiraParser Block
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                  (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{quote}"
                   ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Text ParserState Identity ()
blankline
                   ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
' ')
                   ParsecT Text ParserState Identity ()
-> JiraParser [Block] -> JiraParser [Block]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> JiraParser Block
block JiraParser Block
-> ParsecT Text ParserState Identity String -> JiraParser [Block]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{quote}"))

-- | Parses four consecutive hyphens as @'HorizontalRule'@.
horizontalRule :: JiraParser Block
horizontalRule :: JiraParser Block
horizontalRule = Block
HorizontalRule Block -> ParsecT Text ParserState Identity () -> JiraParser Block
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
  ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"----" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity ()
blankline)

-- | Parses a preformatted text into a @NoFormat@ element.
noformat :: JiraParser Block
noformat :: JiraParser Block
noformat = JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  (Maybe Text
_, [Parameter]
params) <- String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{noformat" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
parameters ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
  ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline
  String
content <- ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{noformat}" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Text ParserState Identity ()
blankline)
  Block -> JiraParser Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> JiraParser Block) -> Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ [Parameter] -> Text -> Block
NoFormat [Parameter]
params (String -> Text
pack String
content)

-- | Parses a preformatted text into a @NoFormat@ element.
panel :: JiraParser Block
panel :: JiraParser Block
panel = JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  (Maybe Text
_, [Parameter]
params) <- String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{panel" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
parameters ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}' ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
newline
  [Block]
content <- JiraParser Block
block JiraParser Block
-> ParsecT Text ParserState Identity () -> JiraParser [Block]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{panel}" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity ()
blankline)
  Block -> JiraParser Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> JiraParser Block) -> Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ [Parameter] -> [Block] -> Block
Panel [Parameter]
params [Block]
content

-- | Parses colored text into a @'Color'@ element.
color :: JiraParser Block
color :: JiraParser Block
color= JiraParser Block -> JiraParser Block
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser Block -> JiraParser Block)
-> JiraParser Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ do
  String
name <- String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{color:" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity String
forall u. Parsec Text u String
colorName ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}'
  [Block]
content <- JiraParser Block
block JiraParser Block
-> ParsecT Text ParserState Identity () -> JiraParser [Block]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
`manyTill` ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text ParserState Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{color}" ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity ()
blankline)
  Block -> JiraParser Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> JiraParser Block) -> Block -> JiraParser Block
forall a b. (a -> b) -> a -> b
$ ColorName -> [Block] -> Block
Color (Text -> ColorName
ColorName (Text -> ColorName) -> Text -> ColorName
forall a b. (a -> b) -> a -> b
$ String -> Text
pack String
name) [Block]
content

-- | Skip whitespace till we reach the next block
skipWhitespace :: JiraParser ()
skipWhitespace :: ParsecT Text ParserState Identity ()
skipWhitespace = ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT Text ParserState Identity ()
 -> ParsecT Text ParserState Identity ())
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall a b. (a -> b) -> a -> b
$ do
  Bool
isInList  <- ParserState -> Bool
stateInList  (ParserState -> Bool)
-> ParsecT Text ParserState Identity ParserState
-> ParsecT Text ParserState Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  Bool
isInTable <- ParserState -> Bool
stateInTable (ParserState -> Bool)
-> ParsecT Text ParserState Identity ParserState
-> ParsecT Text ParserState Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  case (Bool
isInList, Bool
isInTable) of
    (Bool
True, Bool
_) -> ParsecT Text ParserState Identity ()
blankline
    (Bool
_, Bool
True) -> ParsecT Text ParserState Identity ()
skipSpaces
    (Bool, Bool)
_         -> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Text ParserState Identity ()
blankline