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

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

Functions for parsing markup-less strings.
-}

module Text.Jira.Parser.PlainText
  ( plainText
  ) where

import Data.Text (Text, append, pack)
import Text.Jira.Markup
import Text.Jira.Parser.Core
import Text.Jira.Parser.Inline (specialChars)
import Text.Jira.Parser.Shared (icon)
import Text.Parsec

-- | Parses into an @'Inline'@ elements which represent plain text. The
-- result consists of any number of @'Str'@, @'SpecialChar'@, or
-- @'Space'@ elements.
--
-- This parser can be used to convert un-escaped strings into proper
-- Jira markup elements.
plainText :: Text -> Either ParseError [Inline]
plainText :: Text -> Either ParseError [Inline]
plainText = JiraParser [Inline] -> Text -> Either ParseError [Inline]
forall a. JiraParser a -> Text -> Either ParseError a
parseJira ([Inline] -> [Inline]
normalizeInlines ([Inline] -> [Inline])
-> JiraParser [Inline] -> JiraParser [Inline]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity Inline -> JiraParser [Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Text ParserState Identity Inline
plainInlineParser)
  where
    plainInlineParser :: JiraParser Inline
    plainInlineParser :: ParsecT Text ParserState Identity Inline
plainInlineParser = [ParsecT Text ParserState Identity Inline]
-> ParsecT Text ParserState Identity Inline
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice
      [ Inline
Space Inline
-> ParsecT Text ParserState Identity ()
-> ParsecT Text ParserState Identity Inline
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 (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 Inline
forall u. Parsec Text u Inline
escapeIcon
      , ParsecT Text ParserState Identity Inline
forall u. Parsec Text u Inline
plainSpecialChar
      , Text -> Inline
Str (Text -> Inline) -> (String -> Text) -> String -> Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
pack (String -> Inline)
-> ParsecT Text ParserState Identity String
-> ParsecT Text ParserState Identity Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text ParserState Identity Char
-> ParsecT Text ParserState Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 (String -> ParsecT Text ParserState Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf (Char
' 'Char -> String -> String
forall a. a -> [a] -> [a]
:String
specialChars))
      ] ParsecT Text ParserState Identity Inline
-> String -> ParsecT Text ParserState Identity Inline
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"text-only inline"

-- | Escapes text which would otherwise render as an icon.
escapeIcon :: Parsec Text u Inline
escapeIcon :: Parsec Text u Inline
escapeIcon = Text -> Inline
Str (Text -> Inline) -> (Icon -> Text) -> Icon -> Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
"\\" Text -> Text -> Text
`append`) (Text -> Text) -> (Icon -> Text) -> Icon -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Icon -> Text
iconText (Icon -> Inline)
-> ParsecT Text u Identity Icon -> Parsec Text u Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Text u Identity Icon
forall u. Parsec Text u Icon
icon

plainSpecialChar :: Parsec Text u Inline
plainSpecialChar :: Parsec Text u Inline
plainSpecialChar = Char -> Inline
SpecialChar (Char -> Inline)
-> ParsecT Text u Identity Char -> Parsec Text u Inline
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT Text u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
specialChars