    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE OverloadedStrings   #-}
    {- |
       Module      : Text.Pandoc.Writers.RTF
       Copyright   : Copyright (C) 2006-2024 John MacFarlane
       License     : GNU GPL, version 2 or above

       Maintainer  : John MacFarlane <jgm@berkeley.edu>
       Stability   : alpha
       Portability : portable

    Conversion of 'Pandoc' documents to RTF (rich text format).
    -}
    module Text.Pandoc.Writers.RTF ( writeRTF
                                   ) where
    import Control.Monad.Except (catchError, throwError)
    import Control.Monad
    import qualified Data.ByteString as B
    import Data.Char (chr, isDigit, ord, isAlphaNum)
    import qualified Data.Map as M
    import Data.Text (Text)
    import qualified Data.Text as T
    import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
    import qualified Text.Pandoc.Class.PandocMonad as P
    import Text.Pandoc.Definition
    import Text.Pandoc.Error
    import Text.Pandoc.ImageSize
    import Text.Pandoc.Logging
    import Text.Pandoc.Options
    import Text.Pandoc.Shared
    import Text.Pandoc.Templates (renderTemplate)
    import Text.DocLayout (render, literal)
    import Text.Pandoc.Walk
    import Text.Pandoc.Writers.Math
    import Text.Pandoc.Writers.Shared
    import Text.Printf (printf)

    -- | Convert Image inlines into a raw RTF embedded image, read from a file,
    -- or a MediaBag, or the internet.
    -- If file not found or filetype not jpeg or png, leave the inline unchanged.
    rtfEmbedImage :: PandocMonad m => WriterOptions -> Inline -> m Inline
    rtfEmbedImage :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Inline -> m Inline
    rtfEmbedImage WriterOptions
    opts x :: Inline
    x@(Image Attr
    attr [Inline]
    _ (Text
    src,Text
    _)) = m Inline -> (PandocError -> m Inline) -> m Inline
    forall a. m a -> (PandocError -> m a) -> m a
    forall e (m :: * -> *) a.
    MonadError e m =>
    m a -> (e -> m a) -> m a
    catchError
      (do result <- Text -> m (ByteString, Maybe Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> m (ByteString, Maybe Text)
    P.fetchItem Text
    src
          case result of
               (ByteString
    imgdata, Just Text
    mime)
                 | Text
    mime' <- (Char -> Bool) -> Text -> Text
    T.takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /=Char
    ';') Text
    mime
                 , Text
    mime' Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    "image/jpeg" Bool -> Bool -> Bool
    || Text
    mime' Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    "image/png" -> do
                 let bytes :: [Text]
    bytes = (Word8 -> Text) -> [Word8] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> Text
    T.pack (String -> Text) -> (Word8 -> String) -> Word8 -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Word8 -> String
    forall r. PrintfType r => String -> r
    printf String
    "%02x") ([Word8] -> [Text]) -> [Word8] -> [Text]
    forall a b. (a -> b) -> a -> b
    $ ByteString -> [Word8]
    B.unpack ByteString
    imgdata
                 filetype <-
                    case Text
    mime' of
                         Text
    "image/jpeg" -> Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    "\\jpegblip"
                         Text
    "image/png"  -> Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    "\\pngblip"
                         Text
    _            -> PandocError -> m Text
    forall a. PandocError -> m a
    forall e (m :: * -> *) a. MonadError e m => e -> m a
    throwError (PandocError -> m Text) -> PandocError -> m Text
    forall a b. (a -> b) -> a -> b
    $
                                             Text -> PandocError
    PandocShouldNeverHappenError (Text -> PandocError) -> Text -> PandocError
    forall a b. (a -> b) -> a -> b
    $
                                             Text
    "Unknown file type " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    mime
                 sizeSpec <-
                    case imageSize opts imgdata of
                         Left Text
    msg -> do
                           LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotDetermineImageSize Text
    src Text
    msg
                           Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    ""
                         Right ImageSize
    sz -> Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "\\picw" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Integer -> Text
    forall a. Show a => a -> Text
    tshow Integer
    xpx Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                                    Text
    "\\pich" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Integer -> Text
    forall a. Show a => a -> Text
    tshow Integer
    ypx Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                                    Text
    "\\picwgoal" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Integer -> Text
    forall a. Show a => a -> Text
    tshow (Double -> Integer
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (Double
    xpt Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    20) :: Integer)
                                    Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\pichgoal" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Integer -> Text
    forall a. Show a => a -> Text
    tshow (Double -> Integer
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (Double
    ypt Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    20) :: Integer)
                            -- twip = 1/1440in = 1/20pt
                            where (Integer
    xpx, Integer
    ypx) = ImageSize -> (Integer, Integer)
    sizeInPixels ImageSize
    sz
                                  (Double
    xpt, Double
    ypt) = WriterOptions -> Attr -> ImageSize -> (Double, Double)
    desiredSizeInPoints WriterOptions
    opts Attr
    attr ImageSize
    sz
                 let raw = Text
    "{\\pict" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    filetype Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    sizeSpec Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                            [Text] -> Text
    T.concat [Text]
    bytes Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "}"
                 if B.null imgdata
                    then do
                      report $ CouldNotFetchResource src "image contained no data"
                      return x
                    else return $ RawInline (Format "rtf") raw
                 | Bool
    otherwise -> do
                   LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotFetchResource Text
    src Text
    "image is not a jpeg or png"
                   Inline -> m Inline
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Inline
    x
               (ByteString
    _, Maybe Text
    Nothing) -> do
                 LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> LogMessage
    CouldNotDetermineMimeType Text
    src
                 Inline -> m Inline
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Inline
    x)
      (\PandocError
    e -> do
         LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> LogMessage
    CouldNotFetchResource Text
    src (Text -> LogMessage) -> Text -> LogMessage
    forall a b. (a -> b) -> a -> b
    $ PandocError -> Text
    forall a. Show a => a -> Text
    tshow PandocError
    e
         Inline -> m Inline
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Inline
    x)
    rtfEmbedImage WriterOptions
    _ Inline
    x = Inline -> m Inline
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Inline
    x

    -- | Convert Pandoc to a string in rich text format.
    writeRTF :: PandocMonad m => WriterOptions -> Pandoc -> m Text
    writeRTF :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeRTF WriterOptions
    options Pandoc
    doc = do
      -- handle images
      Pandoc meta@(Meta metamap) blocks <- (Inline -> m Inline) -> Pandoc -> m Pandoc
    forall a b (m :: * -> *).
    (Walkable a b, Monad m, Applicative m, Functor m) =>
    (a -> m a) -> b -> m b
    forall (m :: * -> *).
    (Monad m, Applicative m, Functor m) =>
    (Inline -> m Inline) -> Pandoc -> m Pandoc
    walkM (WriterOptions -> Inline -> m Inline
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Inline -> m Inline
    rtfEmbedImage WriterOptions
    options) Pandoc
    doc
      let spacer = Bool -> Bool
    not (Bool -> Bool) -> Bool -> Bool
    forall a b. (a -> b) -> a -> b
    $ ([Inline] -> Bool) -> [[Inline]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Inline] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null ([[Inline]] -> Bool) -> [[Inline]] -> Bool
    forall a b. (a -> b) -> a -> b
    $ Meta -> [Inline]
    docTitle Meta
    meta [Inline] -> [[Inline]] -> [[Inline]]
    forall a. a -> [a] -> [a]
    : Meta -> [Inline]
    docDate Meta
    meta [Inline] -> [[Inline]] -> [[Inline]]
    forall a. a -> [a] -> [a]
    : Meta -> [[Inline]]
    docAuthors Meta
    meta
      let toPlain (MetaBlocks [Para [Inline]
    ils]) = [Inline] -> MetaValue
    MetaInlines [Inline]
    ils
          toPlain MetaValue
    x                       = MetaValue
    x
      -- adjust title, author, date so we don't get para inside para
      let meta'  = Map Text MetaValue -> Meta
    Meta (Map Text MetaValue -> Meta) -> Map Text MetaValue -> Meta
    forall a b. (a -> b) -> a -> b
    $ (MetaValue -> MetaValue)
    -> Text -> Map Text MetaValue -> Map Text MetaValue
    forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
    M.adjust MetaValue -> MetaValue
    toPlain Text
    "title"
                        (Map Text MetaValue -> Map Text MetaValue)
    -> (Map Text MetaValue -> Map Text MetaValue)
    -> Map Text MetaValue
    -> Map Text MetaValue
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (MetaValue -> MetaValue)
    -> Text -> Map Text MetaValue -> Map Text MetaValue
    forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
    M.adjust MetaValue -> MetaValue
    toPlain Text
    "author"
                        (Map Text MetaValue -> Map Text MetaValue)
    -> (Map Text MetaValue -> Map Text MetaValue)
    -> Map Text MetaValue
    -> Map Text MetaValue
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (MetaValue -> MetaValue)
    -> Text -> Map Text MetaValue -> Map Text MetaValue
    forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
    M.adjust MetaValue -> MetaValue
    toPlain Text
    "date"
                        (Map Text MetaValue -> Map Text MetaValue)
    -> Map Text MetaValue -> Map Text MetaValue
    forall a b. (a -> b) -> a -> b
    $ Map Text MetaValue
    metamap
      metadata <- metaToContext options
                  (fmap (literal . T.concat) .
                    mapM (blockToRTF 0 AlignDefault))
                  (fmap literal . inlinesToRTF)
                  meta'
      body <- blocksToRTF 0 AlignDefault blocks
      toc <- blocksToRTF 0 AlignDefault [toTableOfContents options blocks]
      let context = Text -> Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField Text
    "body" Text
    body
                  (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Bool -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField Text
    "spacer" Bool
    spacer
                  (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ (if WriterOptions -> Bool
    writerTableOfContents WriterOptions
    options
                        then Text -> Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField Text
    "table-of-contents" Text
    toc
                             -- for backwards compatibility,
                             -- we populate toc with the contents
                             -- of the toc rather than a boolean:
                             (Context Text -> Context Text)
    -> (Context Text -> Context Text) -> Context Text -> Context Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField Text
    "toc" Text
    toc
                        else Context Text -> Context Text
    forall a. a -> a
    id) Context Text
    metadata
      return $
        case writerTemplate options of
           Just 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
           Maybe (Template Text)
    Nothing  -> case Text -> Maybe (Text, Char)
    T.unsnoc Text
    body of
                            Just (Text
    _,Char
    '\n') -> Text
    body
                            Maybe (Text, Char)
    _             -> Text
    body Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Char -> Text
    T.singleton Char
    '\n'

    -- | Convert unicode characters (> 127) into rich text format representation.
    handleUnicode :: Text -> Text
    handleUnicode :: Text -> Text
    handleUnicode = (Char -> Text) -> Text -> Text
    T.concatMap ((Char -> Text) -> Text -> Text) -> (Char -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ \Char
    c ->
      if Char -> Int
    ord Char
    c Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    127
         then if Char -> Bool
    surrogate Char
    c
              then let x :: Int
    x = Char -> Int
    ord Char
    c Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    0x10000
                       (Int
    q, Int
    r) = Int
    x Int -> Int -> (Int, Int)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Int
    0x400
                       upper :: Int
    upper = Int
    q Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    0xd800
                       lower :: Int
    lower = Int
    r Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    0xDC00
                   in Char -> Text
    enc (Int -> Char
    chr Int
    upper) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Char -> Text
    enc (Int -> Char
    chr Int
    lower)
              else Char -> Text
    enc Char
    c
         else Char -> Text
    T.singleton Char
    c
      where
        surrogate :: Char -> Bool
    surrogate Char
    x = Bool -> Bool
    not (   (Int
    0x0000 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char -> Int
    ord Char
    x Bool -> Bool -> Bool
    && Char -> Int
    ord Char
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    0xd7ff)
                           Bool -> Bool -> Bool
    || (Int
    0xe000 Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Char -> Int
    ord Char
    x Bool -> Bool -> Bool
    && Char -> Int
    ord Char
    x Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    0xffff) )
        enc :: Char -> Text
    enc Char
    x = Text
    "\\u" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow (Char -> Int
    ord Char
    x) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " ?"

    -- | Escape special characters.
    escapeSpecial :: Text -> Text
    escapeSpecial :: Text -> Text
    escapeSpecial Text
    t
      | (Char -> Bool) -> Text -> Bool
    T.all Char -> Bool
    isAlphaNum Text
    t = Text
    t
      | Bool
    otherwise          = (Char -> Text) -> Text -> Text
    T.concatMap Char -> Text
    escChar Text
    t
     where
      escChar :: Char -> Text
    escChar Char
    '\t' = Text
    "\\tab "
      escChar Char
    '\8216' = Text
    "\\u8216'"
      escChar Char
    '\8217' = Text
    "\\u8217'"
      escChar Char
    '\8220' = Text
    "\\u8220\""
      escChar Char
    '\8221' = Text
    "\\u8221\""
      escChar Char
    '\8211' = Text
    "\\u8211-"
      escChar Char
    '\8212' = Text
    "\\u8212-"
      escChar Char
    '{'     = Text
    "\\{"
      escChar Char
    '}'     = Text
    "\\}"
      escChar Char
    '\\'    = Text
    "\\\\"
      escChar Char
    c       = Char -> Text
    T.singleton Char
    c

    -- | Escape strings as needed for rich text format.
    stringToRTF :: Text -> Text
    stringToRTF :: Text -> Text
    stringToRTF = Text -> Text
    handleUnicode (Text -> Text) -> (Text -> Text) -> Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Text
    escapeSpecial

    -- | Escape things as needed for code block in RTF.
    codeStringToRTF :: Text -> Text
    codeStringToRTF :: Text -> Text
    codeStringToRTF Text
    str = Text -> [Text] -> Text
    T.intercalate Text
    "\\line\n" ([Text] -> Text) -> [Text] -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> [Text]
    T.lines (Text -> Text
    stringToRTF Text
    str)

    -- | Make a paragraph with first-line indent, block indent, and space after.
    rtfParSpaced :: Int       -- ^ space after (in twips)
                 -> Int       -- ^ block indent (in twips)
                 -> Int       -- ^ first line indent (relative to block) (in twips)
                 -> Alignment -- ^ alignment
                 -> Text    -- ^ string with content
                 -> Text
    rtfParSpaced :: Int -> Int -> Int -> Alignment -> Text -> Text
    rtfParSpaced Int
    spaceAfter Int
    indent Int
    firstLineIndent Alignment
    alignment Text
    content =
      let alignString :: Text
    alignString = case Alignment
    alignment of
                               Alignment
    AlignLeft    -> Text
    "\\ql "
                               Alignment
    AlignRight   -> Text
    "\\qr "
                               Alignment
    AlignCenter  -> Text
    "\\qc "
                               Alignment
    AlignDefault -> Text
    "\\ql "
      in  Text
    "{\\pard " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    alignString Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
          Text
    "\\f0 \\sa" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    spaceAfter Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " \\li" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> String -> Text
    T.pack (Int -> String
    forall a. Show a => a -> String
    show Int
    indent) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
          Text
    " \\fi" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    firstLineIndent Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    content Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\par}\n"

    -- | Default paragraph.
    rtfPar :: Int       -- ^ block indent (in twips)
           -> Int       -- ^ first line indent (relative to block) (in twips)
           -> Alignment -- ^ alignment
           -> Text    -- ^ string with content
           -> Text
    rtfPar :: Int -> Int -> Alignment -> Text -> Text
    rtfPar = Int -> Int -> Int -> Alignment -> Text -> Text
    rtfParSpaced Int
    180

    -- | Compact paragraph (e.g. for compact list items).
    rtfCompact ::  Int       -- ^ block indent (in twips)
               ->  Int       -- ^ first line indent (relative to block) (in twips)
               ->  Alignment -- ^ alignment
               ->  Text    -- ^ string with content
               ->  Text
    rtfCompact :: Int -> Int -> Alignment -> Text -> Text
    rtfCompact = Int -> Int -> Int -> Alignment -> Text -> Text
    rtfParSpaced Int
    0

    -- number of twips to indent
    indentIncrement :: Int
    indentIncrement :: Int
    indentIncrement = Int
    720

    listIncrement :: Int
    listIncrement :: Int
    listIncrement = Int
    360

    -- | Returns appropriate bullet list marker for indent level.
    bulletMarker :: Int -> Text
    bulletMarker :: Int -> Text
    bulletMarker Int
    indent = case Int
    indent Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    720 of
                                 Int
    0 -> Text
    "\\bullet "
                                 Int
    _ -> Text
    "\\endash "

    -- | Returns appropriate (list of) ordered list markers for indent level.
    orderedMarkers :: Int -> ListAttributes -> [Text]
    orderedMarkers :: Int -> ListAttributes -> [Text]
    orderedMarkers Int
    indent (Int
    start, ListNumberStyle
    style, ListNumberDelim
    delim) =
      if ListNumberStyle
    style ListNumberStyle -> ListNumberStyle -> Bool
    forall a. Eq a => a -> a -> Bool
    == ListNumberStyle
    DefaultStyle Bool -> Bool -> Bool
    && ListNumberDelim
    delim ListNumberDelim -> ListNumberDelim -> Bool
    forall a. Eq a => a -> a -> Bool
    == ListNumberDelim
    DefaultDelim
         then case Int
    indent Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    720 of
                  Int
    0 -> ListAttributes -> [Text]
    orderedListMarkers (Int
    start, ListNumberStyle
    Decimal, ListNumberDelim
    Period)
                  Int
    _ -> ListAttributes -> [Text]
    orderedListMarkers (Int
    start, ListNumberStyle
    LowerAlpha, ListNumberDelim
    Period)
         else ListAttributes -> [Text]
    orderedListMarkers (Int
    start, ListNumberStyle
    style, ListNumberDelim
    delim)

    blocksToRTF :: PandocMonad m
                => Int
                -> Alignment
                -> [Block]
                -> m Text
    blocksToRTF :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> [Block] -> m Text
    blocksToRTF Int
    indent Alignment
    align = ([Text] -> Text) -> m [Text] -> m Text
    forall a b. (a -> b) -> m a -> m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [Text] -> Text
    T.concat (m [Text] -> m Text) -> ([Block] -> m [Text]) -> [Block] -> m Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Block -> m Text) -> [Block] -> m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Int -> Alignment -> Block -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF Int
    indent Alignment
    align)

    -- | Convert Pandoc block element to RTF.
    blockToRTF :: PandocMonad m
               => Int       -- ^ indent level
               -> Alignment -- ^ alignment
               -> Block     -- ^ block to convert
               -> m Text
    blockToRTF :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF Int
    indent Alignment
    alignment (Div Attr
    _ [Block]
    bs) =
      Int -> Alignment -> [Block] -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> [Block] -> m Text
    blocksToRTF Int
    indent Alignment
    alignment [Block]
    bs
    blockToRTF Int
    indent Alignment
    alignment (Plain [Inline]
    lst) =
      Int -> Int -> Alignment -> Text -> Text
    rtfCompact Int
    indent Int
    0 Alignment
    alignment (Text -> Text) -> m Text -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
    blockToRTF Int
    indent Alignment
    alignment (Para [Inline]
    lst) =
      Int -> Int -> Alignment -> Text -> Text
    rtfPar Int
    indent Int
    0 Alignment
    alignment (Text -> Text) -> m Text -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
    blockToRTF Int
    indent Alignment
    alignment (LineBlock [[Inline]]
    lns) =
      Int -> Alignment -> Block -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF Int
    indent Alignment
    alignment (Block -> m Text) -> Block -> m Text
    forall a b. (a -> b) -> a -> b
    $ [[Inline]] -> Block
    linesToPara [[Inline]]
    lns
    blockToRTF Int
    indent Alignment
    alignment (BlockQuote [Block]
    lst) =
      Int -> Alignment -> [Block] -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> [Block] -> m Text
    blocksToRTF (Int
    indent Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    indentIncrement) Alignment
    alignment [Block]
    lst
    blockToRTF Int
    indent Alignment
    _ (CodeBlock Attr
    _ Text
    str) =
      Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> Alignment -> Text -> Text
    rtfPar Int
    indent Int
    0 Alignment
    AlignLeft (Text
    "\\f1 " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    codeStringToRTF Text
    str)
    blockToRTF Int
    _ Alignment
    _ b :: Block
    b@(RawBlock Format
    f Text
    str)
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format Text
    "rtf" = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      | Bool
    otherwise         = do
          LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ Block -> LogMessage
    BlockNotRendered Block
    b
          Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    ""
    blockToRTF Int
    indent Alignment
    alignment (BulletList [[Block]]
    lst) = Text -> Text
    spaceAtEnd (Text -> Text) -> ([Text] -> Text) -> [Text] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Text] -> Text
    T.concat ([Text] -> Text) -> m [Text] -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
      ([Block] -> m Text) -> [[Block]] -> m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Alignment -> Int -> Text -> [Block] -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Alignment -> Int -> Text -> [Block] -> m Text
    listItemToRTF Alignment
    alignment Int
    indent (Int -> Text
    bulletMarker Int
    indent)) [[Block]]
    lst
    blockToRTF Int
    indent Alignment
    alignment (OrderedList ListAttributes
    attribs [[Block]]
    lst) =
      Text -> Text
    spaceAtEnd (Text -> Text) -> ([Text] -> Text) -> [Text] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Text] -> Text
    T.concat ([Text] -> Text) -> m [Text] -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
       (Text -> [Block] -> m Text) -> [Text] -> [[Block]] -> m [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (Alignment -> Int -> Text -> [Block] -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Alignment -> Int -> Text -> [Block] -> m Text
    listItemToRTF Alignment
    alignment Int
    indent) (Int -> ListAttributes -> [Text]
    orderedMarkers Int
    indent ListAttributes
    attribs) [[Block]]
    lst
    blockToRTF Int
    indent Alignment
    alignment (DefinitionList [([Inline], [[Block]])]
    lst) = Text -> Text
    spaceAtEnd (Text -> Text) -> ([Text] -> Text) -> [Text] -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Text] -> Text
    T.concat ([Text] -> Text) -> m [Text] -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
      (([Inline], [[Block]]) -> m Text)
    -> [([Inline], [[Block]])] -> m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Alignment -> Int -> ([Inline], [[Block]]) -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Alignment -> Int -> ([Inline], [[Block]]) -> m Text
    definitionListItemToRTF Alignment
    alignment Int
    indent) [([Inline], [[Block]])]
    lst
    blockToRTF Int
    indent Alignment
    _ Block
    HorizontalRule = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $
      Int -> Int -> Alignment -> Text -> Text
    rtfPar Int
    indent Int
    0 Alignment
    AlignCenter Text
    "\\emdash\\emdash\\emdash\\emdash\\emdash"
    blockToRTF Int
    indent Alignment
    alignment (Header Int
    level Attr
    _ [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ rtfPar indent 0 alignment $
                 "\\outlinelevel" <> tshow (level - 1) <>
                 " \\b \\fs" <> tshow (40 - (level * 4)) <> " " <> contents
    blockToRTF Int
    indent Alignment
    alignment (Table Attr
    _ Caption
    blkCapt [ColSpec]
    specs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot) = do
      let ([Inline]
    caption, [Alignment]
    aligns, [Double]
    sizes, [[Block]]
    headers, [[[Block]]]
    rows) = Caption
    -> [ColSpec]
    -> TableHead
    -> [TableBody]
    -> TableFoot
    -> ([Inline], [Alignment], [Double], [[Block]], [[[Block]]])
    toLegacyTable Caption
    blkCapt [ColSpec]
    specs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot
      caption' <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    caption
      header' <- if all null headers
                    then return ""
                    else tableRowToRTF True indent aligns sizes headers
      rows' <- T.concat <$> mapM (tableRowToRTF False indent aligns sizes) rows
      return $ header' <> rows' <> rtfPar indent 0 alignment caption'
    blockToRTF Int
    indent Alignment
    alignment (Figure Attr
    attr Caption
    capt [Block]
    body) =
      Int -> Alignment -> Block -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF Int
    indent Alignment
    alignment (Block -> m Text) -> Block -> m Text
    forall a b. (a -> b) -> a -> b
    $ Attr -> Caption -> [Block] -> Block
    figureDiv Attr
    attr Caption
    capt [Block]
    body

    tableRowToRTF :: PandocMonad m
                  => Bool -> Int -> [Alignment] -> [Double] -> [[Block]] -> m Text
    tableRowToRTF :: forall (m :: * -> *).
    PandocMonad m =>
    Bool -> Int -> [Alignment] -> [Double] -> [[Block]] -> m Text
    tableRowToRTF Bool
    header Int
    indent [Alignment]
    aligns [Double]
    sizes' [[Block]]
    cols = do
      let totalTwips :: Double
    totalTwips = Double
    6 Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    1440 -- 6 inches
      let sizes :: [Double]
    sizes = if (Double -> Bool) -> [Double] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (Double -> Double -> Bool
    forall a. Eq a => a -> a -> Bool
    == Double
    0) [Double]
    sizes'
                     then Int -> Double -> [Double]
    forall a. Int -> a -> [a]
    replicate ([[Block]] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [[Block]]
    cols) (Double
    1.0 Double -> Double -> Double
    forall a. Fractional a => a -> a -> a
    / Int -> Double
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ([[Block]] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [[Block]]
    cols))
                     else [Double]
    sizes'
      columns <- [Text] -> Text
    T.concat ([Text] -> Text) -> m [Text] -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
         (Alignment -> [Block] -> m Text)
    -> [Alignment] -> [[Block]] -> m [Text]
    forall (m :: * -> *) a b c.
    Applicative m =>
    (a -> b -> m c) -> [a] -> [b] -> m [c]
    zipWithM (Int -> Alignment -> [Block] -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> [Block] -> m Text
    tableItemToRTF Int
    indent) [Alignment]
    aligns [[Block]]
    cols
      let rightEdges = Int -> [Integer] -> [Integer]
    forall a. Int -> [a] -> [a]
    drop Int
    1 ([Integer] -> [Integer]) -> [Integer] -> [Integer]
    forall a b. (a -> b) -> a -> b
    $
                        (Integer -> Double -> Integer) -> Integer -> [Double] -> [Integer]
    forall b a. (b -> a -> b) -> b -> [a] -> [b]
    scanl (\Integer
    sofar Double
    new -> Integer
    sofar Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Double -> Integer
    forall b. Integral b => Double -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (Double
    new Double -> Double -> Double
    forall a. Num a => a -> a -> a
    * Double
    totalTwips))
                              (Integer
    0 :: Integer) [Double]
    sizes
      let cellDefs = (Integer -> Text) -> [Integer] -> [Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Integer
    edge -> (if Bool
    header
                                       then Text
    "\\clbrdrb\\brdrs"
                                       else Text
    "") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\cellx" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Integer -> Text
    forall a. Show a => a -> Text
    tshow Integer
    edge)
                         [Integer]
    rightEdges
      let start = Text
    "{\n\\trowd \\trgaph120\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    T.concat [Text]
    cellDefs Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\n" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                  Text
    "\\trkeep\\intbl\n{\n"
      let end = Text
    "}\n\\intbl\\row}\n"
      return $ start <> columns <> end

    tableItemToRTF :: PandocMonad m => Int -> Alignment -> [Block] -> m Text
    tableItemToRTF :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> [Block] -> m Text
    tableItemToRTF Int
    indent Alignment
    alignment [Block]
    item = do
      contents <- Int -> Alignment -> [Block] -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> [Block] -> m Text
    blocksToRTF Int
    indent Alignment
    alignment [Block]
    item
      return $ "{" <> T.replace "\\pard" "\\pard\\intbl" contents <> "\\cell}\n"

    -- | Ensure that there's the same amount of space after compact
    -- lists as after regular lists.
    spaceAtEnd :: Text -> Text
    spaceAtEnd :: Text -> Text
    spaceAtEnd Text
    str = Text -> (Text -> Text) -> Maybe Text -> Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Text
    str (Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\sa180\\par}\n") (Maybe Text -> Text) -> Maybe Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> Maybe Text
    T.stripSuffix Text
    "\\par}\n" Text
    str

    -- | Convert list item (list of blocks) to RTF.
    listItemToRTF :: PandocMonad m
                  => Alignment  -- ^ alignment
                  -> Int        -- ^ indent level
                  -> Text     -- ^ list start marker
                  -> [Block]    -- ^ list item (list of blocks)
                  -> m Text
    listItemToRTF :: forall (m :: * -> *).
    PandocMonad m =>
    Alignment -> Int -> Text -> [Block] -> m Text
    listItemToRTF Alignment
    alignment Int
    indent Text
    marker [] = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $
      Int -> Int -> Alignment -> Text -> Text
    rtfCompact (Int
    indent Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    listIncrement) (Int -> Int
    forall a. Num a => a -> a
    negate Int
    listIncrement) Alignment
    alignment
                 (Text
    marker Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\tx" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    listIncrement Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\tab ")
    listItemToRTF Alignment
    alignment Int
    indent Text
    marker (Block
    listFirst:[Block]
    listRest) = do
      let f :: Block -> m Text
    f = Int -> Alignment -> Block -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF (Int
    indent Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    listIncrement) Alignment
    alignment
      first <- Block -> m Text
    f Block
    listFirst
      rest <- mapM f listRest
      let listMarker = Text
    "\\fi" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow (Int -> Int
    forall a. Num a => a -> a
    negate Int
    listIncrement) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    marker Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                       Text
    "\\tx" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    listIncrement Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\\tab"
      -- Find the first occurrence of \\fi or \\fi-, then replace it and the following
      -- digits with the list marker.
      let insertListMarker Text
    t = case Text -> Maybe Text
    popDigit (Text -> Maybe Text) -> Text -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    optionDash (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Int -> Text -> Text
    T.drop Int
    3 Text
    suff of
            Just Text
    suff' -> Text
    pref Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    listMarker Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (Char -> Bool) -> Text -> Text
    T.dropWhile Char -> Bool
    isDigit Text
    suff'
            Maybe Text
    Nothing    -> Text
    t
            where
              (Text
    pref, Text
    suff) = HasCallStack => Text -> Text -> (Text, Text)
    Text -> Text -> (Text, Text)
    T.breakOn Text
    "\\fi" Text
    t
              optionDash :: Text -> Text
    optionDash Text
    x = case Text -> Maybe (Char, Text)
    T.uncons Text
    x of
                Just (Char
    '-', Text
    xs) -> Text
    xs
                Maybe (Char, Text)
    _              -> Text
    x
              popDigit :: Text -> Maybe Text
    popDigit Text
    x
                | Just (Char
    d, Text
    xs) <- Text -> Maybe (Char, Text)
    T.uncons Text
    x
                , Char -> Bool
    isDigit Char
    d = Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    xs
                | Bool
    otherwise = Maybe Text
    forall a. Maybe a
    Nothing
       -- insert the list marker into the (processed) first block
      return $ insertListMarker first <> T.concat rest

    -- | Convert definition list item (label, list of blocks) to RTF.
    definitionListItemToRTF :: PandocMonad m
                            => Alignment          -- ^ alignment
                            -> Int                -- ^ indent level
                            -> ([Inline],[[Block]]) -- ^ list item (list of blocks)
                            -> m Text
    definitionListItemToRTF :: forall (m :: * -> *).
    PandocMonad m =>
    Alignment -> Int -> ([Inline], [[Block]]) -> m Text
    definitionListItemToRTF Alignment
    alignment Int
    indent ([Inline]
    label, [[Block]]
    defs) = do
      labelText <- Int -> Alignment -> Block -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF Int
    indent Alignment
    alignment ([Inline] -> Block
    Plain [Inline]
    label)
      itemsText <- blocksToRTF (indent + listIncrement) alignment (concat defs)
      return $ labelText <> itemsText

    -- | Convert list of inline items to RTF.
    inlinesToRTF :: PandocMonad m
                 => [Inline]   -- ^ list of inlines to convert
                 -> m Text
    inlinesToRTF :: forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst = [Text] -> Text
    T.concat ([Text] -> Text) -> m [Text] -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Inline -> m Text) -> [Inline] -> m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Inline -> m Text
    forall (m :: * -> *). PandocMonad m => Inline -> m Text
    inlineToRTF [Inline]
    lst

    -- | Convert inline item to RTF.
    inlineToRTF :: PandocMonad m
                => Inline         -- ^ inline to convert
                -> m Text
    inlineToRTF :: forall (m :: * -> *). PandocMonad m => Inline -> m Text
    inlineToRTF (Span Attr
    _ [Inline]
    lst) = [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
    inlineToRTF (Emph [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\i " <> contents <> "}"
    inlineToRTF (Underline [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\ul " <> contents <> "}"
    inlineToRTF (Strong [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\b " <> contents <> "}"
    inlineToRTF (Strikeout [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\strike " <> contents <> "}"
    inlineToRTF (Superscript [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\super " <> contents <> "}"
    inlineToRTF (Subscript [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\sub " <> contents <> "}"
    inlineToRTF (SmallCaps [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "{\\scaps " <> contents <> "}"
    inlineToRTF (Quoted QuoteType
    SingleQuote [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "\\u8216'" <> contents <> "\\u8217'"
    inlineToRTF (Quoted QuoteType
    DoubleQuote [Inline]
    lst) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
      return $ "\\u8220\"" <> contents <> "\\u8221\""
    inlineToRTF (Code Attr
    _ Text
    str) = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "{\\f1 " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    codeStringToRTF Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "}"
    inlineToRTF (Str Text
    str) = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    stringToRTF Text
    str
    inlineToRTF (Math MathType
    t Text
    str) = MathType -> Text -> m [Inline]
    forall (m :: * -> *).
    PandocMonad m =>
    MathType -> Text -> m [Inline]
    texMathToInlines MathType
    t Text
    str m [Inline] -> ([Inline] -> m Text) -> m Text
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF
    inlineToRTF (Cite [Citation]
    _ [Inline]
    lst) = [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    lst
    inlineToRTF il :: Inline
    il@(RawInline Format
    f Text
    str)
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format Text
    "rtf" = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    str
      | Bool
    otherwise         = do
          LogMessage -> m ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (LogMessage -> m ()) -> LogMessage -> m ()
    forall a b. (a -> b) -> a -> b
    $ Inline -> LogMessage
    InlineNotRendered Inline
    il
          Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    ""
    inlineToRTF Inline
    LineBreak = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    "\\line "
    inlineToRTF Inline
    SoftBreak = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    " "
    inlineToRTF Inline
    Space = Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    " "
    inlineToRTF (Link Attr
    _ [Inline]
    text (Text
    src, Text
    _)) = do
      contents <- [Inline] -> m Text
    forall (m :: * -> *). PandocMonad m => [Inline] -> m Text
    inlinesToRTF [Inline]
    text
      return $ "{\\field{\\*\\fldinst{HYPERLINK \"" <> codeStringToRTF src <>
        "\"}}{\\fldrslt{\\ul\n" <> contents <> "\n}}}\n"
    inlineToRTF (Image Attr
    _ [Inline]
    _ (Text
    source, Text
    _)) =
      Text -> m Text
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> m Text) -> Text -> m Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "{\\cf1 [image: " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    source Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]\\cf0}"
    inlineToRTF (Note [Block]
    contents) = do
      body <- [Text] -> Text
    T.concat ([Text] -> Text) -> m [Text] -> m Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> m Text) -> [Block] -> m [Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (Int -> Alignment -> Block -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Alignment -> Block -> m Text
    blockToRTF Int
    0 Alignment
    AlignDefault) [Block]
    contents
      return $ "{\\super\\chftn}{\\*\\footnote\\chftn\\~\\plain\\pard " <>
        body <> "}"