{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
module Text.Jira.Parser.Inline
( inline
, anchor
, autolink
, dash
, emoji
, entity
, image
, linebreak
, link
, monospaced
, specialChar
, str
, styled
, whitespace
, specialChars
) where
import Control.Monad (guard, void)
import Data.Char (isLetter, 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
monospaced
, JiraParser Inline
anchor
, 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
<?> "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 '{' 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 '}'
specialChars :: String
specialChars :: String
specialChars = "_+-*^~|[]{}(!&\\"
linebreak :: JiraParser Inline
linebreak :: JiraParser Inline
linebreak = Inline
Linebreak Inline -> JiraParser () -> JiraParser Inline
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ JiraParser () -> JiraParser ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (
[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 "\\\\" 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 '\\')
]
) JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "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 ' ') JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "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 -> Inline) -> JiraParser String -> JiraParser Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (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"
where
nonStrChars :: String
nonStrChars = " \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 (String -> ParsecT Text u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf 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 '&' 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 ';')
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 '#' 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 = 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
<?> "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 "--"
[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 "—" 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 '-'
, Inline -> JiraParser Inline
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Inline
Str "–")
] 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 ' ') 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
<?> "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 '\\' 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
/= '|') 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` ("]|\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
/= ' ')
(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 "{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 "\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 '}')
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 '!' 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 "\r\t\n|]!"))
(_, params :: [Parameter]
params) <- (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option (Maybe Text
forall a. Maybe a
Nothing, []) (Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '|' ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
-> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Text ParserState Identity (Maybe Text, [Parameter])
parameters)
Char
_ <- Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m 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
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 (\b :: Bool
b st :: 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 '['
[Inline]
alias <- [Inline]
-> ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option [] (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
$ ParsecT Text ParserState Identity [Inline]
-> ParsecT Text ParserState Identity [Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (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 [Inline]
-> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity [Inline]
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 '|')
URL
linkUrl <- 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
<|> ParsecT Text ParserState Identity URL
url
Char
_ <- Char -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m 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
$ [Inline] -> URL -> Inline
Link [Inline]
alias URL
linkUrl
autolink :: JiraParser Inline
autolink :: JiraParser Inline
autolink = 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
<|> ParsecT Text ParserState Identity URL
url) JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "email or other URL"
url :: JiraParser URL
url :: ParsecT Text ParserState Identity URL
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
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
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 "://"
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
'f' -> ("file" 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 "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
<|> ("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 "tp")
'h' -> String -> ParsecT Text u Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m 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 "http" ("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 's')
'i' -> "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 "rc"
'n' -> ("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 "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
<|> ("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 "ews")
_ -> String -> ParsecT Text u Identity Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "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 -> String -> String
forall a. [a] -> [a] -> [a]
(++) (String -> String -> String)
-> JiraParser String
-> ParsecT Text ParserState Identity (String -> String)
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 "mailto:" 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)
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
$ \c :: Char
c ->
Char
c Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` ("|]" :: String) Bool -> Bool -> Bool
&& Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 32 Bool -> Bool -> Bool
&& Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 127
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
<?> "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 "-_+*~^"
[Inline]
content <- 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 '{' 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 "-_+*~^" 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 '}'
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
styleChar, '}']
let style :: InlineStyle
style = Char -> InlineStyle
delimiterStyle Char
styleChar
[Inline]
content <- 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
delimiterStyle :: Char -> InlineStyle
delimiterStyle :: Char -> InlineStyle
delimiterStyle = \case
'*' -> InlineStyle
Strong
'+' -> InlineStyle
Insert
'-' -> InlineStyle
Strikeout
'^' -> InlineStyle
Superscript
'_' -> InlineStyle
Emphasis
'~' -> InlineStyle
Subscript
c :: Char
c -> String -> InlineStyle
forall a. HasCallStack => String -> a
error ("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 opening closing a.
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 "{{") (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 "}}") JiraParser Inline
inline
JiraParser Inline -> String -> JiraParser Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> "monospaced"
delimitingMany :: Char -> JiraParser a -> JiraParser [a]
delimitingMany :: Char -> JiraParser a -> JiraParser [a]
delimitingMany c :: Char
c = ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity Char
-> JiraParser a
-> JiraParser [a]
forall opening closing a.
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 :: JiraParser opening -> JiraParser closing
-> JiraParser a
-> JiraParser [a]
enclosed :: JiraParser opening
-> JiraParser closing -> JiraParser a -> JiraParser [a]
enclosed opening :: JiraParser opening
opening closing :: JiraParser closing
closing parser :: 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 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 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
$ 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
isLetter)) 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