{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{- |
   Module      : Text.Pandoc.Writers.Jira
   Copyright   : © 2010-2022 Albert Krewinkel, John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
   Stability   : alpha
   Portability : portable

Conversion of 'Pandoc' documents to Jira markup.

JIRA:
<https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all>
-}
module Text.Pandoc.Writers.Jira ( writeJira ) where
import Control.Monad.Reader (ReaderT, ask, asks, runReaderT)
import Control.Monad.State.Strict (StateT, evalStateT, gets, modify)
import Data.Foldable (find)
import Data.Text (Text)
import Text.Jira.Parser (plainText)
import Text.Jira.Printer (prettyBlocks, prettyInlines)
import Text.Pandoc.Class.PandocMonad (PandocMonad)
import Text.Pandoc.Definition
import Text.Pandoc.Options (WriterOptions (writerTemplate, writerWrapText),
                            WrapOption (..))
import Text.Pandoc.Shared (linesToPara, stringify)
import Text.Pandoc.Templates (renderTemplate)
import Text.Pandoc.Writers.Math (texMathToInlines)
import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable)
import Text.DocLayout (literal, render)
import qualified Data.Text as T
import qualified Text.Jira.Markup as Jira

-- | Convert Pandoc to Jira.
writeJira :: PandocMonad m => WriterOptions -> Pandoc -> m Text
writeJira :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeJira WriterOptions
opts = forall (m :: * -> *) a.
PandocMonad m =>
WrapOption -> (a -> JiraConverter m Text) -> a -> m Text
runDefaultConverter (WriterOptions -> WrapOption
writerWrapText WriterOptions
opts) (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> JiraConverter m Text
pandocToJira WriterOptions
opts)

-- | State to keep track of footnotes.
data ConverterState = ConverterState
  { ConverterState -> [Text]
stNotes   :: [Text] -- ^ Footnotes to be appended to the end of the text
  , ConverterState -> Bool
stInPanel :: Bool   -- ^ whether we are in a @{panel}@ block
  }

-- | Initial converter state.
startState :: ConverterState
startState :: ConverterState
startState = ConverterState
  { stNotes :: [Text]
stNotes = []
  , stInPanel :: Bool
stInPanel = Bool
False
  }

-- | Converter monad
type JiraConverter m = ReaderT WrapOption (StateT ConverterState m)

-- | Run a converter using the default state
runDefaultConverter :: PandocMonad m
                    => WrapOption
                    -> (a -> JiraConverter m Text)
                    -> a
                    -> m Text
runDefaultConverter :: forall (m :: * -> *) a.
PandocMonad m =>
WrapOption -> (a -> JiraConverter m Text) -> a -> m Text
runDefaultConverter WrapOption
wrap a -> JiraConverter m Text
c a
x = forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (a -> JiraConverter m Text
c a
x) WrapOption
wrap) ConverterState
startState

-- | Return Jira representation of document.
pandocToJira :: PandocMonad m
             => WriterOptions -> Pandoc -> JiraConverter m Text
pandocToJira :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> JiraConverter m Text
pandocToJira WriterOptions
opts (Pandoc Meta
meta [Block]
blocks) = do
  WrapOption
wrap <- forall r (m :: * -> *). MonadReader r m => m r
ask
  Context Text
metadata <- forall (m :: * -> *) a.
(Monad m, TemplateTarget a) =>
WriterOptions
-> ([Block] -> m (Doc a))
-> ([Inline] -> m (Doc a))
-> Meta
-> m (Context a)
metaToContext WriterOptions
opts
                 (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. HasChars a => a -> Doc a
literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
PandocMonad m =>
WrapOption -> (a -> JiraConverter m Text) -> a -> m Text
runDefaultConverter WrapOption
wrap forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m Text
blockListToJira)
                 (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. HasChars a => a -> Doc a
literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
PandocMonad m =>
WrapOption -> (a -> JiraConverter m Text) -> a -> m Text
runDefaultConverter WrapOption
wrap forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m Text
inlineListToJira) Meta
meta
  Text
body <- forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m Text
blockListToJira [Block]
blocks
  Text
notes <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate Text
"\n" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConverterState -> [Text]
stNotes
  let main :: Text
main = Text
body forall a. Semigroup a => a -> a -> a
<> if Text -> Bool
T.null Text
notes then forall a. Monoid a => a
mempty else Text
"\n\n" forall a. Semigroup a => a -> a -> a
<> Text
notes
  let context :: Context Text
context = forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"body" Text
main Context Text
metadata
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    case WriterOptions -> Maybe (Template Text)
writerTemplate WriterOptions
opts of
      Maybe (Template Text)
Nothing  -> Text
main
      Just Template Text
tpl -> forall a. HasChars a => Maybe Int -> Doc a -> a
render forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$ forall a b.
(TemplateTarget a, ToContext a b) =>
Template a -> b -> Doc a
renderTemplate Template Text
tpl Context Text
context

blockListToJira :: PandocMonad m => [Block] -> JiraConverter m Text
blockListToJira :: forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m Text
blockListToJira = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Block] -> Text
prettyBlocks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks

inlineListToJira :: PandocMonad m => [Inline] -> JiraConverter m Text
inlineListToJira :: forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m Text
inlineListToJira = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Inline] -> Text
prettyInlines forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines

toJiraBlocks :: PandocMonad m => [Block] -> JiraConverter m [Jira.Block]
toJiraBlocks :: forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks [Block]
blocks = do
  let convert :: Block -> JiraConverter m [Block]
convert = \case
        BlockQuote [Block]
bs        -> forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> Block
Jira.BlockQuote
                                forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks [Block]
bs
        BulletList [[Block]]
items     -> forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. ListStyle -> [[Block]] -> Block
Jira.List ListStyle
Jira.CircleBullets
                                forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[[Block]] -> JiraConverter m [[Block]]
toJiraItems [[Block]]
items
        CodeBlock Attr
attr Text
cs    -> forall (m :: * -> *).
PandocMonad m =>
Attr -> Text -> JiraConverter m [Block]
toJiraCode Attr
attr Text
cs
        DefinitionList [([Inline], [[Block]])]
items -> forall (m :: * -> *).
PandocMonad m =>
[([Inline], [[Block]])] -> JiraConverter m [Block]
toJiraDefinitionList [([Inline], [[Block]])]
items
        Div Attr
attr [Block]
bs          -> forall (m :: * -> *).
PandocMonad m =>
Attr -> [Block] -> JiraConverter m [Block]
toJiraPanel Attr
attr [Block]
bs
        Header Int
lvl Attr
attr [Inline]
xs   -> forall (m :: * -> *).
PandocMonad m =>
Int -> Attr -> [Inline] -> JiraConverter m [Block]
toJiraHeader Int
lvl Attr
attr [Inline]
xs
        Block
HorizontalRule       -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ Block
Jira.HorizontalRule
        LineBlock [[Inline]]
xs         -> forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks [[[Inline]] -> Block
linesToPara [[Inline]]
xs]
        OrderedList ListAttributes
_ [[Block]]
items  -> forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. ListStyle -> [[Block]] -> Block
Jira.List ListStyle
Jira.Enumeration
                                forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[[Block]] -> JiraConverter m [[Block]]
toJiraItems [[Block]]
items
        Para [Inline]
xs              -> forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> Block
Jira.Para forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
xs
        Plain [Inline]
xs             -> forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> Block
Jira.Para forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
xs
        RawBlock Format
fmt Text
cs      -> forall (m :: * -> *).
PandocMonad m =>
Format -> Text -> JiraConverter m [Block]
rawBlockToJira Format
fmt Text
cs
        Block
Null                 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
        Table Attr
_ Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot -> forall a. a -> [a]
singleton forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
          let ([Inline]
_, [Alignment]
_, [Double]
_, [[Block]]
hd, [[[Block]]]
body) = Caption
-> [ColSpec]
-> TableHead
-> [TableBody]
-> TableFoot
-> ([Inline], [Alignment], [Double], [[Block]], [[[Block]]])
toLegacyTable Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot
          Maybe Row
headerRow <- if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
hd
                       then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
                       else forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
([Block] -> Cell) -> [[Block]] -> JiraConverter m Row
toRow [Block] -> Cell
Jira.HeaderCell [[Block]]
hd
          [Row]
bodyRows <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
([Block] -> Cell) -> [[Block]] -> JiraConverter m Row
toRow [Block] -> Cell
Jira.BodyCell) [[[Block]]]
body
          let rows :: [Row]
rows = case Maybe Row
headerRow of
                       Just Row
header -> Row
header forall a. a -> [a] -> [a]
: [Row]
bodyRows
                       Maybe Row
Nothing     -> [Row]
bodyRows
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Row] -> Block
Jira.Table [Row]
rows
  [[Block]]
jiraBlocks <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Block -> JiraConverter m [Block]
convert [Block]
blocks
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat [[Block]]
jiraBlocks

toRow :: PandocMonad m
      => ([Jira.Block] -> Jira.Cell)
      -> [[Block]]
      -> JiraConverter m Jira.Row
toRow :: forall (m :: * -> *).
PandocMonad m =>
([Block] -> Cell) -> [[Block]] -> JiraConverter m Row
toRow [Block] -> Cell
mkCell [[Block]]
cells = [Cell] -> Row
Jira.Row forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
  forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Block] -> Cell
mkCell forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks) [[Block]]
cells

toJiraItems :: PandocMonad m => [[Block]] -> JiraConverter m [[Jira.Block]]
toJiraItems :: forall (m :: * -> *).
PandocMonad m =>
[[Block]] -> JiraConverter m [[Block]]
toJiraItems = forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks

toJiraCode :: PandocMonad m
           => Attr
           -> Text
           -> JiraConverter m [Jira.Block]
toJiraCode :: forall (m :: * -> *).
PandocMonad m =>
Attr -> Text -> JiraConverter m [Block]
toJiraCode (Text
ident, [Text]
classes, [(Text, Text)]
_attribs) Text
code = do
  forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Block] -> [Block]
addAnchor Text
ident forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$
    case forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\Text
c -> Text -> Text
T.toLower Text
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
knownLanguages) [Text]
classes of
      Maybe Text
Nothing -> [Parameter] -> Text -> Block
Jira.NoFormat forall a. Monoid a => a
mempty Text
code
      Just Text
l  -> Language -> [Parameter] -> Text -> Block
Jira.Code (Text -> Language
Jira.Language Text
l) forall a. Monoid a => a
mempty Text
code

-- | Prepends an anchor with the given identifier.
addAnchor :: Text -> [Jira.Block] -> [Jira.Block]
addAnchor :: Text -> [Block] -> [Block]
addAnchor Text
ident =
  if Text -> Bool
T.null Text
ident
  then forall a. a -> a
id
  else \case
    Jira.Para [Inline]
xs : [Block]
bs -> ([Inline] -> Block
Jira.Para (Text -> Inline
Jira.Anchor Text
ident forall a. a -> [a] -> [a]
: [Inline]
xs) forall a. a -> [a] -> [a]
: [Block]
bs)
    [Block]
bs                -> ([Inline] -> Block
Jira.Para (forall a. a -> [a]
singleton (Text -> Inline
Jira.Anchor Text
ident)) forall a. a -> [a] -> [a]
: [Block]
bs)

-- | Creates a Jira definition list
toJiraDefinitionList :: PandocMonad m
                     => [([Inline], [[Block]])]
                     -> JiraConverter m [Jira.Block]
toJiraDefinitionList :: forall (m :: * -> *).
PandocMonad m =>
[([Inline], [[Block]])] -> JiraConverter m [Block]
toJiraDefinitionList [([Inline], [[Block]])]
defItems = do
  let convertDefItem :: ([Inline], [[Block]])
-> ReaderT WrapOption (StateT ConverterState m) [Block]
convertDefItem ([Inline]
term, [[Block]]
defs) = do
        Block
jiraTerm <- [Inline] -> Block
Jira.Para forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Strong [Inline]
term
        [Block]
jiraDefs <- forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks [[Block]]
defs
        forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Block
jiraTerm forall a. a -> [a] -> [a]
: [Block]
jiraDefs
  forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. ListStyle -> [[Block]] -> Block
Jira.List ListStyle
Jira.CircleBullets forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {m :: * -> *}.
PandocMonad m =>
([Inline], [[Block]])
-> ReaderT WrapOption (StateT ConverterState m) [Block]
convertDefItem [([Inline], [[Block]])]
defItems

-- | Creates a Jira panel
toJiraPanel :: PandocMonad m
            => Attr -> [Block]
            -> JiraConverter m [Jira.Block]
toJiraPanel :: forall (m :: * -> *).
PandocMonad m =>
Attr -> [Block] -> JiraConverter m [Block]
toJiraPanel (Text
ident, [Text]
classes, [(Text, Text)]
attribs) [Block]
blocks = do
  Bool
inPanel <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ConverterState -> Bool
stInPanel
  if Bool
inPanel Bool -> Bool -> Bool
|| (Text
"panel" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` [Text]
classes Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Text, Text)]
attribs)
    then Text -> [Block] -> [Block]
addAnchor Text
ident forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks [Block]
blocks
    else do
      forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \ConverterState
st -> ConverterState
st{ stInPanel :: Bool
stInPanel = Bool
True }
      [Block]
jiraBlocks <- forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Block]
toJiraBlocks [Block]
blocks
      forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \ConverterState
st -> ConverterState
st{ stInPanel :: Bool
stInPanel = Bool
inPanel }
      let params :: [Parameter]
params = forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> Text -> Parameter
Jira.Parameter) [(Text, Text)]
attribs
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> [a]
singleton ([Parameter] -> [Block] -> Block
Jira.Panel [Parameter]
params forall a b. (a -> b) -> a -> b
$ Text -> [Block] -> [Block]
addAnchor Text
ident [Block]
jiraBlocks)

-- | Creates a Jira header
toJiraHeader :: PandocMonad m
             => Int -> Attr -> [Inline]
             -> JiraConverter m [Jira.Block]
toJiraHeader :: forall (m :: * -> *).
PandocMonad m =>
Int -> Attr -> [Inline] -> JiraConverter m [Block]
toJiraHeader Int
lvl (Text
ident, [Text]
_, [(Text, Text)]
_) [Inline]
inlines =
  let anchor :: Inline
anchor = Text -> Inline
Jira.Anchor Text
ident
  in forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Inline] -> Block
Jira.Header Int
lvl forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Inline
anchor forall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
inlines

-- | Handles raw block. Jira is included verbatim, everything else is
-- discarded.
rawBlockToJira :: PandocMonad m
               => Format -> Text
               -> JiraConverter m [Jira.Block]
rawBlockToJira :: forall (m :: * -> *).
PandocMonad m =>
Format -> Text -> JiraConverter m [Block]
rawBlockToJira Format
fmt Text
cs = do
  [Inline]
rawInlines <- forall (m :: * -> *).
PandocMonad m =>
Format -> Text -> JiraConverter m [Inline]
toJiraRaw Format
fmt Text
cs
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
rawInlines
    then forall a. Monoid a => a
mempty
    else forall a. a -> [a]
singleton ([Inline] -> Block
Jira.Para [Inline]
rawInlines)

toJiraRaw :: PandocMonad m
          => Format -> Text -> JiraConverter m [Jira.Inline]
toJiraRaw :: forall (m :: * -> *).
PandocMonad m =>
Format -> Text -> JiraConverter m [Inline]
toJiraRaw Format
fmt Text
cs = case Format
fmt of
  Format Text
"jira" -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ Text -> Inline
Jira.Str Text
cs
  Format
_             -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty


--
-- Inlines
--

toJiraInlines :: PandocMonad m => [Inline] -> JiraConverter m [Jira.Inline]
toJiraInlines :: forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
inlines = do
  let convert :: Inline -> JiraConverter m [Inline]
convert = \case
        Cite [Citation]
_ [Inline]
xs          -> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
xs
        Code Attr
_ Text
cs          -> forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$
                              [Inline] -> Inline
Jira.Monospaced (Text -> [Inline]
escapeSpecialChars Text
cs)
        Emph [Inline]
xs            -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Emphasis [Inline]
xs
        Underline [Inline]
xs       -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Insert [Inline]
xs
        Image Attr
attr [Inline]
cap (Text, Text)
tgt -> forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (forall (m :: * -> *).
PandocMonad m =>
Attr -> [Inline] -> Text -> Text -> JiraConverter m [Inline]
imageToJira Attr
attr [Inline]
cap) (Text, Text)
tgt
        Inline
LineBreak          -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ Inline
Jira.Linebreak
        Link Attr
attr [Inline]
xs (Text, Text)
tgt   -> forall (m :: * -> *).
PandocMonad m =>
Attr -> (Text, Text) -> [Inline] -> JiraConverter m [Inline]
toJiraLink Attr
attr (Text, Text)
tgt [Inline]
xs
        Math MathType
mtype Text
cs      -> forall (m :: * -> *).
PandocMonad m =>
MathType -> Text -> JiraConverter m [Inline]
mathToJira MathType
mtype Text
cs
        Note [Block]
bs            -> forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Inline]
registerNotes [Block]
bs
        Quoted QuoteType
qt [Inline]
xs       -> forall (m :: * -> *).
PandocMonad m =>
QuoteType -> [Inline] -> JiraConverter m [Inline]
quotedToJira QuoteType
qt [Inline]
xs
        RawInline Format
fmt Text
cs   -> forall (m :: * -> *).
PandocMonad m =>
Format -> Text -> JiraConverter m [Inline]
toJiraRaw Format
fmt Text
cs
        SmallCaps [Inline]
xs       -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Strong [Inline]
xs
        Inline
SoftBreak          -> do
                                Bool
preserveBreak <- forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks (forall a. Eq a => a -> a -> Bool
== WrapOption
WrapPreserve)
                                forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ if Bool
preserveBreak
                                  then Inline
Jira.Linebreak
                                  else Inline
Jira.Space
        Inline
Space              -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ Inline
Jira.Space
        Span Attr
attr [Inline]
xs       -> forall (m :: * -> *).
PandocMonad m =>
Attr -> [Inline] -> JiraConverter m [Inline]
spanToJira Attr
attr [Inline]
xs
        Str Text
s              -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Text -> [Inline]
escapeSpecialChars Text
s
        Strikeout [Inline]
xs       -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Strikeout [Inline]
xs
        Strong [Inline]
xs          -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Strong [Inline]
xs
        Subscript [Inline]
xs       -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Subscript [Inline]
xs
        Superscript [Inline]
xs     -> forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
Jira.Superscript [Inline]
xs
  [[Inline]]
jiraInlines <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Inline -> JiraConverter m [Inline]
convert [Inline]
inlines
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat [[Inline]]
jiraInlines

singleton :: a -> [a]
singleton :: forall a. a -> [a]
singleton = (forall a. a -> [a] -> [a]
:[])

styled :: PandocMonad m
       => Jira.InlineStyle -> [Inline]
       -> JiraConverter m [Jira.Inline]
styled :: forall (m :: * -> *).
PandocMonad m =>
InlineStyle -> [Inline] -> JiraConverter m [Inline]
styled InlineStyle
s = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. InlineStyle -> [Inline] -> Inline
Jira.Styled InlineStyle
s) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines

-- | Converts a plain text value to Jira inlines, ensuring that all
-- special characters will be handled appropriately.
escapeSpecialChars :: Text -> [Jira.Inline]
escapeSpecialChars :: Text -> [Inline]
escapeSpecialChars Text
t = case Text -> Either ParseError [Inline]
plainText Text
t of
  Right [Inline]
xs -> [Inline]
xs
  Left ParseError
_  -> forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ Text -> Inline
Jira.Str Text
t

imageToJira :: PandocMonad m
            => Attr -> [Inline] -> Text -> Text
            -> JiraConverter m [Jira.Inline]
imageToJira :: forall (m :: * -> *).
PandocMonad m =>
Attr -> [Inline] -> Text -> Text -> JiraConverter m [Inline]
imageToJira (Text
_, [Text]
classes, [(Text, Text)]
kvs) [Inline]
caption Text
src Text
title =
  let imageWithParams :: [Parameter] -> Inline
imageWithParams [Parameter]
ps = [Parameter] -> URL -> Inline
Jira.Image [Parameter]
ps (Text -> URL
Jira.URL Text
src)
      alt :: Text
alt = forall a. Walkable Inline a => a -> Text
stringify [Inline]
caption
  in forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Parameter] -> Inline
imageWithParams forall a b. (a -> b) -> a -> b
$
     if Text
"thumbnail" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes
     then [Text -> Text -> Parameter
Jira.Parameter Text
"thumbnail" Text
""]
     else forall a b. (a -> b) -> [a] -> [b]
map (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Text -> Text -> Parameter
Jira.Parameter)
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Text -> Bool
T.null Text
title then forall a. a -> a
id else ((Text
"title", Text
title)forall a. a -> [a] -> [a]
:))
          forall b c a. (b -> c) -> (a -> b) -> a -> c
. (if Text -> Bool
T.null Text
alt then forall a. a -> a
id else ((Text
"alt", Text
alt)forall a. a -> [a] -> [a]
:))
          forall a b. (a -> b) -> a -> b
$ [(Text, Text)]
kvs

-- | Creates a Jira Link element.
toJiraLink :: PandocMonad m
           => Attr
           -> Target
           -> [Inline]
           -> JiraConverter m [Jira.Inline]
toJiraLink :: forall (m :: * -> *).
PandocMonad m =>
Attr -> (Text, Text) -> [Inline] -> JiraConverter m [Inline]
toJiraLink (Text
_, [Text]
classes, [(Text, Text)]
_) (Text
url, Text
_) [Inline]
alias = do
  let (LinkType
linkType, Text
url') = Text -> (LinkType, Text)
toLinkType Text
url
  [Inline]
description <- if Text
url forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [forall a. Walkable Inline a => a -> Text
stringify [Inline]
alias, Text
"mailto:" forall a. Semigroup a => a -> a -> a
<> forall a. Walkable Inline a => a -> Text
stringify [Inline]
alias]
                 then forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Monoid a => a
mempty
                 else forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
alias
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall a b. (a -> b) -> a -> b
$ LinkType -> [Inline] -> URL -> Inline
Jira.Link LinkType
linkType [Inline]
description (Text -> URL
Jira.URL Text
url')
 where
  toLinkType :: Text -> (LinkType, Text)
toLinkType Text
url'
    | Just Text
email <- Text -> Text -> Maybe Text
T.stripPrefix Text
"mailto:" Text
url' = (LinkType
Jira.Email, Text
email)
    | Text
"user-account" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes              = (LinkType
Jira.User, Text -> Text
dropTilde Text
url)
    | Text
"attachment" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes                = (LinkType
Jira.Attachment, Text
url)
    | Text
"smart-card" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes                = (LinkType
Jira.SmartCard, Text
url)
    | Text
"smart-link" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes                = (LinkType
Jira.SmartLink, Text
url)
    | Bool
otherwise                                  = (LinkType
Jira.External, Text
url)
  dropTilde :: Text -> Text
dropTilde Text
txt = case Text -> Maybe (Char, Text)
T.uncons Text
txt of
    Just (Char
'~', Text
username) -> Text
username
    Maybe (Char, Text)
_                    -> Text
txt

mathToJira :: PandocMonad m
           => MathType
           -> Text
           -> JiraConverter m [Jira.Inline]
mathToJira :: forall (m :: * -> *).
PandocMonad m =>
MathType -> Text -> JiraConverter m [Inline]
mathToJira MathType
mtype Text
cs = do
  [Inline]
mathInlines <- forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *).
PandocMonad m =>
MathType -> Text -> m [Inline]
texMathToInlines MathType
mtype Text
cs
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ case MathType
mtype of
    MathType
InlineMath  -> [Inline]
mathInlines
    MathType
DisplayMath -> Inline
Jira.Linebreak forall a. a -> [a] -> [a]
: [Inline]
mathInlines forall a. [a] -> [a] -> [a]
++ [Inline
Jira.Linebreak]

quotedToJira :: PandocMonad m
             => QuoteType
             -> [Inline]
             -> JiraConverter m [Jira.Inline]
quotedToJira :: forall (m :: * -> *).
PandocMonad m =>
QuoteType -> [Inline] -> JiraConverter m [Inline]
quotedToJira QuoteType
qtype [Inline]
xs = do
  let quoteChar :: Text
quoteChar = case QuoteType
qtype of
                    QuoteType
DoubleQuote -> Text
"\""
                    QuoteType
SingleQuote -> Text
"'"
  let surroundWithQuotes :: [Inline] -> [Inline]
surroundWithQuotes = (Text -> Inline
Jira.Str Text
quoteChar forall a. a -> [a] -> [a]
:) forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. [a] -> [a] -> [a]
++ [Text -> Inline
Jira.Str Text
quoteChar])
  [Inline] -> [Inline]
surroundWithQuotes forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
xs

spanToJira :: PandocMonad m
           => Attr -> [Inline]
           -> JiraConverter m [Jira.Inline]
spanToJira :: forall (m :: * -> *).
PandocMonad m =>
Attr -> [Inline] -> JiraConverter m [Inline]
spanToJira (Text
ident, [Text]
_classes, [(Text, Text)]
attribs) [Inline]
inls =
  let wrap :: [Inline] -> [Inline]
wrap = case forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"color" [(Text, Text)]
attribs of
               Maybe Text
Nothing -> forall a. a -> a
id
               Just Text
color -> forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. ColorName -> [Inline] -> Inline
Jira.ColorInline (Text -> ColorName
Jira.ColorName Text
color)
  in [Inline] -> [Inline]
wrap forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case Text
ident of
    Text
"" -> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
inls
    Text
_  -> (Text -> Inline
Jira.Anchor Text
ident forall a. a -> [a] -> [a]
:) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
[Inline] -> JiraConverter m [Inline]
toJiraInlines [Inline]
inls

registerNotes :: PandocMonad m => [Block] -> JiraConverter m [Jira.Inline]
registerNotes :: forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m [Inline]
registerNotes [Block]
contents = do
  [Text]
curNotes <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets ConverterState -> [Text]
stNotes
  let newnum :: Int
newnum = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
curNotes forall a. Num a => a -> a -> a
+ Int
1
  Text
contents' <- forall (m :: * -> *).
PandocMonad m =>
[Block] -> JiraConverter m Text
blockListToJira [Block]
contents
  let thisnote :: Text
thisnote = Text
"\\[" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show Int
newnum) forall a. Semigroup a => a -> a -> a
<> Text
"] " forall a. Semigroup a => a -> a -> a
<> Text
contents' forall a. Semigroup a => a -> a -> a
<> Text
"\n"
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \ConverterState
s -> ConverterState
s { stNotes :: [Text]
stNotes = Text
thisnote forall a. a -> [a] -> [a]
: [Text]
curNotes }
  forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a]
singleton forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Inline
Jira.Str forall a b. (a -> b) -> a -> b
$
    Text
"[" forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack (forall a. Show a => a -> String
show Int
newnum) forall a. Semigroup a => a -> a -> a
<> Text
"]"

-- | Language codes recognized by jira
knownLanguages :: [Text]
knownLanguages :: [Text]
knownLanguages =
  [ Text
"actionscript", Text
"ada", Text
"applescript", Text
"bash", Text
"c", Text
"c#", Text
"c++"
  , Text
"css", Text
"erlang", Text
"go", Text
"groovy", Text
"haskell", Text
"html", Text
"java", Text
"javascript"
  , Text
"json", Text
"lua", Text
"nyan", Text
"objc", Text
"perl", Text
"php", Text
"python", Text
"r", Text
"ruby"
  , Text
"scala", Text
"sql", Text
"swift", Text
"visualbasic", Text
"xml", Text
"yaml"
  ]