    {-# LANGUAGE CPP #-}
    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE TupleSections #-}
    {-|
    Module      : Text.Jira.Parser.Inline
    Copyright   : © 2019–2023 Albert Krewinkel
    License     : MIT

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

    Parse Jira wiki inline markup.
    -}
    module Text.Jira.Parser.Inline
      ( inline
        -- * Inline component parsers
      , anchor
      , autolink
      , citation
      , colorInline
      , dash
      , emoji
      , entity
      , image
      , linebreak
      , link
      , monospaced
      , specialChar
      , str
      , styled
      , whitespace
        -- * Constants
      , specialChars
      ) where

    import Control.Monad (guard, void)
    import Data.Char (isAlphaNum, isAscii, isPunctuation, isSpace, ord)
    #if !MIN_VERSION_base(4,13,0)
    import Data.Monoid ((<>), All (..))
    #else
    import Data.Monoid (All (..))
    #endif
    import Data.Text (append, pack)
    import Text.Jira.Markup
    import Text.Jira.Parser.Core
    import Text.Jira.Parser.Shared
    import Text.Parsec

    -- | Parses any inline element.
    inline :: JiraParser Inline
    inline :: JiraParser Inline
    inline = JiraParser [Char] -> JiraParser ()
    forall a. Show a => JiraParser a -> JiraParser ()
    notFollowedBy' JiraParser [Char]
    forall {u}. ParsecT Text u Identity [Char]
    blockEnd JiraParser () -> JiraParser Inline -> JiraParser Inline
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> [JiraParser Inline] -> JiraParser Inline
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ JiraParser Inline
    whitespace
      , JiraParser Inline
    emoji
      , JiraParser Inline
    dash
      , JiraParser Inline
    autolink
      , JiraParser Inline
    str
      , JiraParser Inline
    linebreak
      , JiraParser Inline
    link
      , JiraParser Inline
    image
      , JiraParser Inline
    styled
      , JiraParser Inline
    colorInline
      , JiraParser Inline
    monospaced
      , JiraParser Inline
    anchor
      , JiraParser Inline
    citation
      , JiraParser Inline
    entity
      , JiraParser Inline
    specialChar
      ] JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "inline"
      where
        blockEnd :: ParsecT Text u Identity [Char]
    blockEnd = Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '{' ParsecT Text u Identity Char
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> [ParsecT Text u Identity [Char]] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice (([Char] -> ParsecT Text u Identity [Char])
    -> [[Char]] -> [ParsecT Text u Identity [Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [[Char]]
    blockNames) ParsecT Text u Identity [Char]
    -> ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '}'

    -- | Characters which, depending on context, can have a special meaning.
    specialChars :: String
    specialChars :: [Char]
    specialChars = [Char]
    "_+-*^~|[]{}(?!&\\:;"

    -- | Parses an in-paragraph newline as a @Linebreak@ element. Both newline
    -- characters and double-backslash are recognized as line-breaks.
    linebreak :: JiraParser Inline
    linebreak :: JiraParser Inline
    linebreak = (JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "linebreak") (JiraParser Inline -> JiraParser Inline)
    -> (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline
    -> JiraParser Inline
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
      Bool -> JiraParser ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> JiraParser ())
    -> (ParserState -> Bool) -> ParserState -> JiraParser ()
    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
    stateInMarkup (ParserState -> JiraParser ())
    -> ParsecT Text ParserState Identity ParserState -> JiraParser ()
    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
      [JiraParser ()] -> JiraParser ()
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice [ ParsecT Text ParserState Identity Char -> JiraParser ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (ParsecT Text ParserState Identity Char -> JiraParser ())
    -> ParsecT Text ParserState Identity Char -> JiraParser ()
    forall a b. (a -> b) -> a -> b
    $ ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    newline ParsecT Text ParserState Identity Char
    -> JiraParser () -> ParsecT Text ParserState Identity Char
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* JiraParser () -> JiraParser ()
    forall a. Show a => JiraParser a -> JiraParser ()
    notFollowedBy' JiraParser ()
    endOfPara
             , JiraParser [Char] -> JiraParser ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void (JiraParser [Char] -> JiraParser ())
    -> JiraParser [Char] -> JiraParser ()
    forall a b. (a -> b) -> a -> b
    $ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "\\\\" JiraParser [Char] -> JiraParser () -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Text ParserState Identity Char -> JiraParser ()
    forall a. Show a => JiraParser a -> JiraParser ()
    notFollowedBy' (Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '\\')
             ]
      JiraParser ()
    updateLastSpcPos
      Inline -> JiraParser Inline
    forall a. a -> ParsecT Text ParserState Identity a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Inline
    Linebreak

    -- | Parses whitespace and return a @Space@ element.
    whitespace :: JiraParser Inline
    whitespace :: JiraParser Inline
    whitespace = Inline
    Space Inline -> JiraParser () -> JiraParser Inline
    forall a b.
    a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ ParsecT Text ParserState Identity Char -> JiraParser ()
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m ()
    skipMany1 (Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ' ') JiraParser Inline -> JiraParser () -> JiraParser Inline
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* JiraParser ()
    updateLastSpcPos
      JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "whitespace"

    -- | Parses a simple, markup-less string into a @Str@ element.
    str :: JiraParser Inline
    str :: JiraParser Inline
    str = Text -> Inline
    Str (Text -> Inline) -> ([[Char]] -> Text) -> [[Char]] -> Inline
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack ([Char] -> Text) -> ([[Char]] -> [Char]) -> [[Char]] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Char]] -> [Char]
    forall a. Monoid a => [a] -> a
    mconcat
      ([[Char]] -> Inline)
    -> ParsecT Text ParserState Identity [[Char]] -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> JiraParser [Char] -> ParsecT Text ParserState Identity [[Char]]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 (JiraParser [Char]
    alphaNums JiraParser [Char] -> JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> JiraParser [Char]
    forall {u}. ParsecT Text u Identity [Char]
    otherNonSpecialChars)
      JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "string"
      where
        nonStrChars :: [Char]
    nonStrChars = [Char]
    " \n" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    specialChars
        alphaNums :: JiraParser [Char]
    alphaNums = ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    alphaNum JiraParser [Char] -> JiraParser () -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* JiraParser ()
    updateLastStrPos
        otherNonSpecialChars :: ParsecT Text u Identity [Char]
    otherNonSpecialChars = ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 (ParsecT Text u Identity Char -> ParsecT Text u Identity [Char])
    -> ((Char -> Bool) -> ParsecT Text u Identity Char)
    -> (Char -> Bool)
    -> ParsecT Text u Identity [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool) -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    (Char -> Bool) -> ParsecT s u m Char
    satisfy ((Char -> Bool) -> ParsecT Text u Identity [Char])
    -> (Char -> Bool) -> ParsecT Text u Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ \Char
    c ->
          Bool -> Bool
    not (Char -> Bool
    isAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> [Char] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Char]
    nonStrChars)

    -- | Parses an HTML entity into an @'Entity'@ element.
    entity :: JiraParser Inline
    entity :: JiraParser Inline
    entity = Text -> Inline
    Entity (Text -> Inline) -> ([Char] -> Text) -> [Char] -> Inline
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack
      ([Char] -> Inline) -> JiraParser [Char] -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (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 [Char] -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> (JiraParser [Char]
    forall {u}. ParsecT Text u Identity [Char]
    numerical JiraParser [Char] -> JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> JiraParser [Char]
    forall {u}. ParsecT Text u Identity [Char]
    named) JiraParser [Char]
    -> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    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
    ';')
      where
        numerical :: ParsecT Text u Identity [Char]
    numerical = (:) (Char -> [Char] -> [Char])
    -> ParsecT Text u Identity Char
    -> ParsecT Text u Identity ([Char] -> [Char])
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '#' ParsecT Text u Identity ([Char] -> [Char])
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall a b.
    ParsecT Text u Identity (a -> b)
    -> ParsecT Text u Identity a -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT Text u Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    digit
        named :: ParsecT Text u Identity [Char]
    named = ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT Text u Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    letter

    -- | Parses textual representation of an icon into an @'Emoji'@ element.
    emoji :: JiraParser Inline
    emoji :: JiraParser Inline
    emoji = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (Icon -> Inline
    Emoji (Icon -> Inline)
    -> ParsecT Text ParserState Identity Icon -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Text ParserState Identity Icon
    forall u. Parsec Text u Icon
    icon JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "emoji")

    -- | Parses ASCII representation of en-dash or em-dash.
    dash :: JiraParser Inline
    dash :: JiraParser Inline
    dash = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
      Bool -> JiraParser ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> JiraParser ())
    -> ParsecT Text ParserState Identity Bool -> JiraParser ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< ParsecT Text ParserState Identity Bool
    notAfterString
      _ <- [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "--"
      choice [ Str "—" <$ char '-'   -- em dash
             , pure (Str "–")          -- en dash
             ] <* lookAhead (void (char ' ') <|> eof)

    -- | Parses a special character symbol as a 'SpecialChar'.
    specialChar :: JiraParser Inline
    specialChar :: JiraParser Inline
    specialChar = Char -> Inline
    SpecialChar (Char -> Inline)
    -> ParsecT Text ParserState Identity Char -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (ParsecT Text ParserState Identity Char
    forall {u}. ParsecT Text u Identity Char
    backslash ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> ParsecT Text ParserState Identity Char
    forall {u}. ParsecT Text u Identity Char
    escapedChar ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> ParsecT Text ParserState Identity Char
    plainSpecialChar)
      JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "special char"
      where
        -- backslash before an icon-sequence that's not an emoji does *not*
        -- work as an escape character.
        backslash :: ParsecT Text u Identity Char
    backslash = ParsecT Text u Identity Char -> ParsecT Text u Identity Char
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '\\' ParsecT Text u Identity Char
    -> ParsecT Text u Identity Char -> ParsecT Text u Identity Char
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* ParsecT Text u Identity Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m a
    lookAhead (Parsec Text u Icon
    forall u. Parsec Text u Icon
    icon' Parsec Text u Icon
    -> ParsecT Text u Identity Char -> ParsecT Text u Identity Char
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text u Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    alphaNum))

        escapedChar :: ParsecT Text u Identity Char
    escapedChar = ParsecT Text u Identity Char -> ParsecT Text u Identity Char
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '\\' ParsecT Text u Identity Char
    -> ParsecT Text u Identity Char -> ParsecT Text u Identity Char
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> (Char -> Bool) -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    (Char -> Bool) -> ParsecT s u m Char
    satisfy Char -> Bool
    isPunctuation)

        plainSpecialChar :: ParsecT Text ParserState Identity Char
    plainSpecialChar = do
          inTablePred <- do
            b <- 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
            return $ if b then All . (/= '|') else mempty
          inLinkPred  <- do
            b <- stateInLink  <$> getState
            return $ if b then All . (`notElem` ("]^|\n" :: String)) else mempty
          oneOf $ filter (getAll . (inTablePred <> inLinkPred)) specialChars

    --
    -- Anchors, links and images
    --

    -- | Parses an anchor into an @Anchor@ element.
    anchor :: JiraParser Inline
    anchor :: JiraParser Inline
    anchor = Text -> Inline
    Anchor (Text -> Inline) -> ([Char] -> Text) -> [Char] -> Inline
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack ([Char] -> Text) -> ([Char] -> [Char]) -> [Char] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Char -> Bool) -> [Char] -> [Char]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    ' ')
      ([Char] -> Inline) -> JiraParser [Char] -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try ([Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "{anchor:" JiraParser [Char] -> JiraParser [Char] -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    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
    noneOf [Char]
    "\n" ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    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` Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '}')

    -- | Parse image into an @Image@ element.
    image :: JiraParser Inline
    image :: JiraParser Inline
    image = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
      -- does not use @url@, as is may contain relative locations.
      src <- 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 Char
    -> ParsecT Text ParserState Identity Char
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m a
    lookAhead ((Char -> Bool) -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    (Char -> Bool) -> ParsecT s u m Char
    satisfy ((Char -> Bool) -> ParsecT Text ParserState Identity Char)
    -> (Char -> Bool) -> ParsecT Text ParserState Identity Char
    forall a b. (a -> b) -> a -> b
    $ Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    isSpace)
             ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity URL
    -> ParsecT Text ParserState Identity URL
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> (Text -> URL
    URL (Text -> URL) -> ([Char] -> Text) -> [Char] -> URL
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack ([Char] -> URL)
    -> JiraParser [Char] -> ParsecT Text ParserState Identity URL
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall s u (m :: * -> *) a. 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
    noneOf [Char]
    "\r\t\n|]!"))
      params <- option [] (char '|' *> (thumbnail <|> imgParams `sepBy` comma))
      _ <- char '!'
      return $ Image params src
      where
        thumbnail :: ParsecT Text u Identity [Parameter]
    thumbnail = [Text -> Text -> Parameter
    Parameter Text
    "thumbnail" Text
    ""] [Parameter]
    -> ParsecT Text u Identity [Char]
    -> ParsecT Text u Identity [Parameter]
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try ([Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "thumbnail")
        imgParams :: ParsecT Text u Identity Parameter
    imgParams = ParsecT Text u Identity Parameter
    -> ParsecT Text u Identity Parameter
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (Text -> Text -> Parameter
    Parameter (Text -> Text -> Parameter)
    -> ParsecT Text u Identity Text
    -> ParsecT Text u Identity (Text -> Parameter)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Text u Identity Text
    forall {u}. ParsecT Text u Identity Text
    key ParsecT Text u Identity (Text -> Parameter)
    -> ParsecT Text u Identity Text
    -> ParsecT Text u Identity Parameter
    forall a b.
    ParsecT Text u Identity (a -> b)
    -> ParsecT Text u Identity a -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> (Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '=' ParsecT Text u Identity Char
    -> ParsecT Text u Identity Text -> ParsecT Text u Identity Text
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text u Identity Text
    forall {u}. ParsecT Text u Identity Text
    value))
        key :: ParsecT Text u Identity Text
    key       = [Char] -> Text
    pack ([Char] -> Text)
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ([Char] -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    noneOf [Char]
    ",\"'\t\n\r |{}=!")
        value :: ParsecT Text u Identity Text
    value     = [Char] -> Text
    pack ([Char] -> Text)
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try ParsecT Text u Identity [Char]
    forall {u}. ParsecT Text u Identity [Char]
    quotedValue ParsecT Text u Identity [Char]
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> ParsecT Text u Identity [Char]
    forall {u}. ParsecT Text u Identity [Char]
    unquotedValue)
        comma :: JiraParser ()
    comma     = 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 () -> JiraParser ()
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> JiraParser ()
    skipSpaces
        quotedValue :: ParsecT Text u Identity [Char]
    quotedValue = Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '"' ParsecT Text u Identity Char
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text u Identity Char
    -> ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    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 ([Char] -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    noneOf [Char]
    "\n\r") (Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '"')
        unquotedValue :: ParsecT Text u Identity [Char]
    unquotedValue = ParsecT Text u Identity Char -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ([Char] -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    noneOf [Char]
    ",\"'\n\r|{}=!")

    -- | Parse link into a @Link@ element.
    link :: JiraParser Inline
    link :: JiraParser Inline
    link = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
      Bool -> JiraParser ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> JiraParser ())
    -> (ParserState -> Bool) -> ParserState -> JiraParser ()
    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
    stateInLink (ParserState -> JiraParser ())
    -> ParsecT Text ParserState Identity ParserState -> JiraParser ()
    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 Inline -> JiraParser Inline
    forall a.
    (Bool -> ParserState -> ParserState)
    -> JiraParser a -> JiraParser a
    withStateFlag (\Bool
    b ParserState
    st -> ParserState
    st { stateInLink = b }) (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
        _ <- Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    '['
        (alias, sep) <- option ([], '|') . try $ (,) <$> many inline <*> oneOf "^|"
        (linkType, linkURL) <-
          if sep == '|'
          then (Email,) <$> email <|>
               (External,) <$> anchorLink <|>
               (User,) <$> userLink <|>
               externalLink
          else (Attachment,) . URL . pack <$>
               many1 (noneOf "\t\r\f\n]|:;/\\")
        _ <- char ']'
        return $ Link linkType alias linkURL

    -- | Parse a plain URL or mail address as @'AutoLink'@ element.
    autolink :: JiraParser Inline
    autolink :: JiraParser Inline
    autolink = do
      Bool -> JiraParser ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> JiraParser ())
    -> (ParserState -> Bool) -> ParserState -> JiraParser ()
    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
    stateInLink (ParserState -> JiraParser ())
    -> ParsecT Text ParserState Identity ParserState -> JiraParser ()
    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
      URL -> Inline
    AutoLink (URL -> Inline)
    -> ParsecT Text ParserState Identity URL -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (ParsecT Text ParserState Identity URL
    email' ParsecT Text ParserState Identity URL
    -> ParsecT Text ParserState Identity URL
    -> ParsecT Text ParserState Identity URL
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> Bool -> ParsecT Text ParserState Identity URL
    url Bool
    True) JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "email or other URL"
        where email' :: ParsecT Text ParserState Identity URL
    email' = (\(URL Text
    e) -> Text -> URL
    URL (Text
    "mailto:" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    e)) (URL -> URL)
    -> ParsecT Text ParserState Identity URL
    -> ParsecT Text ParserState Identity URL
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ParsecT Text ParserState Identity URL
    email

    -- | Parse a URL with scheme @file@, @ftp@, @http@, @https@, @irc@,
    -- @nntp@, or @news@; ignores @file@ if @isAutoLink@ is false.
    url :: Bool {-^ isAutoLink -} -> JiraParser URL
    url :: Bool -> ParsecT Text ParserState Identity URL
    url Bool
    isAutoLink = ParsecT Text ParserState Identity URL
    -> ParsecT Text ParserState Identity URL
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (ParsecT Text ParserState Identity URL
     -> ParsecT Text ParserState Identity URL)
    -> ParsecT Text ParserState Identity URL
    -> ParsecT Text ParserState Identity URL
    forall a b. (a -> b) -> a -> b
    $ do
      let urlChar' :: ParsecT Text ParserState Identity Char
    urlChar' = if Bool
    isAutoLink then ParsecT Text ParserState Identity Char
    urlPathChar else ParsecT Text ParserState Identity Char
    urlChar ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    ' '
      urlScheme <- ParsecT Text ParserState Identity Text
    forall {u}. ParsecT Text u Identity Text
    scheme
      sep <- pack <$> string "://"
      rest <- pack <$> many urlChar'
      return $ URL (urlScheme `append` sep `append` rest)
      where
        scheme :: ParsecT Text u Identity Text
    scheme = do
          first <- ParsecT Text u Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    letter
          case first of
            Char
    'f' -> (Text
    "file" Text
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ (Bool -> ParsecT Text u Identity ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> Bool
    not Bool
    isAutoLink) ParsecT Text u Identity ()
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "ile")) ParsecT Text u Identity Text
    -> ParsecT Text u Identity Text -> ParsecT Text u Identity Text
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|>
                   (Text
    "ftp" Text
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "tp")
            Char
    'h' -> [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "ttp" ParsecT Text u Identity [Char]
    -> ParsecT Text u Identity Text -> ParsecT Text u Identity Text
    forall a b.
    ParsecT Text u Identity a
    -> ParsecT Text u Identity b -> ParsecT Text u Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> Text
    -> ParsecT Text u Identity Text -> ParsecT Text u Identity Text
    forall s (m :: * -> *) t a u.
    Stream s m t =>
    a -> ParsecT s u m a -> ParsecT s u m a
    option Text
    "http" (Text
    "https" Text
    -> ParsecT Text u Identity Char -> ParsecT Text u Identity Text
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ Char -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    's')
            Char
    'i' -> Text
    "irc" Text
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "rc"
            Char
    'n' -> (Text
    "nntp" Text
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "ntp") ParsecT Text u Identity Text
    -> ParsecT Text u Identity Text -> ParsecT Text u Identity Text
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> (Text
    "news" Text
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity Text
    forall a b.
    a -> ParsecT Text u Identity b -> ParsecT Text u Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "ews")
            Char
    _   -> [Char] -> ParsecT Text u Identity Text
    forall a. [Char] -> ParsecT Text u Identity a
    forall (m :: * -> *) a. MonadFail m => [Char] -> m a
    fail [Char]
    "not looking at a known scheme"

    -- | Parses an email URI, returns the mail address without schema.
    email :: JiraParser URL
    email :: ParsecT Text ParserState Identity URL
    email = Text -> URL
    URL (Text -> URL) -> ([Char] -> Text) -> [Char] -> URL
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack ([Char] -> URL)
    -> JiraParser [Char] -> ParsecT Text ParserState Identity URL
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try ([Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "mailto:" JiraParser [Char] -> JiraParser [Char] -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT Text ParserState Identity Char
    urlChar)

    -- | Parses the link to an anchor name.
    anchorLink :: JiraParser URL
    anchorLink :: ParsecT Text ParserState Identity URL
    anchorLink = Text -> URL
    URL (Text -> URL) -> ([Char] -> Text) -> [Char] -> URL
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack ([Char] -> URL)
    -> JiraParser [Char] -> ParsecT Text ParserState Identity URL
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ((:) (Char -> [Char] -> [Char])
    -> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity ([Char] -> [Char])
    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
    '#' ParsecT Text ParserState Identity ([Char] -> [Char])
    -> JiraParser [Char] -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity (a -> b)
    -> ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many1 ParsecT Text ParserState Identity Char
    urlChar)

    -- | Parses a user-identifying resource name
    userLink :: JiraParser URL
    userLink :: ParsecT Text ParserState Identity URL
    userLink = Text -> URL
    URL (Text -> URL) -> ([Char] -> Text) -> [Char] -> URL
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    pack ([Char] -> URL)
    -> JiraParser [Char] -> ParsecT Text ParserState Identity URL
    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
    '~' ParsecT Text ParserState Identity Char
    -> JiraParser [Char] -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
    many ([Char] -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    noneOf [Char]
    "|]\n\r"))

    -- | Parses an external link, i.e., either a plain link to an external
    -- website, or a \"smart\" link or card.
    externalLink :: JiraParser (LinkType, URL)
    externalLink :: ParsecT Text ParserState Identity (LinkType, URL)
    externalLink = do
      url' <- Bool -> ParsecT Text ParserState Identity URL
    url Bool
    False
      mSmartType <- optionMaybe (char '|' *> smartLinkType)
      return $ case mSmartType of
        Maybe LinkType
    Nothing -> (LinkType
    External, URL
    url')
        Just LinkType
    st -> (LinkType
    st, URL
    url')

    -- | Finds the type of a "smart" link.
    smartLinkType :: JiraParser LinkType
    smartLinkType :: ParsecT Text ParserState Identity LinkType
    smartLinkType = [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "smart-" JiraParser [Char]
    -> ParsecT Text ParserState Identity LinkType
    -> ParsecT Text ParserState Identity LinkType
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> [ParsecT Text ParserState Identity LinkType]
    -> ParsecT Text ParserState Identity LinkType
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    [ParsecT s u m a] -> ParsecT s u m a
    choice
      [ LinkType
    SmartLink LinkType
    -> JiraParser [Char] -> ParsecT Text ParserState Identity LinkType
    forall a b.
    a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "link"
      , LinkType
    SmartCard LinkType
    -> JiraParser [Char] -> ParsecT Text ParserState Identity LinkType
    forall a b.
    a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "card"
      ]

    -- | Parses a character which is allowed in URLs
    urlChar :: JiraParser Char
    urlChar :: ParsecT Text ParserState Identity Char
    urlChar = (Char -> Bool) -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    (Char -> Bool) -> ParsecT s u m Char
    satisfy ((Char -> Bool) -> ParsecT Text ParserState Identity Char)
    -> (Char -> Bool) -> ParsecT Text ParserState Identity Char
    forall a b. (a -> b) -> a -> b
    $ \case
      Char
    ']' -> Bool
    False    -- "]"
      Char
    '|' -> Bool
    False    -- "|"
      Char
    x   -> Char -> Int
    ord Char
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    32 Bool -> Bool -> Bool
    && Char -> Int
    ord Char
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    126 -- excludes space

    -- | Parses a character in an URL path.
    urlPathChar :: JiraParser Char
    urlPathChar :: ParsecT Text ParserState Identity Char
    urlPathChar = (Char -> Bool) -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    (Char -> Bool) -> ParsecT s u m Char
    satisfy ((Char -> Bool) -> ParsecT Text ParserState Identity Char)
    -> (Char -> Bool) -> ParsecT Text ParserState Identity Char
    forall a b. (a -> b) -> a -> b
    $ \case
      Char
    '!' -> Bool
    True
      Char
    '#' -> Bool
    True
      Char
    '$' -> Bool
    True
      Char
    '%' -> Bool
    True
      Char
    '&' -> Bool
    True
      Char
    '\''-> Bool
    True
      Char
    '(' -> Bool
    True
      Char
    ')' -> Bool
    True
      Char
    '*' -> Bool
    True
      Char
    '+' -> Bool
    True
      Char
    ',' -> Bool
    True
      Char
    '-' -> Bool
    True
      Char
    '.' -> Bool
    True
      Char
    '/' -> Bool
    True
      Char
    ':' -> Bool
    True
      Char
    ';' -> Bool
    True
      Char
    '=' -> Bool
    True
      Char
    '?' -> Bool
    True
      Char
    '@' -> Bool
    True
      Char
    '\\'-> Bool
    True
      Char
    '_' -> Bool
    True
      Char
    '~' -> Bool
    True
      Char
    x   -> Char -> Bool
    isAlphaNum Char
    x Bool -> Bool -> Bool
    && Char -> Bool
    isAscii Char
    x

    --
    -- Color
    --

    -- | Text in a different color.
    colorInline :: JiraParser Inline
    colorInline :: JiraParser Inline
    colorInline = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
      name <- [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "{color:" JiraParser [Char] -> JiraParser [Char] -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> JiraParser [Char]
    forall {u}. ParsecT Text u Identity [Char]
    colorName JiraParser [Char]
    -> ParsecT Text ParserState Identity Char -> JiraParser [Char]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    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
    '}'
      content <- inline `manyTill` try (string "{color}")
      return $ ColorInline (ColorName $ pack name) content

    --
    -- Markup
    --

    -- | Parses styled text
    styled :: JiraParser Inline
    styled :: JiraParser Inline
    styled = (JiraParser Inline
    simpleStyled JiraParser Inline -> JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> JiraParser Inline
    forceStyled) JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "styled text"
      where
        simpleStyled :: JiraParser Inline
    simpleStyled = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
          styleChar <- ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m a
    lookAhead (ParsecT Text ParserState Identity Char
     -> ParsecT Text ParserState Identity Char)
    -> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m Char
    oneOf [Char]
    "-_+*~^"
          content   <- noNewlines $ styleChar `delimitingMany` inline
          let style = Char -> InlineStyle
    delimiterStyle Char
    styleChar
          return $ Styled style content

        forceStyled :: JiraParser Inline
    forceStyled = JiraParser Inline -> JiraParser Inline
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser Inline -> JiraParser Inline)
    -> JiraParser Inline -> JiraParser Inline
    forall a b. (a -> b) -> a -> b
    $ do
          styleChar <- 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 Char
    -> ParsecT Text ParserState Identity Char
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    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
    oneOf [Char]
    "-_+*~^" ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    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
    '}'
          let closing = ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char])
    -> ParsecT Text u Identity [Char] -> ParsecT Text u Identity [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> ParsecT Text u Identity [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char
    '{', Char
    styleChar, Char
    '}']
          let style   = Char -> InlineStyle
    delimiterStyle Char
    styleChar
          content   <- noNewlines $ manyTill inline closing
          return $ Styled style content

    -- | Makes sure that the wrapped parser does not parse inline
    -- linebreaks.
    noNewlines :: JiraParser a -> JiraParser a
    noNewlines :: forall a. JiraParser a -> JiraParser a
    noNewlines = (Bool -> ParserState -> ParserState)
    -> JiraParser a -> JiraParser a
    forall a.
    (Bool -> ParserState -> ParserState)
    -> JiraParser a -> JiraParser a
    withStateFlag (\Bool
    b ParserState
    st -> ParserState
    st { stateInMarkup = b })

    -- | Returns the markup kind from the delimiting markup character.
    delimiterStyle :: Char -> InlineStyle
    delimiterStyle :: Char -> InlineStyle
    delimiterStyle = \case
      Char
    '*' -> InlineStyle
    Strong
      Char
    '+' -> InlineStyle
    Insert
      Char
    '-' -> InlineStyle
    Strikeout
      Char
    '^' -> InlineStyle
    Superscript
      Char
    '_' -> InlineStyle
    Emphasis
      Char
    '~' -> InlineStyle
    Subscript
      Char
    c   -> [Char] -> InlineStyle
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "Unknown delimiter character: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char
    c])

    -- | Parses monospaced text into @Monospaced@.
    monospaced :: JiraParser Inline
    monospaced :: JiraParser Inline
    monospaced = [Inline] -> Inline
    Monospaced
      ([Inline] -> Inline)
    -> ParsecT Text ParserState Identity [Inline] -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> JiraParser [Char]
    -> JiraParser [Char]
    -> JiraParser Inline
    -> ParsecT Text ParserState Identity [Inline]
    forall closing opening a.
    Show closing =>
    JiraParser opening
    -> JiraParser closing -> JiraParser a -> JiraParser [a]
    enclosed (JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser [Char] -> JiraParser [Char])
    -> JiraParser [Char] -> JiraParser [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "{{") (JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser [Char] -> JiraParser [Char])
    -> JiraParser [Char] -> JiraParser [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "}}") JiraParser Inline
    inline
      JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "monospaced"

    citation :: JiraParser Inline
    citation :: JiraParser Inline
    citation = [Inline] -> Inline
    Citation
      ([Inline] -> Inline)
    -> ParsecT Text ParserState Identity [Inline] -> JiraParser Inline
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> JiraParser [Char]
    -> JiraParser [Char]
    -> JiraParser Inline
    -> ParsecT Text ParserState Identity [Inline]
    forall closing opening a.
    Show closing =>
    JiraParser opening
    -> JiraParser closing -> JiraParser a -> JiraParser [a]
    enclosed (JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser [Char] -> JiraParser [Char])
    -> JiraParser [Char] -> JiraParser [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "??") (JiraParser [Char] -> JiraParser [Char]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser [Char] -> JiraParser [Char])
    -> JiraParser [Char] -> JiraParser [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char] -> JiraParser [Char]
    forall s (m :: * -> *) u.
    Stream s m Char =>
    [Char] -> ParsecT s u m [Char]
    string [Char]
    "??") JiraParser Inline
    inline
      JiraParser Inline -> [Char] -> JiraParser Inline
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> [Char] -> ParsecT s u m a
    <?> [Char]
    "citation"

    --
    -- Helpers
    --

    -- | Parse text delimited by a character.
    delimitingMany :: Char -> JiraParser a -> JiraParser [a]
    delimitingMany :: forall a. Char -> JiraParser a -> JiraParser [a]
    delimitingMany Char
    c = ParsecT Text ParserState Identity Char
    -> ParsecT Text ParserState Identity Char
    -> JiraParser a
    -> JiraParser [a]
    forall closing opening a.
    Show closing =>
    JiraParser opening
    -> JiraParser closing -> JiraParser a -> JiraParser [a]
    enclosed (Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    c) (Char -> ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    Char -> ParsecT s u m Char
    char Char
    c)

    enclosed :: Show closing
             => JiraParser opening -> JiraParser closing
             -> JiraParser a
             -> JiraParser [a]
    enclosed :: forall closing opening a.
    Show closing =>
    JiraParser opening
    -> JiraParser closing -> JiraParser a -> JiraParser [a]
    enclosed JiraParser opening
    opening JiraParser closing
    closing JiraParser a
    parser = ParsecT Text ParserState Identity [a]
    -> ParsecT Text ParserState Identity [a]
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (ParsecT Text ParserState Identity [a]
     -> ParsecT Text ParserState Identity [a])
    -> ParsecT Text ParserState Identity [a]
    -> ParsecT Text ParserState Identity [a]
    forall a b. (a -> b) -> a -> b
    $ do
      Bool -> JiraParser ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> JiraParser ())
    -> ParsecT Text ParserState Identity Bool -> JiraParser ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< ParsecT Text ParserState Identity Bool
    notAfterString
      JiraParser opening
    opening JiraParser opening -> JiraParser () -> JiraParser ()
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> ParsecT Text ParserState Identity Char -> JiraParser ()
    forall s (m :: * -> *) t a u.
    (Stream s m t, Show a) =>
    ParsecT s u m a -> ParsecT s u m ()
    notFollowedBy ParsecT Text ParserState Identity Char
    forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
    space JiraParser ()
    -> ParsecT Text ParserState Identity [a]
    -> ParsecT Text ParserState Identity [a]
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    *> JiraParser a
    -> JiraParser closing -> ParsecT Text ParserState Identity [a]
    forall end a.
    Show end =>
    JiraParser a -> JiraParser end -> JiraParser [a]
    many1Till JiraParser a
    parser JiraParser closing
    closing'
      where
        closing' :: JiraParser closing
    closing' = JiraParser closing -> JiraParser closing
    forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
    try (JiraParser closing -> JiraParser closing)
    -> JiraParser closing -> JiraParser closing
    forall a b. (a -> b) -> a -> b
    $ do
          Bool -> JiraParser ()
    forall (f :: * -> *). Alternative f => Bool -> f ()
    guard (Bool -> JiraParser ()) -> (Bool -> Bool) -> Bool -> JiraParser ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Bool -> Bool
    not (Bool -> JiraParser ())
    -> ParsecT Text ParserState Identity Bool -> JiraParser ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< ParsecT Text ParserState Identity Bool
    afterSpace
          JiraParser closing
    closing JiraParser closing -> JiraParser () -> JiraParser closing
    forall a b.
    ParsecT Text ParserState Identity a
    -> ParsecT Text ParserState Identity b
    -> ParsecT Text ParserState Identity a
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
    <* JiraParser () -> JiraParser ()
    forall s (m :: * -> *) t u a.
    Stream s m t =>
    ParsecT s u m a -> ParsecT s u m a
    lookAhead JiraParser ()
    forall {u}. ParsecT Text u Identity ()
    wordBoundary
        wordBoundary :: ParsecT Text u Identity ()
    wordBoundary = ParsecT Text u Identity Char -> ParsecT Text u Identity ()
    forall (f :: * -> *) a. Functor f => f a -> f ()
    void ((Char -> Bool) -> ParsecT Text u Identity Char
    forall s (m :: * -> *) u.
    Stream s m Char =>
    (Char -> Bool) -> ParsecT s u m Char
    satisfy (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Bool
    isAlphaNum)) ParsecT Text u Identity ()
    -> ParsecT Text u Identity () -> ParsecT Text u Identity ()
    forall s u (m :: * -> *) a.
    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
    <|> ParsecT Text u Identity ()
    forall s (m :: * -> *) t u.
    (Stream s m t, Show t) =>
    ParsecT s u m ()
    eof