{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TupleSections #-}
module Text.Jira.Parser.Inline
( inline
, anchor
, autolink
, citation
, colorInline
, dash
, emoji
, entity
, image
, linebreak
, link
, monospaced
, specialChar
, str
, styled
, whitespace
, specialChars
) where
import Control.Monad (guard, void)
import Data.Char (isAlphaNum, isAscii, isPunctuation, 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
inline :: JiraParser Inline
inline :: JiraParser Inline
inline = JiraParser String -> JiraParser ()
forall a. Show a => JiraParser a -> JiraParser ()
notFollowedBy' JiraParser String
forall u. ParsecT Text u Identity String
blockEnd JiraParser () -> JiraParser Inline -> JiraParser Inline
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 -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"inline"
where
blockEnd :: ParsecT Text u Identity String
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 String -> ParsecT Text u Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> [ParsecT Text u Identity String] -> ParsecT Text u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice ((String -> ParsecT Text u Identity String)
-> [String] -> [ParsecT Text u Identity String]
forall a b. (a -> b) -> [a] -> [b]
map String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string [String]
blockNames) ParsecT Text u Identity String
-> ParsecT Text u Identity Char -> ParsecT Text u Identity String
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
'}'
specialChars :: String
specialChars :: String
specialChars = String
"_+-*^~|[]{}(?!&\\:;"
linebreak :: JiraParser Inline
linebreak :: JiraParser Inline
linebreak = (JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"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 (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* JiraParser () -> JiraParser ()
forall a. Show a => JiraParser a -> JiraParser ()
notFollowedBy' JiraParser ()
endOfPara
, JiraParser String -> JiraParser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (JiraParser String -> JiraParser ())
-> JiraParser String -> JiraParser ()
forall a b. (a -> b) -> a -> b
$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"\\\\" JiraParser String -> JiraParser () -> JiraParser String
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 (m :: * -> *) a. Monad m => a -> m a
return Inline
Linebreak
whitespace :: JiraParser Inline
whitespace :: JiraParser Inline
whitespace = Inline
Space Inline -> JiraParser () -> JiraParser Inline
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 (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* JiraParser ()
updateLastSpcPos
JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"whitespace"
str :: JiraParser Inline
str :: JiraParser Inline
str = Text -> Inline
Str (Text -> Inline) -> ([String] -> Text) -> [String] -> Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> ([String] -> String) -> [String] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [String] -> String
forall a. Monoid a => [a] -> a
mconcat
([String] -> Inline)
-> ParsecT Text ParserState Identity [String] -> JiraParser Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JiraParser String -> 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 (JiraParser String
alphaNums JiraParser String -> JiraParser String -> JiraParser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> JiraParser String
forall u. ParsecT Text u Identity String
otherNonSpecialChars)
JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"string"
where
nonStrChars :: String
nonStrChars = String
" \n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
specialChars
alphaNums :: JiraParser String
alphaNums = ParsecT Text ParserState Identity Char -> JiraParser String
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 Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum JiraParser String -> JiraParser () -> JiraParser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* JiraParser ()
updateLastStrPos
otherNonSpecialChars :: ParsecT Text u Identity String
otherNonSpecialChars = ParsecT Text u Identity Char -> ParsecT Text u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT Text u Identity Char -> ParsecT Text u Identity String)
-> ((Char -> Bool) -> ParsecT Text u Identity Char)
-> (Char -> Bool)
-> ParsecT Text u Identity String
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 String)
-> (Char -> Bool) -> ParsecT Text u Identity String
forall a b. (a -> b) -> a -> b
$ \Char
c ->
Bool -> Bool
not (Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
nonStrChars)
entity :: JiraParser Inline
entity :: JiraParser Inline
entity = Text -> Inline
Entity (Text -> Inline) -> (String -> Text) -> String -> Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack
(String -> Inline) -> JiraParser String -> JiraParser Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JiraParser String -> JiraParser String
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 String -> JiraParser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (JiraParser String
forall u. ParsecT Text u Identity String
numerical JiraParser String -> JiraParser String -> JiraParser String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> JiraParser String
forall u. ParsecT Text u Identity String
named) JiraParser String
-> ParsecT Text ParserState Identity Char -> JiraParser 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
';')
where
numerical :: ParsecT Text u Identity String
numerical = (:) (Char -> String -> String)
-> ParsecT Text u Identity Char
-> ParsecT Text u Identity (String -> String)
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 (String -> String)
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Text u Identity Char -> ParsecT Text u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
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 String
named = ParsecT Text u Identity Char -> ParsecT Text u Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
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
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 -> JiraParser () -> JiraParser Inline
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' ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"emoji")
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
String
_ <- String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"--"
[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 [ Text -> Inline
Str Text
"—" Inline
-> ParsecT Text ParserState Identity Char -> JiraParser Inline
forall (f :: * -> *) a b. Functor 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 -> JiraParser Inline
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Inline
Str Text
"–")
] JiraParser Inline -> JiraParser () -> JiraParser Inline
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 (ParsecT Text ParserState Identity Char -> JiraParser ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
' ') JiraParser () -> JiraParser () -> JiraParser ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> JiraParser ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof)
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
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 -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"special char"
where
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 (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
Char -> All
inTablePred <- do
Bool
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
(Char -> All) -> ParsecT Text ParserState Identity (Char -> All)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Char -> All) -> ParsecT Text ParserState Identity (Char -> All))
-> (Char -> All) -> ParsecT Text ParserState Identity (Char -> All)
forall a b. (a -> b) -> a -> b
$ if Bool
b then Bool -> All
All (Bool -> All) -> (Char -> Bool) -> Char -> All
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'|') else Char -> All
forall a. Monoid a => a
mempty
Char -> All
inLinkPred <- do
Bool
b <- ParserState -> Bool
stateInLink (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
(Char -> All) -> ParsecT Text ParserState Identity (Char -> All)
forall (m :: * -> *) a. Monad m => a -> m a
return ((Char -> All) -> ParsecT Text ParserState Identity (Char -> All))
-> (Char -> All) -> ParsecT Text ParserState Identity (Char -> All)
forall a b. (a -> b) -> a -> b
$ if Bool
b then Bool -> All
All (Bool -> All) -> (Char -> Bool) -> Char -> All
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` (String
"]^|\n" :: String)) else Char -> All
forall a. Monoid a => a
mempty
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 Char)
-> String -> ParsecT Text ParserState Identity Char
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (All -> Bool
getAll (All -> Bool) -> (Char -> All) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> All
inTablePred (Char -> All) -> (Char -> All) -> Char -> All
forall a. Semigroup a => a -> a -> a
<> Char -> All
inLinkPred)) String
specialChars
anchor :: JiraParser Inline
anchor :: JiraParser Inline
anchor = Text -> Inline
Anchor (Text -> Inline) -> (String -> Text) -> String -> Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Text) -> (String -> String) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
' ')
(String -> Inline) -> JiraParser String -> JiraParser Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{anchor:" JiraParser String -> JiraParser String -> JiraParser String
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
noneOf String
"\n" ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char -> JiraParser 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` Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'}')
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
URL
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 URL
-> ParsecT Text ParserState Identity URL
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Text -> URL
URL (Text -> URL) -> (String -> Text) -> String -> URL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> URL)
-> JiraParser String -> ParsecT Text ParserState Identity URL
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity Char -> JiraParser 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
noneOf String
"\r\t\n|]!"))
[Parameter]
params <- [Parameter]
-> ParsecT Text ParserState Identity [Parameter]
-> ParsecT Text ParserState Identity [Parameter]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] (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 [Parameter]
-> ParsecT Text ParserState Identity [Parameter]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (ParsecT Text ParserState Identity [Parameter]
forall u. ParsecT Text u Identity [Parameter]
thumbnail ParsecT Text ParserState Identity [Parameter]
-> ParsecT Text ParserState Identity [Parameter]
-> ParsecT Text ParserState Identity [Parameter]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Text ParserState Identity Parameter
forall u. ParsecT Text u Identity Parameter
imgParams ParsecT Text ParserState Identity Parameter
-> JiraParser () -> ParsecT Text ParserState Identity [Parameter]
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]
`sepBy` JiraParser ()
comma))
Char
_ <- Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'!'
Inline -> JiraParser Inline
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> JiraParser Inline) -> Inline -> JiraParser Inline
forall a b. (a -> b) -> a -> b
$ [Parameter] -> URL -> Inline
Image [Parameter]
params URL
src
where
thumbnail :: ParsecT Text u Identity [Parameter]
thumbnail = [Text -> Text -> Parameter
Parameter Text
"thumbnail" Text
""] [Parameter]
-> ParsecT Text u Identity String
-> ParsecT Text u Identity [Parameter]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"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 (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 (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 = String -> Text
pack (String -> Text)
-> ParsecT Text u Identity String -> 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 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 u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
",\"'\t\n\r |{}=!")
value :: ParsecT Text u Identity Text
value = String -> Text
pack (String -> Text)
-> ParsecT Text u Identity String -> ParsecT Text u Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT Text u Identity String
forall u. ParsecT Text u Identity String
quotedValue ParsecT Text u Identity String
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Text u Identity String
forall u. ParsecT Text u Identity String
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 (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> JiraParser ()
skipSpaces
quotedValue :: ParsecT Text u Identity String
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 String -> ParsecT Text u Identity String
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 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 (String -> ParsecT Text u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"\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 String
unquotedValue = ParsecT Text u Identity Char -> ParsecT Text u 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 u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
",\"'\n\r|{}=!")
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 :: Bool
stateInLink = Bool
b }) (JiraParser Inline -> JiraParser Inline)
-> JiraParser Inline -> JiraParser Inline
forall a b. (a -> b) -> a -> b
$ do
Char
_ <- Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'['
([Inline]
alias, Char
sep) <- ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char)
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option ([], Char
'|') (ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char))
-> (ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char))
-> ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char))
-> ParsecT Text ParserState Identity ([Inline], Char)
-> ParsecT Text ParserState Identity ([Inline], Char)
forall a b. (a -> b) -> a -> b
$ (,) ([Inline] -> Char -> ([Inline], Char))
-> ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity (Char -> ([Inline], Char))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JiraParser Inline -> ParsecT Text ParserState Identity [Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many JiraParser Inline
inline ParsecT Text ParserState Identity (Char -> ([Inline], Char))
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ([Inline], Char)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"^|"
(LinkType
linkType, URL
linkURL) <-
if Char
sep Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'|'
then (LinkType
Email,) (URL -> (LinkType, URL))
-> ParsecT Text ParserState Identity URL
-> ParsecT Text ParserState Identity (LinkType, URL)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity URL
email ParsecT Text ParserState Identity (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
(LinkType
External,) (URL -> (LinkType, URL))
-> ParsecT Text ParserState Identity URL
-> ParsecT Text ParserState Identity (LinkType, URL)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity URL
anchorLink ParsecT Text ParserState Identity (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
(LinkType
User,) (URL -> (LinkType, URL))
-> ParsecT Text ParserState Identity URL
-> ParsecT Text ParserState Identity (LinkType, URL)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity URL
userLink ParsecT Text ParserState Identity (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
ParsecT Text ParserState Identity (LinkType, URL)
externalLink
else (LinkType
Attachment,) (URL -> (LinkType, URL))
-> (String -> URL) -> String -> (LinkType, URL)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> URL
URL (Text -> URL) -> (String -> Text) -> String -> URL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> (LinkType, URL))
-> JiraParser String
-> ParsecT Text ParserState Identity (LinkType, URL)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
ParsecT Text ParserState Identity Char -> JiraParser 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
noneOf String
"\t\r\f\n]|:;/\\")
Char
_ <- Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
']'
Inline -> JiraParser Inline
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> JiraParser Inline) -> Inline -> JiraParser Inline
forall a b. (a -> b) -> a -> b
$ LinkType -> [Inline] -> URL -> Inline
Link LinkType
linkType [Inline]
alias URL
linkURL
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 -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"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
url :: Bool -> 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
' '
Text
urlScheme <- ParsecT Text ParserState Identity Text
forall u. ParsecT Text u Identity Text
scheme
Text
sep <- String -> Text
pack (String -> Text)
-> JiraParser String -> ParsecT Text ParserState Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"://"
Text
rest <- String -> Text
pack (String -> Text)
-> JiraParser String -> ParsecT Text ParserState Identity Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity Char -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Text ParserState Identity Char
urlChar'
URL -> ParsecT Text ParserState Identity URL
forall (m :: * -> *) a. Monad m => a -> m a
return (URL -> ParsecT Text ParserState Identity URL)
-> URL -> ParsecT Text ParserState Identity URL
forall a b. (a -> b) -> a -> b
$ Text -> URL
URL (Text
urlScheme Text -> Text -> Text
`append` Text
sep Text -> Text -> Text
`append` Text
rest)
where
scheme :: ParsecT Text u Identity Text
scheme = do
Char
first <- ParsecT Text u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
letter
case Char
first of
Char
'f' -> (Text
"file" Text
-> ParsecT Text u Identity String -> ParsecT Text u Identity Text
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 String -> ParsecT Text u Identity String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"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 String -> ParsecT Text u Identity Text
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"tp")
Char
'h' -> String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"ttp" ParsecT Text u Identity String
-> ParsecT Text u Identity Text -> ParsecT Text u Identity Text
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 (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 String -> ParsecT Text u Identity Text
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"rc"
Char
'n' -> (Text
"nntp" Text
-> ParsecT Text u Identity String -> ParsecT Text u Identity Text
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"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 String -> ParsecT Text u Identity Text
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"ews")
Char
_ -> String -> ParsecT Text u Identity Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"not looking at a known scheme"
email :: JiraParser URL
email :: ParsecT Text ParserState Identity URL
email = Text -> URL
URL (Text -> URL) -> (String -> Text) -> String -> URL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> URL)
-> JiraParser String -> ParsecT Text ParserState Identity URL
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"mailto:" JiraParser String -> JiraParser String -> JiraParser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Char -> JiraParser String
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 Char
urlChar)
anchorLink :: JiraParser URL
anchorLink :: ParsecT Text ParserState Identity URL
anchorLink = Text -> URL
URL (Text -> URL) -> (String -> Text) -> String -> URL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> URL)
-> JiraParser String -> ParsecT Text ParserState Identity URL
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((:) (Char -> String -> String)
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity (String -> String)
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 (String -> String)
-> JiraParser String -> JiraParser String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT Text ParserState Identity Char -> JiraParser String
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 Char
urlChar)
userLink :: JiraParser URL
userLink :: ParsecT Text ParserState Identity URL
userLink = Text -> URL
URL (Text -> URL) -> (String -> Text) -> String -> URL
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> URL)
-> JiraParser String -> 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 String -> JiraParser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity Char -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
"|]\n\r"))
externalLink :: JiraParser (LinkType, URL)
externalLink :: ParsecT Text ParserState Identity (LinkType, URL)
externalLink = do
URL
url' <- Bool -> ParsecT Text ParserState Identity URL
url Bool
False
Maybe LinkType
mSmartType <- ParsecT Text ParserState Identity LinkType
-> ParsecT Text ParserState Identity (Maybe LinkType)
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m (Maybe a)
optionMaybe (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 LinkType
-> ParsecT Text ParserState Identity LinkType
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity LinkType
smartLinkType)
(LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
forall (m :: * -> *) a. Monad m => a -> m a
return ((LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL))
-> (LinkType, URL)
-> ParsecT Text ParserState Identity (LinkType, URL)
forall a b. (a -> b) -> a -> b
$ case Maybe LinkType
mSmartType of
Maybe LinkType
Nothing -> (LinkType
External, URL
url')
Just LinkType
st -> (LinkType
st, URL
url')
smartLinkType :: JiraParser LinkType
smartLinkType :: ParsecT Text ParserState Identity LinkType
smartLinkType = String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"smart-" JiraParser String
-> ParsecT Text ParserState Identity LinkType
-> ParsecT Text ParserState Identity LinkType
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 String -> ParsecT Text ParserState Identity LinkType
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"link"
, LinkType
SmartCard LinkType
-> JiraParser String -> ParsecT Text ParserState Identity LinkType
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"card"
]
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
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
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
String
name <- String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{color:" JiraParser String -> JiraParser String -> JiraParser String
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> JiraParser String
forall u. ParsecT Text u Identity String
colorName JiraParser String
-> ParsecT Text ParserState Identity Char -> JiraParser 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
'}'
[Inline]
content <- JiraParser Inline
inline JiraParser Inline
-> JiraParser String -> 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` JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{color}")
Inline -> JiraParser Inline
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> JiraParser Inline) -> Inline -> JiraParser Inline
forall a b. (a -> b) -> a -> b
$ ColorName -> [Inline] -> Inline
ColorInline (Text -> ColorName
ColorName (Text -> ColorName) -> Text -> ColorName
forall a b. (a -> b) -> a -> b
$ String -> Text
pack String
name) [Inline]
content
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 -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"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
Char
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
$ String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"-_+*~^"
[Inline]
content <- ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall a. JiraParser a -> JiraParser a
noNewlines (ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline])
-> ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall a b. (a -> b) -> a -> b
$ Char
styleChar Char
-> JiraParser Inline -> ParsecT Text ParserState Identity [Inline]
forall a. Char -> JiraParser a -> JiraParser [a]
`delimitingMany` JiraParser Inline
inline
let style :: InlineStyle
style = Char -> InlineStyle
delimiterStyle Char
styleChar
Inline -> JiraParser Inline
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> JiraParser Inline) -> Inline -> JiraParser Inline
forall a b. (a -> b) -> a -> b
$ InlineStyle -> [Inline] -> Inline
Styled InlineStyle
style [Inline]
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
Char
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 (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
"-_+*~^" 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
'}'
let closing :: ParsecT Text u Identity String
closing = ParsecT Text u Identity String -> ParsecT Text u Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Text u Identity String -> ParsecT Text u Identity String)
-> ParsecT Text u Identity String -> ParsecT Text u Identity String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string [Char
'{', Char
styleChar, Char
'}']
let style :: InlineStyle
style = Char -> InlineStyle
delimiterStyle Char
styleChar
[Inline]
content <- ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall a. JiraParser a -> JiraParser a
noNewlines (ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline])
-> ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall a b. (a -> b) -> a -> b
$ JiraParser Inline
-> JiraParser String -> 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 JiraParser Inline
inline JiraParser String
forall u. ParsecT Text u Identity String
closing
Inline -> JiraParser Inline
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> JiraParser Inline) -> Inline -> JiraParser Inline
forall a b. (a -> b) -> a -> b
$ InlineStyle -> [Inline] -> Inline
Styled InlineStyle
style [Inline]
content
noNewlines :: JiraParser a -> JiraParser a
noNewlines :: 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 :: Bool
stateInMarkup = Bool
b })
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 -> String -> InlineStyle
forall a. HasCallStack => String -> a
error (String
"Unknown delimiter character: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [Char
c])
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 String
-> JiraParser String
-> JiraParser Inline
-> ParsecT Text ParserState Identity [Inline]
forall closing opening a.
Show closing =>
JiraParser opening
-> JiraParser closing -> JiraParser a -> JiraParser [a]
enclosed (JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser String -> JiraParser String)
-> JiraParser String -> JiraParser String
forall a b. (a -> b) -> a -> b
$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"{{") (JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser String -> JiraParser String)
-> JiraParser String -> JiraParser String
forall a b. (a -> b) -> a -> b
$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"}}") JiraParser Inline
inline
JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"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 String
-> JiraParser String
-> JiraParser Inline
-> ParsecT Text ParserState Identity [Inline]
forall closing opening a.
Show closing =>
JiraParser opening
-> JiraParser closing -> JiraParser a -> JiraParser [a]
enclosed (JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser String -> JiraParser String)
-> JiraParser String -> JiraParser String
forall a b. (a -> b) -> a -> b
$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"??") (JiraParser String -> JiraParser String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser String -> JiraParser String)
-> JiraParser String -> JiraParser String
forall a b. (a -> b) -> a -> b
$ String -> JiraParser String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
"??") JiraParser Inline
inline
JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"citation"
delimitingMany :: Char -> JiraParser a -> JiraParser [a]
delimitingMany :: 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 :: JiraParser opening
-> JiraParser closing -> JiraParser a -> JiraParser [a]
enclosed JiraParser opening
opening JiraParser closing
closing JiraParser a
parser = JiraParser [a] -> JiraParser [a]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (JiraParser [a] -> JiraParser [a])
-> JiraParser [a] -> JiraParser [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 (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 () -> JiraParser [a] -> JiraParser [a]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> JiraParser a -> JiraParser closing -> JiraParser [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 (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