{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
{- |
   Module      : Text.Pandoc.Writers.Jira
   Copyright   : © 2010-2019 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 Prelude
import Control.Monad.State.Strict
import Data.Foldable (find)
import Data.Text (Text, pack)
import Text.Pandoc.Class (PandocMonad, report)
import Text.Pandoc.Definition
import Text.Pandoc.Logging (LogMessage (BlockNotRendered, InlineNotRendered))
import Text.Pandoc.Options (WriterOptions (writerTemplate))
import Text.Pandoc.Shared (blocksToInlines, linesToPara)
import Text.Pandoc.Templates (renderTemplate)
import Text.Pandoc.Writers.Math (texMathToInlines)
import Text.Pandoc.Writers.Shared (metaToContext, defField)
import qualified Data.Text as T
import Text.DocLayout (literal, render)

data WriterState = WriterState
  { WriterState -> [Text]
stNotes     :: [Text]      -- Footnotes
  , WriterState -> Text
stListLevel :: Text        -- String at beginning of list items, e.g. "**"
  }

-- | Initial writer state
startState :: WriterState
startState :: WriterState
startState = WriterState :: [Text] -> Text -> WriterState
WriterState
  { stNotes :: [Text]
stNotes = []
  , stListLevel :: Text
stListLevel = ""
  }

type JiraWriter = StateT WriterState

-- | Convert Pandoc to Jira.
writeJira :: PandocMonad m => WriterOptions -> Pandoc -> m Text
writeJira :: WriterOptions -> Pandoc -> m Text
writeJira opts :: WriterOptions
opts document :: Pandoc
document =
  StateT WriterState m Text -> WriterState -> m Text
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (WriterOptions -> Pandoc -> StateT WriterState m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> JiraWriter m Text
pandocToJira WriterOptions
opts Pandoc
document) WriterState
startState

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

-- | Escape one character as needed for Jira.
escapeCharForJira :: Char -> Text
escapeCharForJira :: Char -> Text
escapeCharForJira c :: Char
c =
  let specialChars :: String
specialChars = "_*-+~^|!{}[]" :: String
  in case Char
c of
    '\x2013' -> " -- "
    '\x2014' -> " --- "
    '\x2026' -> "..."
    _ | Char
c Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
specialChars -> Char -> Text -> Text
T.cons '\\' (Char -> Text
T.singleton Char
c)
    _                         -> Char -> Text
T.singleton Char
c

-- | Escape string as needed for Jira.
escapeStringForJira :: Text -> Text
escapeStringForJira :: Text -> Text
escapeStringForJira = (Char -> Text) -> Text -> Text
T.concatMap Char -> Text
escapeCharForJira

-- | Create an anchor macro from the given element attributes.
anchor :: Attr -> Text
anchor :: Attr -> Text
anchor (ident :: Text
ident,_,_) =
  if Text
ident Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== ""
  then ""
  else "{anchor:" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ident Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "}"

-- | Append a newline character unless we are in a list.
appendNewlineUnlessInList :: PandocMonad m
                          => Text
                          -> JiraWriter m Text
appendNewlineUnlessInList :: Text -> JiraWriter m Text
appendNewlineUnlessInList t :: Text
t = do
  Text
listLevel <- (WriterState -> Text) -> JiraWriter m Text
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Text
stListLevel
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (if Text -> Bool
T.null Text
listLevel then Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "\n" else Text
t)

-- | Convert Pandoc block element to Jira.
blockToJira :: PandocMonad m
            => WriterOptions -- ^ Options
            -> Block         -- ^ Block element
            -> JiraWriter m Text

blockToJira :: WriterOptions -> Block -> JiraWriter m Text
blockToJira _ Null = Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return ""

blockToJira opts :: WriterOptions
opts (Div attr :: Attr
attr bs :: [Block]
bs) =
  (Attr -> Text
anchor Attr
attr Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> JiraWriter m Text -> JiraWriter m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterOptions -> [Block] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> JiraWriter m Text
blockListToJira WriterOptions
opts [Block]
bs

blockToJira opts :: WriterOptions
opts (Plain inlines :: [Inline]
inlines) =
  WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
inlines

blockToJira opts :: WriterOptions
opts (Para inlines :: [Inline]
inlines) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
inlines
  Text -> JiraWriter m Text
forall (m :: * -> *). PandocMonad m => Text -> JiraWriter m Text
appendNewlineUnlessInList Text
contents

blockToJira opts :: WriterOptions
opts (LineBlock lns :: [[Inline]]
lns) =
  WriterOptions -> Block -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> JiraWriter m Text
blockToJira WriterOptions
opts (Block -> JiraWriter m Text) -> Block -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ [[Inline]] -> Block
linesToPara [[Inline]]
lns

blockToJira _ b :: Block
b@(RawBlock f :: Format
f str :: Text
str) =
  if Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format "jira"
  then Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
str
  else "" Text -> StateT WriterState m () -> JiraWriter m Text
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ LogMessage -> StateT WriterState m ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (Block -> LogMessage
BlockNotRendered Block
b)

blockToJira _ HorizontalRule = Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return "----\n"

blockToJira opts :: WriterOptions
opts (Header level :: Int
level attr :: Attr
attr inlines :: [Inline]
inlines) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
inlines
  let prefix :: Text
prefix = "h" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (Int -> String
forall a. Show a => a -> String
show Int
level) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ". "
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Attr -> Text
anchor Attr
attr Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "\n"

blockToJira _ (CodeBlock attr :: Attr
attr@(_,classes :: [Text]
classes,_) str :: Text
str) = do
  let lang :: Maybe Text
lang = (Text -> Bool) -> [Text] -> Maybe Text
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\c :: Text
c -> Text -> Text
T.toLower Text
c Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
knownLanguages) [Text]
classes
  let start :: Text
start = case Maybe Text
lang of
                Nothing -> "{code}"
                Just l :: Text
l  -> "{code:" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
l Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "}"
  let anchorMacro :: Text
anchorMacro = Attr -> Text
anchor Attr
attr
  Text -> JiraWriter m Text
forall (m :: * -> *). PandocMonad m => Text -> JiraWriter m Text
appendNewlineUnlessInList (Text -> JiraWriter m Text)
-> ([Text] -> Text) -> [Text] -> JiraWriter m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate "\n" ([Text] -> JiraWriter m Text) -> [Text] -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$
    (if Text
anchorMacro Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== "" then [Text] -> [Text]
forall a. a -> a
id else (Text
anchorMacro Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:))
    [Text
start, Text
str, "{code}"]

blockToJira opts :: WriterOptions
opts (BlockQuote [p :: Block
p@(Para _)]) = do
  Text
contents <- WriterOptions -> Block -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> JiraWriter m Text
blockToJira WriterOptions
opts Block
p
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return ("bq. " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents)

blockToJira opts :: WriterOptions
opts (BlockQuote blocks :: [Block]
blocks) = do
  Text
contents <- WriterOptions -> [Block] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> JiraWriter m Text
blockListToJira WriterOptions
opts [Block]
blocks
  Text -> JiraWriter m Text
forall (m :: * -> *). PandocMonad m => Text -> JiraWriter m Text
appendNewlineUnlessInList (Text -> JiraWriter m Text)
-> ([Text] -> Text) -> [Text] -> JiraWriter m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
T.unlines ([Text] -> JiraWriter m Text) -> [Text] -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$
    [ "{quote}", Text
contents, "{quote}"]

blockToJira opts :: WriterOptions
opts (Table _caption :: [Inline]
_caption _aligns :: [Alignment]
_aligns _widths :: [Double]
_widths headers :: [[Block]]
headers rows :: [[[Block]]]
rows) = do
  [Text]
headerCells <- ([Block] -> JiraWriter m Text)
-> [[Block]] -> StateT WriterState m [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM [Block] -> JiraWriter m Text
forall (m :: * -> *). PandocMonad m => [Block] -> JiraWriter m Text
blocksToCell [[Block]]
headers
  [[Text]]
bodyRows    <- ([[Block]] -> StateT WriterState m [Text])
-> [[[Block]]] -> StateT WriterState m [[Text]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (([Block] -> JiraWriter m Text)
-> [[Block]] -> StateT WriterState m [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM [Block] -> JiraWriter m Text
forall (m :: * -> *). PandocMonad m => [Block] -> JiraWriter m Text
blocksToCell) [[[Block]]]
rows
  let tblHead :: Text
tblHead = [Text] -> Text
headerCellsToRow [Text]
headerCells
  let tblBody :: [Text]
tblBody = ([Text] -> Text) -> [[Text]] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Text] -> Text
cellsToRow [[Text]]
bodyRows
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ if ([Block] -> Bool) -> [[Block]] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all [Block] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
headers
           then [Text] -> Text
T.unlines [Text]
tblBody
           else [Text] -> Text
T.unlines (Text
tblHead Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
tblBody)
 where
  blocksToCell :: PandocMonad m => [Block] -> JiraWriter m Text
  blocksToCell :: [Block] -> JiraWriter m Text
blocksToCell = WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts ([Inline] -> JiraWriter m Text)
-> ([Block] -> [Inline]) -> [Block] -> JiraWriter m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Block] -> [Inline]
blocksToInlines

  cellsToRow :: [Text] -> Text
  cellsToRow :: [Text] -> Text
cellsToRow cells :: [Text]
cells = "|" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate "|" [Text]
cells Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "|"

  headerCellsToRow :: [Text] -> Text
  headerCellsToRow :: [Text] -> Text
headerCellsToRow cells :: [Text]
cells = "||" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> [Text] -> Text
T.intercalate "||" [Text]
cells Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "||"

blockToJira opts :: WriterOptions
opts (BulletList items :: [[Block]]
items) =
  WriterOptions -> [[Block]] -> Char -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [[Block]] -> Char -> JiraWriter m Text
listWithMarker WriterOptions
opts [[Block]]
items '*'

blockToJira opts :: WriterOptions
opts (OrderedList _listAttr :: ListAttributes
_listAttr items :: [[Block]]
items) =
  WriterOptions -> [[Block]] -> Char -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [[Block]] -> Char -> JiraWriter m Text
listWithMarker WriterOptions
opts [[Block]]
items '#'

blockToJira opts :: WriterOptions
opts (DefinitionList items :: [([Inline], [[Block]])]
items) =
  WriterOptions -> Block -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> JiraWriter m Text
blockToJira WriterOptions
opts ([[Block]] -> Block
BulletList ((([Inline], [[Block]]) -> [Block])
-> [([Inline], [[Block]])] -> [[Block]]
forall a b. (a -> b) -> [a] -> [b]
map ([Inline], [[Block]]) -> [Block]
defToBulletItem [([Inline], [[Block]])]
items))
 where
  defToBulletItem :: ([Inline], [[Block]]) -> [Block]
  defToBulletItem :: ([Inline], [[Block]]) -> [Block]
defToBulletItem (inlns :: [Inline]
inlns, defs :: [[Block]]
defs) =
    let term :: Block
term = [Inline] -> Block
Plain [[Inline] -> Inline
Strong [Inline]
inlns]
        blks :: [Block]
blks = [[Block]] -> [Block]
forall a. Monoid a => [a] -> a
mconcat [[Block]]
defs
    in Block
term Block -> [Block] -> [Block]
forall a. a -> [a] -> [a]
: [Block]
blks

-- Auxiliary functions for lists:

-- | Create a list using the given character as bullet item marker.
listWithMarker :: PandocMonad m
               => WriterOptions
               -> [[Block]]
               -> Char
               -> JiraWriter m Text
listWithMarker :: WriterOptions -> [[Block]] -> Char -> JiraWriter m Text
listWithMarker opts :: WriterOptions
opts items :: [[Block]]
items marker :: Char
marker = do
  (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \s :: WriterState
s -> WriterState
s { stListLevel :: Text
stListLevel = WriterState -> Text
stListLevel WriterState
s Text -> Char -> Text
`T.snoc` Char
marker }
  [Text]
contents <- ([Block] -> JiraWriter m Text)
-> [[Block]] -> StateT WriterState m [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (WriterOptions -> [Block] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> JiraWriter m Text
listItemToJira WriterOptions
opts) [[Block]]
items
  (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \s :: WriterState
s -> WriterState
s { stListLevel :: Text
stListLevel = Text -> Text
T.init (WriterState -> Text
stListLevel WriterState
s) }
  Text -> JiraWriter m Text
forall (m :: * -> *). PandocMonad m => Text -> JiraWriter m Text
appendNewlineUnlessInList (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ Text -> [Text] -> Text
T.intercalate "\n" [Text]
contents

-- | Convert bullet or ordered list item (list of blocks) to Jira.
listItemToJira :: PandocMonad m
               => WriterOptions
               -> [Block]
               -> JiraWriter m Text
listItemToJira :: WriterOptions -> [Block] -> JiraWriter m Text
listItemToJira opts :: WriterOptions
opts items :: [Block]
items = do
  Text
contents <- WriterOptions -> [Block] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> JiraWriter m Text
blockListToJira WriterOptions
opts [Block]
items
  Text
marker <- (WriterState -> Text) -> JiraWriter m Text
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Text
stListLevel
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ Text
marker Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> " " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents

-- | Convert list of Pandoc block elements to Jira.
blockListToJira :: PandocMonad m
                => WriterOptions -- ^ Options
                -> [Block]       -- ^ List of block elements
                -> JiraWriter m Text
blockListToJira :: WriterOptions -> [Block] -> JiraWriter m Text
blockListToJira opts :: WriterOptions
opts blocks :: [Block]
blocks =
  Text -> [Text] -> Text
T.intercalate "\n" ([Text] -> Text)
-> StateT WriterState m [Text] -> JiraWriter m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Block -> JiraWriter m Text)
-> [Block] -> StateT WriterState m [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (WriterOptions -> Block -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> JiraWriter m Text
blockToJira WriterOptions
opts) [Block]
blocks

-- | Convert list of Pandoc inline elements to Jira.
inlineListToJira :: PandocMonad m
                 => WriterOptions
                 -> [Inline]
                 -> JiraWriter m Text
inlineListToJira :: WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira opts :: WriterOptions
opts lst :: [Inline]
lst =
  [Text] -> Text
T.concat ([Text] -> Text)
-> StateT WriterState m [Text] -> JiraWriter m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Inline -> JiraWriter m Text)
-> [Inline] -> StateT WriterState m [Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (WriterOptions -> Inline -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> JiraWriter m Text
inlineToJira WriterOptions
opts) [Inline]
lst

-- | Convert Pandoc inline element to Jira.
inlineToJira :: PandocMonad m
             => WriterOptions
             -> Inline
             -> JiraWriter m Text

inlineToJira :: WriterOptions -> Inline -> JiraWriter m Text
inlineToJira opts :: WriterOptions
opts (Span attr :: Attr
attr lst :: [Inline]
lst) =
  (Attr -> Text
anchor Attr
attr Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) (Text -> Text) -> JiraWriter m Text -> JiraWriter m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst

inlineToJira opts :: WriterOptions
opts (Emph lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "_"

inlineToJira opts :: WriterOptions
opts (Strong lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "*" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "*"

inlineToJira opts :: WriterOptions
opts (Strikeout lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "-"

inlineToJira opts :: WriterOptions
opts (Superscript lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "{^" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "^}"

inlineToJira opts :: WriterOptions
opts (Subscript lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "{~" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "~}"

inlineToJira opts :: WriterOptions
opts (SmallCaps lst :: [Inline]
lst) = WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst

inlineToJira opts :: WriterOptions
opts (Quoted SingleQuote lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "'" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "'"

inlineToJira opts :: WriterOptions
opts (Quoted DoubleQuote lst :: [Inline]
lst) = do
  Text
contents <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "\"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "\""

inlineToJira opts :: WriterOptions
opts (Cite _  lst :: [Inline]
lst) = WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
lst

inlineToJira _ (Code attr :: Attr
attr str :: Text
str) =
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Attr -> Text
anchor Attr
attr Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "{{" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
str Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "}}")

inlineToJira _ (Str str :: Text
str) = Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
escapeStringForJira Text
str

inlineToJira opts :: WriterOptions
opts (Math InlineMath str :: Text
str) =
  m [Inline] -> StateT WriterState m [Inline]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (MathType -> Text -> m [Inline]
forall (m :: * -> *).
PandocMonad m =>
MathType -> Text -> m [Inline]
texMathToInlines MathType
InlineMath Text
str) StateT WriterState m [Inline]
-> ([Inline] -> JiraWriter m Text) -> JiraWriter m Text
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts

inlineToJira opts :: WriterOptions
opts (Math DisplayMath str :: Text
str) = do
  [Inline]
mathInlines <- m [Inline] -> StateT WriterState m [Inline]
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (MathType -> Text -> m [Inline]
forall (m :: * -> *).
PandocMonad m =>
MathType -> Text -> m [Inline]
texMathToInlines MathType
DisplayMath Text
str)
  Text
contents    <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
mathInlines
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "\\\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "\\\\"

inlineToJira _opts :: WriterOptions
_opts il :: Inline
il@(RawInline f :: Format
f str :: Text
str) =
  if Format
f Format -> Format -> Bool
forall a. Eq a => a -> a -> Bool
== Text -> Format
Format "jira"
  then Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
str
  else "" Text -> StateT WriterState m () -> JiraWriter m Text
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ LogMessage -> StateT WriterState m ()
forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report (Inline -> LogMessage
InlineNotRendered Inline
il)

inlineToJira _ LineBreak = Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return "\n"

inlineToJira _ SoftBreak = Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return " "

inlineToJira _ Space = Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return " "

inlineToJira opts :: WriterOptions
opts (Link _attr :: Attr
_attr txt :: [Inline]
txt (src :: Text
src, _title :: Text
_title)) = do
  Text
linkText <- WriterOptions -> [Inline] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> JiraWriter m Text
inlineListToJira WriterOptions
opts [Inline]
txt
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat
    [ "["
    , if [Inline] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
txt then "" else Text
linkText Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "|"
    , Text
src
    , "]"
    ]

inlineToJira _opts :: WriterOptions
_opts (Image attr :: Attr
attr _alt :: [Inline]
_alt (src :: Text
src, _title :: Text
_title)) =
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text)
-> ([Text] -> Text) -> [Text] -> JiraWriter m Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
T.concat ([Text] -> JiraWriter m Text) -> [Text] -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ [Attr -> Text
anchor Attr
attr, "!", Text
src, "!"]

inlineToJira opts :: WriterOptions
opts (Note contents :: [Block]
contents) = do
  [Text]
curNotes <- (WriterState -> [Text]) -> StateT WriterState m [Text]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> [Text]
stNotes
  let newnum :: Int
newnum = [Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
curNotes Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1
  Text
contents' <- WriterOptions -> [Block] -> JiraWriter m Text
forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> JiraWriter m Text
blockListToJira WriterOptions
opts [Block]
contents
  let thisnote :: Text
thisnote = "[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (Int -> String
forall a. Show a => a -> String
show Int
newnum) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "] " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contents' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "\n"
  (WriterState -> WriterState) -> StateT WriterState m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((WriterState -> WriterState) -> StateT WriterState m ())
-> (WriterState -> WriterState) -> StateT WriterState m ()
forall a b. (a -> b) -> a -> b
$ \s :: WriterState
s -> WriterState
s { stNotes :: [Text]
stNotes = Text
thisnote Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text]
curNotes }
  Text -> JiraWriter m Text
forall (m :: * -> *) a. Monad m => a -> m a
return (Text -> JiraWriter m Text) -> Text -> JiraWriter m Text
forall a b. (a -> b) -> a -> b
$ "[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
pack (Int -> String
forall a. Show a => a -> String
show Int
newnum) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> "]"

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