    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE Strict #-}
    {-# LANGUAGE TypeApplications #-}
    {- |
       Module      : Text.Pandoc.Writers.BBCode
       Copyright   : © 2025 Aleksey Myshko <git@crii.xyz>
       License     : GNU GPL, version 2 or above

       Maintainer  : Aleksey Myshko <git@crii.xyz>
       Stability   : alpha
       Portability : portable

    Conversion of 'Pandoc' documents to various BBCode flavors.
    -}

    module Text.Pandoc.Writers.BBCode (
      -- * Predefined writers
      -- Writers for different flavors of BBCode. 'writeBBCode' is a synonym for
      -- 'writeBBCode_official'
      writeBBCode,
      writeBBCodeOfficial,
      writeBBCodeSteam,
      writeBBCodePhpBB,
      writeBBCodeFluxBB,
      writeBBCodeHubzilla,
      writeBBCodeXenforo,

      -- * Extending the writer
      -- $extending
      FlavorSpec (..),
      WriterState (..),
      RR,
      writeBBCodeCustom,
      inlineToBBCode,
      inlineListToBBCode,
      blockToBBCode,
      blockListToBBCode,

      -- ** Handling attributes
      -- $wrapping_spans_divs
      attrToMap,

      -- * Predefined flavor specifications
      officialSpec,
      steamSpec,
      phpbbSpec,
      fluxbbSpec,
      hubzillaSpec,
      xenforoSpec,
    ) where

    import Control.Applicative (some)
    import Control.Monad (forM)
    import Control.Monad.Reader (MonadReader (..), ReaderT (..), asks)
    import Control.Monad.State (MonadState (..), StateT, evalStateT, gets, modify)
    import Data.Default (Default (..))
    import Data.Either (isRight)
    import Data.Foldable (toList)
    import Data.Map.Strict (Map)
    import qualified Data.Map.Strict as Map
    import Data.Maybe (fromMaybe, isJust)
    import Data.Sequence (Seq, (|>))
    import qualified Data.Sequence as Seq
    import Data.Text (Text)
    import qualified Data.Text as T
    import Text.DocLayout hiding (char, link, text)
    import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
    import Text.Pandoc.Definition
    import Text.Pandoc.Logging (LogMessage (..))
    import Text.Pandoc.Options (WriterOptions (..))
    import Text.Pandoc.Parsing (char, digit, eof, readWith)
    import Text.Pandoc.Shared (inquotes, onlySimpleTableCells, removeFormatting, trim, tshow)
    import Text.Pandoc.Templates (renderTemplate)
    import Text.Pandoc.URI (escapeURI)
    import Text.Pandoc.Writers.Shared (defField, metaToContext, toLegacyTable, unsmartify)
    import Text.Read (readMaybe)

    -- Type synonym to prevent haddock-generated HTML from overflowing
    type PandocTable =
      (Attr, Caption, [ColSpec], TableHead, [TableBody], TableFoot)

    -- $extending
    -- If you want to support more Pandoc elements (or render some of them
    -- differently) you can do so by creating your own 'FlavorSpec'
    --
    -- The module exports the @'FlavorSpec'@s underlying @writeBBCode_*@ functions,
    -- namely 'officialSpec', 'steamSpec', 'phpbbSpec', 'fluxbbSpec',
    -- 'hubzillaSpec'.
    --
    -- You can create and use your own renderers, for instance here we define a
    -- renderer for 'CodeBlock' and use it to create a derivative format:
    --
    -- > renderCodeBlockCustom :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    -- > renderCodeBlockCustom (_, cls, _) code = do
    -- >   let opening = case cls of
    -- >         (lang : _) -> "[code=" <> lang <> "]"
    -- >         ("c++" : _) -> "[code=cpp]"
    -- >         _ -> "[code]"
    -- >   pure $ mconcat [literal opening, literal code, cr, "[/code]"]
    -- >
    -- > specCustom = officialSpec{renderCodeBlock = renderCodeBlockCustom}
    --
    -- Then we can use it to render 'Pandoc' document via 'writeBBCode_custom'

    {- | Data type that is a collection of renderers for most elements in a Pandoc
    AST (see 'Block' and 'Inline')

    The intention here is to allow inheritance between formats, for instance if
    format A and format @B@ differ only in rendering tables, @B@ can be implemented
    as @A{'renderTable' = renderTableB}@
    -}
    data FlavorSpec = FlavorSpec
      { FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Block] -> RR m (Doc Text)
    renderBlockQuote ::
          forall m.
          (PandocMonad m) =>
          [Block] ->
          RR m (Doc Text)
      -- ^ Render 'BlockQuote'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [[Block]] -> RR m (Doc Text)
    renderBulletList ::
          forall m.
          (PandocMonad m) =>
          [[Block]] ->
          RR m (Doc Text)
      -- ^ Render 'BulletList'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> Text -> RR m (Doc Text)
    renderCodeBlock ::
          forall m.
          (PandocMonad m) =>
          Attr ->
          Text ->
          RR m (Doc Text)
      -- ^ Render 'CodeBlock'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionList ::
          forall m.
          (PandocMonad m) =>
          [([Inline], [[Block]])] ->
          RR m (Doc Text)
      -- ^ Render 'DefinitionList'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeader ::
          forall m.
          (PandocMonad m) =>
          Int ->
          Attr ->
          [Inline] ->
          RR m (Doc Text)
      -- ^ Render 'Header'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> Text -> RR m (Doc Text)
    renderInlineCode ::
          forall m.
          (PandocMonad m) =>
          Attr ->
          Text ->
          RR m (Doc Text)
      -- ^ Render 'Code'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLink ::
          forall m.
          (PandocMonad m) =>
          Attr ->
          [Inline] ->
          Target ->
          RR m (Doc Text)
      -- ^ Render 'Link'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedList ::
          forall m.
          (PandocMonad m) =>
          ListAttributes ->
          [[Block]] ->
          RR m (Doc Text)
      -- ^ Render 'OrderedList'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderStrikeout ::
          forall m.
          (PandocMonad m) =>
          [Inline] ->
          RR m (Doc Text)
      -- ^ Render 'Strikeout'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       PandocTable -> RR m (Doc Text)
    renderTable :: forall m. (PandocMonad m) => PandocTable -> RR m (Doc Text)
      -- ^ Render 'Table'
      , FlavorSpec
    -> forall (m :: * -> *). PandocMonad m => RR m (Doc Text)
    renderHorizontalRule ::
          forall m.
          (PandocMonad m) =>
          RR m (Doc Text)
      -- ^ Render 'HorizontalRule'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [[Inline]] -> RR m (Doc Text)
    renderLineBlock ::
          forall m.
          (PandocMonad m) =>
          [[Inline]] ->
          RR m (Doc Text)
      -- ^ Render 'LineBlock'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderPara ::
          forall m.
          (PandocMonad m) =>
          [Inline] ->
          RR m (Doc Text)
      -- ^ Render 'Para'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderSuperscript ::
          forall m.
          (PandocMonad m) =>
          [Inline] ->
          RR m (Doc Text)
      -- ^ Render 'Superscript'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderSubscript :: forall m. (PandocMonad m) => [Inline] -> RR m (Doc Text)
      -- ^ Render 'Subscript'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderSmallCaps :: forall m. (PandocMonad m) => [Inline] -> RR m (Doc Text)
      -- ^ Render 'SmallCaps'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Citation] -> [Inline] -> RR m (Doc Text)
    renderCite ::
          forall m.
          (PandocMonad m) =>
          [Citation] ->
          [Inline] ->
          RR m (Doc Text)
      -- ^ Render 'Cite'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Block] -> RR m (Doc Text)
    renderNote :: forall m. (PandocMonad m) => [Block] -> RR m (Doc Text)
      -- ^ Render 'Note'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> Caption -> [Block] -> RR m (Doc Text)
    renderFigure ::
          forall m.
          (PandocMonad m) =>
          Attr ->
          Caption ->
          [Block] ->
          RR m (Doc Text)
      -- ^ Render 'Figure'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       QuoteType -> [Inline] -> RR m (Doc Text)
    renderQuoted ::
          forall m.
          (PandocMonad m) =>
          QuoteType ->
          [Inline] ->
          RR m (Doc Text)
      -- ^ Render 'Quoted'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       MathType -> Text -> RR m (Doc Text)
    renderMath ::
          forall m.
          (PandocMonad m) =>
          MathType ->
          Text ->
          RR m (Doc Text)
      -- ^ Render 'Math'
      , FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImage ::
          forall m.
          (PandocMonad m) =>
          Attr ->
          [Inline] ->
          Target ->
          RR m (Doc Text)
      -- ^ Render 'Image'
      , FlavorSpec -> Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDiv :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
      -- ^ Wrap document in bbcode tags based on attributes/classes. Boolean flag
      -- indicates whether passed argument is a Div or a Span (True means Div)
      }

    data WriterState = WriterState
      { WriterState -> WriterOptions
    writerOptions :: WriterOptions
      , WriterState -> FlavorSpec
    flavorSpec :: FlavorSpec
      , WriterState -> Bool
    inList :: Bool
      }

    instance Default WriterState where
      def :: WriterState
    def =
        WriterState
          { writerOptions :: WriterOptions
    writerOptions = WriterOptions
    forall a. Default a => a
    def
          , flavorSpec :: FlavorSpec
    flavorSpec = FlavorSpec
    officialSpec
          , inList :: Bool
    inList = Bool
    False
          }

    -- | The base of a renderer monad.
    type RR m a = StateT (Seq (Doc Text)) (ReaderT WriterState m) a

    pandocToBBCode :: (PandocMonad m) => Pandoc -> RR m Text
    pandocToBBCode :: forall (m :: * -> *). PandocMonad m => Pandoc -> RR m Text
    pandocToBBCode (Pandoc Meta
    meta [Block]
    body) = do
      opts <- (WriterState -> WriterOptions)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) WriterOptions
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> WriterOptions
    writerOptions
      -- Run the rendering that mutates the state by producing footnotes
      bodyContents <- blockListToBBCode body
      -- Get the footnotes
      footnotes <- get
      -- Separate footnotes (if any) with a horizontal rule
      footnotesSep <-
        if null footnotes
          then pure empty
          else
            (\Doc Text
    hr -> Doc Text
    forall a. Doc a
    blankline Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    hr Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    forall a. Doc a
    blankline)
              <$> blockToBBCode HorizontalRule
      -- Put footnotes after the main text
      let docText = Doc Text
    bodyContents Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    footnotesSep Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vsep (Seq (Doc Text) -> [Doc Text]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    toList Seq (Doc Text)
    footnotes)
      metadata <- metaToContext opts blockListToBBCode inlineListToBBCode meta
      let context = Text -> Doc Text -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField Text
    "body" Doc Text
    docText Context Text
    metadata
      case writerTemplate opts of
        Just Template Text
    tpl -> Text -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Text -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text)
    -> Text -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall a b. (a -> b) -> a -> b
    $ Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing (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 -> Text -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Text -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text)
    -> Text -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall a b. (a -> b) -> a -> b
    $ Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    docText

    writeBBCode
      , writeBBCodeOfficial
      , writeBBCodeSteam
      , writeBBCodePhpBB
      , writeBBCodeFluxBB
      , writeBBCodeHubzilla
      , writeBBCodeXenforo ::
        (PandocMonad m) => WriterOptions -> Pandoc -> m Text
    writeBBCode :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCode = WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodeOfficial
    writeBBCodeOfficial :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodeOfficial = FlavorSpec -> WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    officialSpec
    writeBBCodeSteam :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodeSteam = FlavorSpec -> WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    steamSpec
    writeBBCodePhpBB :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodePhpBB = FlavorSpec -> WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    phpbbSpec
    writeBBCodeFluxBB :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodeFluxBB = FlavorSpec -> WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    fluxbbSpec
    writeBBCodeHubzilla :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodeHubzilla = FlavorSpec -> WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    hubzillaSpec
    writeBBCodeXenforo :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeBBCodeXenforo = FlavorSpec -> WriterOptions -> Pandoc -> m Text
    forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    xenforoSpec

    {- | Convert a 'Pandoc' document to BBCode using the given 'FlavorSpec' and
    'WriterOptions'.
    -}
    writeBBCodeCustom ::
      (PandocMonad m) => FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom :: forall (m :: * -> *).
    PandocMonad m =>
    FlavorSpec -> WriterOptions -> Pandoc -> m Text
    writeBBCodeCustom FlavorSpec
    spec WriterOptions
    opts Pandoc
    document =
      Seq (Doc Text) -> WriterState -> RR m Text -> m Text
    forall (m :: * -> *) a.
    Monad m =>
    Seq (Doc Text) -> WriterState -> RR m a -> m a
    runRR Seq (Doc Text)
    forall a. Monoid a => a
    mempty WriterState
    forall a. Default a => a
    def{writerOptions = opts, flavorSpec = spec} (RR m Text -> m Text) -> RR m Text -> m Text
    forall a b. (a -> b) -> a -> b
    $
        Pandoc -> RR m Text
    forall (m :: * -> *). PandocMonad m => Pandoc -> RR m Text
    pandocToBBCode Pandoc
    document
     where
      runRR :: (Monad m) => Seq (Doc Text) -> WriterState -> RR m a -> m a
      runRR :: forall (m :: * -> *) a.
    Monad m =>
    Seq (Doc Text) -> WriterState -> RR m a -> m a
    runRR Seq (Doc Text)
    footnotes WriterState
    writerState RR m a
    action =
        ReaderT WriterState m a -> WriterState -> m a
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT (RR m a -> Seq (Doc Text) -> ReaderT WriterState m a
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT RR m a
    action Seq (Doc Text)
    footnotes) WriterState
    writerState

    blockListToBBCode :: (PandocMonad m) => [Block] -> RR m (Doc Text)
    blockListToBBCode :: forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [Block]
    blocks =
      Doc Text -> Doc Text
    forall a. Doc a -> Doc a
    chomp (Doc Text -> Doc Text)
    -> ([Doc Text] -> Doc Text) -> [Doc Text] -> Doc Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vsep ([Doc Text] -> Doc Text)
    -> ([Doc Text] -> [Doc Text]) -> [Doc Text] -> Doc Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Doc Text -> Bool) -> [Doc Text] -> [Doc Text]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (Bool -> Bool
    not (Bool -> Bool) -> (Doc Text -> Bool) -> Doc Text -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Doc Text -> Bool
    forall a. Doc a -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null)
        ([Doc Text] -> Doc Text)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> [Block]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc 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 Block -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => Block -> RR m (Doc Text)
    blockToBBCode [Block]
    blocks

    blockToBBCode :: (PandocMonad m) => Block -> RR m (Doc Text)
    blockToBBCode :: forall (m :: * -> *). PandocMonad m => Block -> RR m (Doc Text)
    blockToBBCode Block
    block = do
      spec <- (WriterState -> FlavorSpec)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) FlavorSpec
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> FlavorSpec
    flavorSpec
      case block of
        Plain [Inline]
    inlines -> [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
        Para [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderPara FlavorSpec
    spec [Inline]
    inlines
        LineBlock [[Inline]]
    inliness -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [[Inline]] -> RR m (Doc Text)
    renderLineBlock FlavorSpec
    spec [[Inline]]
    inliness
        CodeBlock Attr
    attr Text
    code -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> Text -> RR m (Doc Text)
    renderCodeBlock FlavorSpec
    spec Attr
    attr Text
    code
        RawBlock Format
    format Text
    raw -> case Format
    format of
          Format
    "bbcode" -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    raw
          Format
    _ -> Doc Text
    "" Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) ()
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b.
    a
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) b
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> StateT (Seq (Doc Text)) (ReaderT WriterState m) ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Block -> LogMessage
    BlockNotRendered Block
    block)
        BlockQuote [Block]
    blocks -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Block] -> RR m (Doc Text)
    renderBlockQuote FlavorSpec
    spec [Block]
    blocks
        OrderedList ListAttributes
    attr [[Block]]
    items -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedList FlavorSpec
    spec ListAttributes
    attr [[Block]]
    items
        BulletList [[Block]]
    items -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [[Block]] -> RR m (Doc Text)
    renderBulletList FlavorSpec
    spec [[Block]]
    items
        DefinitionList [([Inline], [[Block]])]
    items -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionList FlavorSpec
    spec [([Inline], [[Block]])]
    items
        Header Int
    level Attr
    attr [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeader FlavorSpec
    spec Int
    level Attr
    attr [Inline]
    inlines
        Block
    HorizontalRule -> FlavorSpec
    -> forall (m :: * -> *). PandocMonad m => RR m (Doc Text)
    renderHorizontalRule FlavorSpec
    spec
        Table Attr
    attr Caption
    blkCapt [ColSpec]
    specs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot ->
          FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       PandocTable -> RR m (Doc Text)
    renderTable FlavorSpec
    spec (Attr
    attr, Caption
    blkCapt, [ColSpec]
    specs, TableHead
    thead, [TableBody]
    tbody, TableFoot
    tfoot)
        Figure Attr
    attr Caption
    caption [Block]
    blocks -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> Caption -> [Block] -> RR m (Doc Text)
    renderFigure FlavorSpec
    spec Attr
    attr Caption
    caption [Block]
    blocks
        Div Attr
    attr [Block]
    blocks -> do
          contents <- [Block]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [Block]
    blocks
          let kvcMap = Attr -> Map Text (Maybe Text)
    attrToMap Attr
    attr
          -- whether passed contents is a Div (Block) element
          --                      vvvv
          pure $ wrapSpanDiv spec True kvcMap contents

    inlineToBBCode :: (PandocMonad m) => Inline -> RR m (Doc Text)
    inlineToBBCode :: forall (m :: * -> *). PandocMonad m => Inline -> RR m (Doc Text)
    inlineToBBCode Inline
    inline = do
      spec <- (WriterState -> FlavorSpec)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) FlavorSpec
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> FlavorSpec
    flavorSpec
      case inline of
        Str Text
    str -> do
          opts <- (WriterState -> WriterOptions)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) WriterOptions
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterState -> WriterOptions
    writerOptions
          pure . literal $ unsmartify opts str
        Emph [Inline]
    inlines -> do
          contents <- [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
          pure $ mconcat ["[i]", contents, "[/i]"]
        Underline [Inline]
    inlines -> do
          contents <- [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
          pure $ mconcat ["[u]", contents, "[/u]"]
        Strong [Inline]
    inlines -> do
          contents <- [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
          pure $ mconcat ["[b]", contents, "[/b]"]
        Strikeout [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderStrikeout FlavorSpec
    spec [Inline]
    inlines
        Superscript [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderSuperscript FlavorSpec
    spec [Inline]
    inlines
        Subscript [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderSubscript FlavorSpec
    spec [Inline]
    inlines
        SmallCaps [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Inline] -> RR m (Doc Text)
    renderSmallCaps FlavorSpec
    spec [Inline]
    inlines
        Quoted QuoteType
    typ [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       QuoteType -> [Inline] -> RR m (Doc Text)
    renderQuoted FlavorSpec
    spec QuoteType
    typ [Inline]
    inlines
        Cite [Citation]
    cits [Inline]
    inlines -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Citation] -> [Inline] -> RR m (Doc Text)
    renderCite FlavorSpec
    spec [Citation]
    cits [Inline]
    inlines
        Code Attr
    attr Text
    code -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> Text -> RR m (Doc Text)
    renderInlineCode FlavorSpec
    spec Attr
    attr Text
    code
        Inline
    Space -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Doc Text
    forall a. Doc a
    space
        Inline
    SoftBreak -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Doc Text
    forall a. Doc a
    space
        Inline
    LineBreak -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Doc Text
    forall a. Doc a
    cr
        Math MathType
    typ Text
    math -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       MathType -> Text -> RR m (Doc Text)
    renderMath FlavorSpec
    spec MathType
    typ Text
    math
        RawInline (Format Text
    format) Text
    text -> case Text
    format of
          Text
    "bbcode" -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    text
          Text
    _ -> Doc Text
    "" Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) ()
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b.
    a
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) b
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> StateT (Seq (Doc Text)) (ReaderT WriterState m) ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Inline -> LogMessage
    InlineNotRendered Inline
    inline)
        Link Attr
    attr [Inline]
    txt Target
    target -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLink FlavorSpec
    spec Attr
    attr [Inline]
    txt Target
    target
        Image Attr
    attr [Inline]
    alt Target
    target -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImage FlavorSpec
    spec Attr
    attr [Inline]
    alt Target
    target
        Note [Block]
    blocks -> FlavorSpec
    -> forall (m :: * -> *).
       PandocMonad m =>
       [Block] -> RR m (Doc Text)
    renderNote FlavorSpec
    spec [Block]
    blocks
        Span Attr
    attr [Inline]
    inlines -> do
          contents <- [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
          let kvcMap = Attr -> Map Text (Maybe Text)
    attrToMap Attr
    attr
          -- whether passed contents is a Div (Block element)
          --                      vvvvv
          pure $ wrapSpanDiv spec False kvcMap contents

    renderImageDefault ::
      (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageDefault :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageDefault (Text
    _, [Text]
    _, [Target]
    kvList) [Inline]
    alt (Text
    source, Text
    title) = do
      altText <-
        Text -> Text
    trim (Text -> Text) -> (Doc Text -> Text) -> Doc Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . 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)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode ([Inline] -> [Inline]
    forall a. Walkable Inline a => a -> [Inline]
    removeFormatting [Inline]
    alt)
      let kvMap = [Target] -> Map Text Text
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [Target]
    kvList
      -- No BBCode flavor supported by the Writer has local images support, but we
      -- still allow source to be plain path or anything else
      pure . literal $
        mconcat
          [ "[img"
          , if T.null altText
              then ""
              else " alt=" <> inquotes altText
          , if T.null title
              then ""
              else " title=" <> inquotes title
          , case Map.lookup "width" kvMap of
              Just Text
    w
                | Maybe Int -> Bool
    forall a. Maybe a -> Bool
    isJust (forall a. Read a => String -> Maybe a
    readMaybe @Int (String -> Maybe Int) -> String -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    T.unpack Text
    w) ->
                    Text
    " width=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    inquotes Text
    w
              Maybe Text
    _ -> Text
    ""
          , case Map.lookup "height" kvMap of
              Just Text
    h
                | Maybe Int -> Bool
    forall a. Maybe a -> Bool
    isJust (forall a. Read a => String -> Maybe a
    readMaybe @Int (String -> Maybe Int) -> String -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $ Text -> String
    T.unpack Text
    h) ->
                    Text
    " height=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    inquotes Text
    h
              Maybe Text
    _ -> Text
    ""
          , "]"
          , source
          , "[/img]"
          ]

    renderImageOmit ::
      (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageOmit :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageOmit Attr
    _ [Inline]
    _ Target
    _ = Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Doc Text
    ""

    {- | Basic phpBB doesn't support any attributes, although
    @[img src=https://example.com]whatever[/img]@ is supported, but text in tag has
    no effect
    -}
    renderImagePhpBB ::
      (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImagePhpBB :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImagePhpBB Attr
    _ [Inline]
    _ (Text
    source, Text
    _) =
      Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> (Text -> Doc Text)
    -> Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat [Text
    "[img]", Text
    source, Text
    "[/img]"]

    renderImageXenforo ::
      (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageXenforo :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageXenforo (Text
    _, [Text]
    _, [Target]
    kvList) [Inline]
    alt (Text
    source, Text
    title) = do
      altText <-
        Text -> Text
    trim (Text -> Text) -> (Doc Text -> Text) -> Doc Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . 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)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode ([Inline] -> [Inline]
    forall a. Walkable Inline a => a -> [Inline]
    removeFormatting [Inline]
    alt)
      let kvMap = [Target] -> Map Text Text
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [Target]
    kvList
      -- No BBCode flavor supported by the Writer has local images support, but we
      -- still allow source to be plain path or anything else
      pure . literal $
        mconcat
          [ "[img"
          , if T.null altText
              then ""
              else " alt=" <> inquotes altText
          , if T.null title
              then ""
              else " title=" <> inquotes title
          , case Map.lookup "width" kvMap of
              Just Text
    w
                | Either PandocError () -> Bool
    forall a b. Either a b -> Bool
    isRight (Parsec Sources (Maybe (ZonkAny 0)) ()
    -> Maybe (ZonkAny 0) -> Text -> Either PandocError ()
    forall t st a.
    ToSources t =>
    Parsec Sources st a -> st -> t -> Either PandocError a
    readWith Parsec Sources (Maybe (ZonkAny 0)) ()
    forall {u}. ParsecT Sources u Identity ()
    sizeP Maybe (ZonkAny 0)
    forall a. Maybe a
    Nothing Text
    w) ->
                    Text
    " width=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    w
              Maybe Text
    _ -> Text
    ""
          , "]"
          , source
          , "[/img]"
          ]
     where
      sizeP :: ParsecT Sources u Identity ()
    sizeP = ParsecT Sources u Identity Char
    -> ParsecT Sources u Identity String
    forall a.
    ParsecT Sources u Identity a -> ParsecT Sources u Identity [a]
    forall (f :: * -> *) a. Alternative f => f a -> f [a]
    some ParsecT Sources u Identity Char
    forall (m :: * -> *) s u.
    (Monad m, Stream s m Char, UpdateSourcePos s Char) =>
    ParsecT s u m Char
    digit ParsecT Sources u Identity String
    -> ParsecT Sources u Identity Char
    -> ParsecT Sources u Identity Char
    forall a b.
    ParsecT Sources u Identity a
    -> ParsecT Sources u Identity b -> ParsecT Sources u Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Char -> ParsecT Sources u Identity Char
    forall (m :: * -> *) s u.
    (Monad m, Stream s m Char, UpdateSourcePos s Char) =>
    Char -> ParsecT s u m Char
    char Char
    '%' ParsecT Sources u Identity Char
    -> ParsecT Sources u Identity () -> ParsecT Sources u Identity ()
    forall a b.
    ParsecT Sources u Identity a
    -> ParsecT Sources u Identity b -> ParsecT Sources u Identity b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> ParsecT Sources u Identity ()
    forall s (m :: * -> *) t u.
    (Stream s m t, Show t) =>
    ParsecT s u m ()
    eof

    {- | Check whether character is a bracket

    >>> T.filter notBracket "[a]b[[ó]qü]]n®"
    "ab\243q\252n\174"
    -}
    notBracket :: Char -> Bool
    notBracket :: Char -> Bool
    notBracket = \case
      Char
    '[' -> Bool
    False
      Char
    ']' -> Bool
    False
      Char
    _ -> Bool
    True

    -- FluxBB uses [img=alt text] instead of [img alt="alt text"]
    renderImageFluxBB ::
      (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageFluxBB :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageFluxBB Attr
    _ [Inline]
    alt (Text
    source, Text
    _) = do
      alt' <- (Char -> Bool) -> Text -> Text
    T.filter Char -> Bool
    notBracket (Text -> Text) -> (Doc Text -> Text) -> Doc Text -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . 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)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    alt
      pure . literal $
        mconcat
          [ "[img"
          , if T.null alt'
              then ""
              else "=" <> alt'
          , "]"
          , source
          , "[/img]"
          ]

    inlineListToBBCode :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    inlineListToBBCode :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines = [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat ([Doc Text] -> Doc Text)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Inline
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc 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
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => Inline -> RR m (Doc Text)
    inlineToBBCode [Inline]
    inlines

    -- Taken from Data.Ord
    clamp :: (Ord a) => (a, a) -> a -> a
    clamp :: forall a. Ord a => (a, a) -> a -> a
    clamp (a
    low, a
    high) a
    a = a -> a -> a
    forall a. Ord a => a -> a -> a
    min a
    high (a -> a -> a
    forall a. Ord a => a -> a -> a
    max a
    a a
    low)

    renderHeaderDefault ::
      (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderDefault :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderDefault Int
    level Attr
    _attr [Inline]
    inlines =
      case (Int, Int) -> Int -> Int
    forall a. Ord a => (a, a) -> a -> a
    clamp (Int
    1, Int
    4) Int
    level of
        Int
    1 -> Inline -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Inline -> RR m (Doc Text)
    inlineToBBCode (Inline -> RR m (Doc Text)) -> Inline -> RR m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Inline
    Underline [[Inline] -> Inline
    Strong [Inline]
    inlines]
        Int
    2 -> Inline -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Inline -> RR m (Doc Text)
    inlineToBBCode (Inline -> RR m (Doc Text)) -> Inline -> RR m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Inline
    Strong [Inline]
    inlines
        Int
    3 -> Inline -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Inline -> RR m (Doc Text)
    inlineToBBCode (Inline -> RR m (Doc Text)) -> Inline -> RR m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Inline
    Underline [Inline]
    inlines
        Int
    _ -> [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines

    -- Adapted from Text.Pandoc.Writers.Org
    renderLinkDefault ::
      (PandocMonad m) => Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLinkDefault :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLinkDefault Attr
    _ [Inline]
    txt (Text
    src, Text
    _) =
      case [Inline]
    txt of
        [Str Text
    x]
          | Text -> Text
    escapeURI Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    src ->
              Doc Text -> RR m (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text -> RR m (Doc Text)) -> Doc Text -> RR m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Doc Text
    "[url]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    x Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/url]"
        [Inline]
    _ -> do
          contents <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    txt
          let suffix = if Text -> Bool
    T.null Text
    src then Text
    "" else Text
    "=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src
          pure $ "[url" <> literal suffix <> "]" <> contents <> "[/url]"

    renderCodeBlockDefault :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    renderCodeBlockDefault :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderCodeBlockDefault (Text
    _, [Text]
    cls, [Target]
    _) Text
    code = do
      let opening :: Text
    opening = case [Text]
    cls of
            (Text
    lang : [Text]
    _) -> Text
    "[code=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    lang Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
            [Text]
    _ -> Text
    "[code]"
      Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat [Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    opening, Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    code, Doc Text
    forall a. Doc a
    cr, Doc Text
    "[/code]"]

    renderCodeBlockSimple :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    renderCodeBlockSimple :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderCodeBlockSimple Attr
    _ Text
    code = do
      Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat [Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "[code]", Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    code, Doc Text
    forall a. Doc a
    cr, Doc Text
    "[/code]"]

    renderInlineCodeLiteral :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    renderInlineCodeLiteral :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderInlineCodeLiteral Attr
    _ Text
    code = Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    code

    renderInlineCodeNoParse :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    renderInlineCodeNoParse :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderInlineCodeNoParse Attr
    _ Text
    code =
      Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat [Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "[noparse]", Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    code, Doc Text
    "[/noparse]"]

    renderInlineCodeHubzilla :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    renderInlineCodeHubzilla :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderInlineCodeHubzilla Attr
    _ Text
    code =
      Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat [Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "[code]", Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    code, Doc Text
    "[/code]"]

    renderInlineCodeXenforo :: (PandocMonad m) => Attr -> Text -> RR m (Doc Text)
    renderInlineCodeXenforo :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderInlineCodeXenforo Attr
    _ Text
    code =
      Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Doc Text
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat [Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "[icode]", Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    code, Doc Text
    "[/icode]"]

    renderStrikeoutDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    renderStrikeoutDefault :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderStrikeoutDefault [Inline]
    inlines = do
      contents <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
      pure $ mconcat ["[s]", contents, "[/s]"]

    renderStrikeoutSteam :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    renderStrikeoutSteam :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderStrikeoutSteam [Inline]
    inlines = do
      contents <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
      pure $ mconcat ["[strike]", contents, "[/strike]"]

    renderDefinitionListDefault ::
      (PandocMonad m) => [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionListDefault :: forall (m :: * -> *).
    PandocMonad m =>
    [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionListDefault [([Inline], [[Block]])]
    items = do
      items' <- [([Inline], [[Block]])]
    -> (([Inline], [[Block]])
        -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [([Inline], [[Block]])]
    items ((([Inline], [[Block]])
      -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text])
    -> (([Inline], [[Block]])
        -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ \([Inline]
    term, [[Block]]
    definitions) -> do
        term' <- [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    term
        definitions' <- blockToBBCode (BulletList definitions)
        pure $ term' $$ definitions'
      pure $ vcat items'

    renderDefinitionListHubzilla ::
      (PandocMonad m) => [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionListHubzilla :: forall (m :: * -> *).
    PandocMonad m =>
    [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionListHubzilla [([Inline], [[Block]])]
    items = do
      items' <- [([Inline], [[Block]])]
    -> (([Inline], [[Block]])
        -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [([Inline], [[Block]])]
    items ((([Inline], [[Block]])
      -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text])
    -> (([Inline], [[Block]])
        -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ \([Inline]
    term, [[Block]]
    definitions) -> do
        term' <- [Inline]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    term
        let term'' = Doc Text
    "[*= " Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    term' Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "]"
        definitions' <- forM definitions blockListToBBCode
        pure $ vcat (term'' : definitions')
      pure $ vcat (literal "[dl terms=\"b\"]" : items' ++ [literal "[/dl]"])

    listWithTags ::
      (PandocMonad m) =>
      Text ->
      Text ->
      ([[Block]] -> RR m [Doc Text]) ->
      [[Block]] ->
      RR m (Doc Text)
    listWithTags :: forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    open Text
    close [[Block]] -> RR m [Doc Text]
    renderItems [[Block]]
    items = do
      contents <- (WriterState -> WriterState) -> RR m [Doc Text] -> RR m [Doc Text]
    forall a.
    (WriterState -> WriterState)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
    local (\WriterState
    s -> WriterState
    s{inList = True}) ([[Block]] -> RR m [Doc Text]
    renderItems [[Block]]
    items)
      pure $ vcat $ literal open : contents ++ [literal close]

    starListItems :: (PandocMonad m) => [[Block]] -> RR m [Doc Text]
    starListItems :: forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems [[Block]]
    items = [[Block]]
    -> ([Block]
        -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    t a -> (a -> m b) -> m (t b)
    forM [[Block]]
    items (([Block]
      -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text])
    -> ([Block]
        -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    forall a b. (a -> b) -> a -> b
    $ \[Block]
    item -> do
      item' <- [Block]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [Block]
    item
      pure $ literal "[*]" <> item'

    listStyleCode :: ListNumberStyle -> Maybe Text
    listStyleCode :: ListNumberStyle -> Maybe Text
    listStyleCode = \case
      ListNumberStyle
    Decimal -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "1"
      ListNumberStyle
    DefaultStyle -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "1"
      ListNumberStyle
    LowerAlpha -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "a"
      ListNumberStyle
    UpperAlpha -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "A"
      ListNumberStyle
    LowerRoman -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "i"
      ListNumberStyle
    UpperRoman -> Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "I"
      ListNumberStyle
    Example -> Maybe Text
    forall a. Maybe a
    Nothing

    renderBulletListOfficial :: (PandocMonad m) => [[Block]] -> RR m (Doc Text)
    renderBulletListOfficial :: forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m (Doc Text)
    renderBulletListOfficial = Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    "[list]" Text
    "[/list]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems

    renderBulletListHubzilla :: (PandocMonad m) => [[Block]] -> RR m (Doc Text)
    renderBulletListHubzilla :: forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m (Doc Text)
    renderBulletListHubzilla = Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    "[ul]" Text
    "[/ul]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems

    renderOrderedListHubzilla ::
      (PandocMonad m) => ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListHubzilla :: forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListHubzilla (Int
    _, ListNumberStyle
    style, ListNumberDelim
    _) = case ListNumberStyle
    style of
      ListNumberStyle
    DefaultStyle -> Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    "[ol]" Text
    "[/ol]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems
      ListNumberStyle
    Example -> Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    "[ol]" Text
    "[/ol]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems
      ListNumberStyle
    _ -> Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags (Text
    "[list=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    suffix Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Text
    "[/list]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems
     where
      suffix :: Text
    suffix = Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    "1" (Maybe Text -> Text) -> Maybe Text -> Text
    forall a b. (a -> b) -> a -> b
    $ ListNumberStyle -> Maybe Text
    listStyleCode ListNumberStyle
    style

    renderOrderedListOfficial ::
      (PandocMonad m) => ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListOfficial :: forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListOfficial (Int
    _, ListNumberStyle
    style, ListNumberDelim
    _) = do
      let suffix :: Text
    suffix = Text -> (Text -> Text) -> Maybe Text -> Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Text
    "" (Text
    "=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>) (ListNumberStyle -> Maybe Text
    listStyleCode ListNumberStyle
    style)
      Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags (Text
    "[list" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    suffix Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Text
    "[/list]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems

    renderOrderedListSteam ::
      (PandocMonad m) => ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListSteam :: forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListSteam ListAttributes
    _ =
      Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    "[olist]" Text
    "[/olist]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems

    renderHeaderSteam ::
      (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderSteam :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderSteam Int
    level Attr
    _ [Inline]
    inlines = do
      body <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
      let capped = (Int, Int) -> Int -> Int
    forall a. Ord a => (a, a) -> a -> a
    clamp (Int
    1, Int
    3) Int
    level
          open = Text
    "[h" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    capped Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
          close = Text
    "[/h" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    capped Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
      pure $ literal open <> body <> literal close

    renderHeaderHubzilla ::
      (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderHubzilla :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderHubzilla Int
    level Attr
    _ [Inline]
    inlines = do
      body <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
      let capped = (Int, Int) -> Int -> Int
    forall a. Ord a => (a, a) -> a -> a
    clamp (Int
    1, Int
    6) Int
    level
          open = Text
    "[h" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    capped Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
          close = Text
    "[/h" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    capped Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
      pure $ literal open <> body <> literal close

    -- xenForo supports levels 1--3, but levels other than 1--3 become div with
    -- .bbHeading class which can be linked to.
    renderHeaderXenforo ::
      (PandocMonad m) => Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderXenforo :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderXenforo Int
    level Attr
    _ [Inline]
    inlines = do
      body <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
      let capped = Int -> Int -> Int
    forall a. Ord a => a -> a -> a
    max Int
    1 Int
    level
          open = Text
    "[heading=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    capped Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
          close = Text
    "[/heading]"
      pure $ literal open <> body <> literal close

    renderTableGeneric ::
      (PandocMonad m) =>
      Text ->
      Text ->
      Text ->
      (Attr, Caption, [ColSpec], TableHead, [TableBody], TableFoot) ->
      RR m (Doc Text)
    renderTableGeneric :: forall (m :: * -> *).
    PandocMonad m =>
    Text -> Text -> Text -> PandocTable -> RR m (Doc Text)
    renderTableGeneric Text
    tableTag Text
    headerCellTag Text
    bodyCellTag PandocTable
    table = do
      caption' <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    caption
      table' <-
        if not simpleCells
          then "" <$ report (BlockNotRendered tableBlock)
          else do
            headerDocs <-
              if null headers
                then pure []
                else pure <$> renderTableRow headerCellTag headers
            rowDocs <- mapM (renderTableRow bodyCellTag) rows
            pure $ renderTable' headerDocs rowDocs
      pure $ caption' $$ table'
     where
      (Attr
    attr, Caption
    blkCapt, [ColSpec]
    specs, TableHead
    thead, [TableBody]
    tbody, TableFoot
    tfoot) = PandocTable
    table
      ([Inline]
    caption, [Alignment]
    _, [Double]
    _, [[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
      tableBlock :: Block
    tableBlock = Attr
    -> Caption
    -> [ColSpec]
    -> TableHead
    -> [TableBody]
    -> TableFoot
    -> Block
    Table Attr
    attr Caption
    blkCapt [ColSpec]
    specs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot
      simpleCells :: Bool
    simpleCells = [[[Block]]] -> Bool
    onlySimpleTableCells ([[Block]]
    headers [[Block]] -> [[[Block]]] -> [[[Block]]]
    forall a. a -> [a] -> [a]
    : [[[Block]]]
    rows)
      renderTable' :: [Doc Text] -> [Doc Text] -> Doc Text
    renderTable' [Doc Text]
    headerDocs [Doc Text]
    rowDocs =
        [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat
          [ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    tableTag Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]")
          , [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat [Doc Text]
    headerDocs
          , [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat [Doc Text]
    rowDocs
          , Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[/" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    tableTag Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]")
          ]
      renderCell :: a -> Doc a -> Doc a
    renderCell a
    cellTag Doc a
    cellDoc =
        [Doc a] -> Doc a
    forall a. Monoid a => [a] -> a
    mconcat
          [ a -> Doc a
    forall a. HasChars a => a -> Doc a
    literal (a
    "[" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    cellTag a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "]")
          , Doc a
    cellDoc
          , a -> Doc a
    forall a. HasChars a => a -> Doc a
    literal (a
    "[/" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    cellTag a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "]")
          ]
      renderTableRow :: Text
    -> [[Block]]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    renderTableRow Text
    cellTag [[Block]]
    cells = do
        renderedCells <- ([Block]
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> [[Block]]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc 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 [Block]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [[Block]]
    cells
        let cellsDoc = [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat ([Doc Text] -> Doc Text) -> [Doc Text] -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ (Doc Text -> Doc Text) -> [Doc Text] -> [Doc Text]
    forall a b. (a -> b) -> [a] -> [b]
    map (Text -> Doc Text -> Doc Text
    forall {a}. HasChars a => a -> Doc a -> Doc a
    renderCell Text
    cellTag) [Doc Text]
    renderedCells
        pure $ literal "[tr]" <> cellsDoc <> literal "[/tr]"

    renderTableDefault ::
      (PandocMonad m) =>
      ( Attr
      , Caption
      , [ColSpec]
      , TableHead
      , [TableBody]
      , TableFoot
      ) ->
      RR m (Doc Text)
    renderTableDefault :: forall (m :: * -> *).
    PandocMonad m =>
    PandocTable -> RR m (Doc Text)
    renderTableDefault = Text -> Text -> Text -> PandocTable -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> Text -> Text -> PandocTable -> RR m (Doc Text)
    renderTableGeneric Text
    "table" Text
    "th" Text
    "td"

    renderTableOmit ::
      (PandocMonad m) =>
      ( Attr
      , Caption
      , [ColSpec]
      , TableHead
      , [TableBody]
      , TableFoot
      ) ->
      RR m (Doc Text)
    renderTableOmit :: forall (m :: * -> *).
    PandocMonad m =>
    PandocTable -> RR m (Doc Text)
    renderTableOmit (Attr
    _, Caption
    blkCapt, [ColSpec]
    specs, TableHead
    thead, [TableBody]
    tbody, TableFoot
    tfoot) = do
      let ([Inline]
    caption, [Alignment]
    _, [Double]
    _, [[Block]]
    _, [[[Block]]]
    _) = Caption
    -> [ColSpec]
    -> TableHead
    -> [TableBody]
    -> TableFoot
    -> ([Inline], [Alignment], [Double], [[Block]], [[[Block]]])
    toLegacyTable Caption
    blkCapt [ColSpec]
    specs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot
      caption' <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    caption
      pure $ caption' $$ "(TABLE)"

    -- $wrapping_spans_divs
    -- Consider attribute a key-value pair with a Just value, and respectively
    -- class is key-value pair with Nothing value.
    -- For instance, given @("", ["cl1"], [("k", "v")]) :: 'Attr'@, respective Map
    -- should look like @'Map.fromList' [("cl1", 'Nothing'), ("k", 'Just' "v")]@
    --
    -- This transformation is handled by 'attrToMap'
    --
    -- Example definition of a wrapSpanDiv:
    --
    -- > {-# LANGUAGE OverloadedStrings #-}
    -- > import Data.Map (Map)
    -- > import qualified Data.Map as Map
    -- > import Text.DocLayout
    -- > import Data.Text (Text)
    -- > import qualified Data.Text as T
    -- >
    -- > wrapSpanDivSteam :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    -- > wrapSpanDivSteam isDiv kvc doc = Map.foldrWithKey wrap doc kvc
    -- >  where
    -- >   wrap "spoiler" (Just _) acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"
    -- >   wrap "spoiler" Nothing acc | isDiv = "[spoiler]" <> acc <> "[/spoiler]"
    -- >   wrap _ _ acc = acc
    --
    -- To verify it works, wrap some text in unnamed spoiler
    --
    -- >>> render Nothing $ wrapSpanDivSteam True (attrToMap ("", ["spoiler"], [])) "I am text"
    -- "[spoiler]I am text[/spoiler]"

    {- | The goal of the transformation is to treat classes and key-value pairs
    uniformly.

    Class list becomes Map where all values are Nothing, and list of key-value
    pairs is converted to Map via 'Map.toList'. Both Maps are then merged.
    -}
    attrToMap :: Attr -> Map Text (Maybe Text)
    attrToMap :: Attr -> Map Text (Maybe Text)
    attrToMap (Text
    _, [Text]
    classes, [Target]
    kvList) =
      [(Text, Maybe Text)] -> Map Text (Maybe Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [(Text, Maybe Text)]
    kvList' Map Text (Maybe Text)
    -> Map Text (Maybe Text) -> Map Text (Maybe Text)
    forall k a. Ord k => Map k a -> Map k a -> Map k a
    `Map.union` [(Text, Maybe Text)] -> Map Text (Maybe Text)
    forall k a. Ord k => [(k, a)] -> Map k a
    Map.fromList [(Text, Maybe Text)]
    forall {a}. [(Text, Maybe a)]
    classes'
     where
      kvList' :: [(Text, Maybe Text)]
    kvList' = (Target -> (Text, Maybe Text)) -> [Target] -> [(Text, Maybe Text)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\(Text
    k, Text
    v) -> (Text
    k, Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    v)) [Target]
    kvList
      classes' :: [(Text, Maybe a)]
    classes' = (Text -> (Text, Maybe a)) -> [Text] -> [(Text, Maybe a)]
    forall a b. (a -> b) -> [a] -> [b]
    map (\Text
    k -> (Text
    k, Maybe a
    forall a. Maybe a
    Nothing)) [Text]
    classes

    wrapSpanDivOfficial :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivOfficial :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivOfficial Bool
    isDiv Map Text (Maybe Text)
    kvc Doc Text
    doc = (Text -> Maybe Text -> Doc Text -> Doc Text)
    -> Doc Text -> Map Text (Maybe Text) -> Doc Text
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey Text -> Maybe Text -> Doc Text -> Doc Text
    forall {a}.
    (Eq a, IsString a) =>
    a -> Maybe Text -> Doc Text -> Doc Text
    wrap Doc Text
    doc Map Text (Maybe Text)
    kvc
     where
      wrap :: a -> Maybe Text -> Doc Text -> Doc Text
    wrap a
    "left" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[left]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/left]"
      wrap a
    "center" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[center]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/center]"
      wrap a
    "right" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[right]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/right]"
      wrap a
    "spoiler" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[spoiler]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/spoiler]"
      wrap a
    "spoiler" (Just Text
    v) Doc Text
    acc
        | Bool
    isDiv =
            Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[spoiler=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (Char -> Bool) -> Text -> Text
    T.filter Char -> Bool
    notBracket Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]")
              Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc
              Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/spoiler]"
      wrap a
    "size" (Just Text
    v) Doc Text
    acc
        | Just Int
    v' <- forall a. Read a => String -> Maybe a
    readMaybe @Int (Text -> String
    T.unpack Text
    v)
        , Int
    v' Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0 =
            Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[size=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/size]"
      wrap a
    "color" (Just Text
    v) Doc Text
    acc =
        Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[color=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/color]"
      wrap a
    _ Maybe Text
    _ Doc Text
    acc = Doc Text
    acc

    wrapSpanDivSteam :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivSteam :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivSteam Bool
    isDiv Map Text (Maybe Text)
    kvc Doc Text
    doc = (Text -> Maybe Text -> Doc Text -> Doc Text)
    -> Doc Text -> Map Text (Maybe Text) -> Doc Text
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey Text -> Maybe Text -> Doc Text -> Doc Text
    forall {a} {a} {a}.
    (Eq a, Semigroup a, IsString a, IsString a) =>
    a -> Maybe a -> a -> a
    wrap Doc Text
    doc Map Text (Maybe Text)
    kvc
     where
      wrap :: a -> Maybe a -> a -> a
    wrap a
    "spoiler" (Just a
    _) a
    acc | Bool
    isDiv = a
    "[spoiler]" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    acc a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "[/spoiler]"
      wrap a
    "spoiler" Maybe a
    Nothing a
    acc | Bool
    isDiv = a
    "[spoiler]" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    acc a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "[/spoiler]"
      wrap a
    _ Maybe a
    _ a
    acc = a
    acc

    wrapSpanDivPhpBB :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivPhpBB :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivPhpBB Bool
    _ Map Text (Maybe Text)
    kvc Doc Text
    doc = (Text -> Maybe Text -> Doc Text -> Doc Text)
    -> Doc Text -> Map Text (Maybe Text) -> Doc Text
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey Text -> Maybe Text -> Doc Text -> Doc Text
    forall {a} {a}.
    (Eq a, HasChars a, IsString a) =>
    a -> Maybe a -> Doc a -> Doc a
    wrap Doc Text
    doc Map Text (Maybe Text)
    kvc
     where
      wrap :: a -> Maybe a -> Doc a -> Doc a
    wrap a
    "color" (Just a
    v) Doc a
    acc =
        a -> Doc a
    forall a. HasChars a => a -> Doc a
    literal (a
    "[color=" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    v a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "]") Doc a -> Doc a -> Doc a
    forall a. Semigroup a => a -> a -> a
    <> Doc a
    acc Doc a -> Doc a -> Doc a
    forall a. Semigroup a => a -> a -> a
    <> Doc a
    "[/color]"
      wrap a
    _ Maybe a
    _ Doc a
    acc = Doc a
    acc

    wrapSpanDivFluxBB :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivFluxBB :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivFluxBB Bool
    _ Map Text (Maybe Text)
    kvc Doc Text
    doc = (Text -> Maybe Text -> Doc Text -> Doc Text)
    -> Doc Text -> Map Text (Maybe Text) -> Doc Text
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey Text -> Maybe Text -> Doc Text -> Doc Text
    forall {a} {a}.
    (Eq a, HasChars a, IsString a) =>
    a -> Maybe a -> Doc a -> Doc a
    wrap Doc Text
    doc Map Text (Maybe Text)
    kvc
     where
      wrap :: a -> Maybe a -> Doc a -> Doc a
    wrap a
    "color" (Just a
    v) Doc a
    acc =
        a -> Doc a
    forall a. HasChars a => a -> Doc a
    literal (a
    "[color=" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    v a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "]") Doc a -> Doc a -> Doc a
    forall a. Semigroup a => a -> a -> a
    <> Doc a
    acc Doc a -> Doc a -> Doc a
    forall a. Semigroup a => a -> a -> a
    <> Doc a
    "[/color]"
      wrap a
    _ Maybe a
    _ Doc a
    acc = Doc a
    acc

    wrapSpanDivHubzilla :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivHubzilla :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivHubzilla Bool
    isDiv Map Text (Maybe Text)
    kvc Doc Text
    doc = (Text -> Maybe Text -> Doc Text -> Doc Text)
    -> Doc Text -> Map Text (Maybe Text) -> Doc Text
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey Text -> Maybe Text -> Doc Text -> Doc Text
    forall {a}.
    (Eq a, IsString a) =>
    a -> Maybe Text -> Doc Text -> Doc Text
    wrap Doc Text
    doc Map Text (Maybe Text)
    kvc
     where
      wrap :: a -> Maybe Text -> Doc Text -> Doc Text
    wrap a
    "center" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[center]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/center]"
      wrap a
    "spoiler" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[spoiler]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/spoiler]"
      wrap a
    "spoiler" (Just Text
    v) Doc Text
    acc
        | Bool
    isDiv =
            Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[spoiler=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (Char -> Bool) -> Text -> Text
    T.filter Char -> Bool
    notBracket Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]")
              Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc
              Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/spoiler]"
      wrap a
    "size" (Just Text
    v) Doc Text
    acc
        | Just Int
    v' <- forall a. Read a => String -> Maybe a
    readMaybe @Int (Text -> String
    T.unpack Text
    v)
        , Int
    v' Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0 =
            Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[size=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/size]"
      wrap a
    "color" (Just Text
    v) Doc Text
    acc =
        Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[color=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/color]"
      wrap a
    "font" (Just Text
    v) Doc Text
    acc = Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[font=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/font]"
      wrap a
    _ Maybe Text
    _ Doc Text
    acc = Doc Text
    acc

    wrapSpanDivXenforo :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivXenforo :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivXenforo Bool
    isDiv Map Text (Maybe Text)
    kvc Doc Text
    doc = (Text -> Maybe Text -> Doc Text -> Doc Text)
    -> Doc Text -> Map Text (Maybe Text) -> Doc Text
    forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
    Map.foldrWithKey Text -> Maybe Text -> Doc Text -> Doc Text
    forall {a}.
    (Eq a, IsString a) =>
    a -> Maybe Text -> Doc Text -> Doc Text
    wrap Doc Text
    doc Map Text (Maybe Text)
    kvc
     where
      wrap :: a -> Maybe Text -> Doc Text -> Doc Text
    wrap a
    "left" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[left]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/left]"
      wrap a
    "center" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[center]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/center]"
      wrap a
    "right" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[right]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/right]"
      wrap a
    "spoiler" Maybe Text
    _ Doc Text
    acc | Bool -> Bool
    not Bool
    isDiv = Doc Text
    "[ispoiler]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/ispoiler]"
      wrap a
    "spoiler" Maybe Text
    Nothing Doc Text
    acc | Bool
    isDiv = Doc Text
    "[spoiler]" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/spoiler]"
      wrap a
    "spoiler" (Just Text
    v) Doc Text
    acc
        | Bool
    isDiv =
            Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[spoiler=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (Char -> Bool) -> Text -> Text
    T.filter Char -> Bool
    notBracket Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]")
              Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc
              Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/spoiler]"
      wrap a
    "size" (Just Text
    v) Doc Text
    acc
        | Just Int
    v' <- forall a. Read a => String -> Maybe a
    readMaybe @Int (Text -> String
    T.unpack Text
    v)
        , Int
    v' Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    0 =
            Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[size=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/size]"
      wrap a
    "color" (Just Text
    v) Doc Text
    acc =
        Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[color=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/color]"
      wrap a
    "font" (Just Text
    v) Doc Text
    acc = Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text
    "[font=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    v Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    acc Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    "[/font]"
      wrap a
    _ Maybe Text
    _ Doc Text
    acc = Doc Text
    acc

    renderOrderedListFluxbb ::
      (PandocMonad m) =>
      ListAttributes ->
      [[Block]] ->
      RR m (Doc Text)
    renderOrderedListFluxbb :: forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListFluxbb (Int
    _, ListNumberStyle
    style, ListNumberDelim
    _) =
      let suffix :: Text
    suffix = case ListNumberStyle
    style of
            ListNumberStyle
    LowerAlpha -> Text
    "=a"
            ListNumberStyle
    UpperAlpha -> Text
    "=a"
            ListNumberStyle
    _ -> Text
    "=1"
       in Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags (Text
    "[list" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    suffix Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]") Text
    "[/list]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems

    renderOrderedListXenforo ::
      (PandocMonad m) =>
      ListAttributes ->
      [[Block]] ->
      RR m (Doc Text)
    renderOrderedListXenforo :: forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListXenforo ListAttributes
    _ =
      Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text
    -> Text
    -> ([[Block]] -> RR m [Doc Text])
    -> [[Block]]
    -> RR m (Doc Text)
    listWithTags Text
    "[list=1]" Text
    "[/list]" [[Block]] -> RR m [Doc Text]
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m [Doc Text]
    starListItems

    renderLinkEmailAware ::
      (PandocMonad m) =>
      Attr ->
      [Inline] ->
      Target ->
      RR m (Doc Text)
    renderLinkEmailAware :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLinkEmailAware Attr
    attr [Inline]
    txt target :: Target
    target@(Text
    src, Text
    _) = do
      case Text -> Text -> Maybe Text
    T.stripPrefix Text
    "mailto:" Text
    src of
        Just Text
    address -> do
          linkText <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    txt
          let isAutoEmail = case [Inline]
    txt of
                [Str Text
    x] -> Text
    x Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    address
                [Inline]
    _ -> Bool
    False
          pure $
            if isAutoEmail
              then literal "[email]" <> literal address <> "[/email]"
              else literal ("[email=" <> address <> "]") <> linkText <> "[/email]"
        Maybe Text
    Nothing -> Attr -> [Inline] -> Target -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLinkDefault Attr
    attr [Inline]
    txt Target
    target

    renderBlockQuoteDefault :: (PandocMonad m) => [Block] -> RR m (Doc Text)
    renderBlockQuoteDefault :: forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderBlockQuoteDefault [Block]
    blocks = do
      contents <- [Block] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [Block]
    blocks
      pure $ vcat ["[quote]", contents, "[/quote]"]

    renderBlockQuoteFluxBB :: (PandocMonad m) => [Block] -> RR m (Doc Text)
    renderBlockQuoteFluxBB :: forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderBlockQuoteFluxBB [Block]
    blocks = do
      contents <- [Block] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [Block]
    blocks
      isInList <- asks inList
      if isInList
        then "" <$ report (BlockNotRendered $ BlockQuote blocks)
        else pure $ vcat ["[quote]", contents, "[/quote]"]

    renderHorizontalRuleDefault :: (PandocMonad m) => RR m (Doc Text)
    renderHorizontalRuleDefault :: forall (m :: * -> *). PandocMonad m => RR m (Doc Text)
    renderHorizontalRuleDefault = Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Doc Text
    "* * *"

    renderHorizontalRuleHR :: (PandocMonad m) => RR m (Doc Text)
    renderHorizontalRuleHR :: forall (m :: * -> *). PandocMonad m => RR m (Doc Text)
    renderHorizontalRuleHR = Doc Text
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall a. a -> StateT (Seq (Doc Text)) (ReaderT WriterState m) a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Doc Text
    "[hr]"

    renderLineBlockDefault :: (PandocMonad m) => [[Inline]] -> RR m (Doc Text)
    renderLineBlockDefault :: forall (m :: * -> *).
    PandocMonad m =>
    [[Inline]] -> RR m (Doc Text)
    renderLineBlockDefault [[Inline]]
    inliness = [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc Text]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ([Inline]
     -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text))
    -> [[Inline]]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) [Doc 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]
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [[Inline]]
    inliness

    renderParaDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    renderParaDefault :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderParaDefault [Inline]
    inlines = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines

    renderSuperscriptDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    renderSuperscriptDefault :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSuperscriptDefault = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode

    renderSubscriptDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    renderSubscriptDefault :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSubscriptDefault = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode

    renderSmallCapsDefault :: (PandocMonad m) => [Inline] -> RR m (Doc Text)
    renderSmallCapsDefault :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSmallCapsDefault = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode

    renderCiteDefault ::
      (PandocMonad m) => [Citation] -> [Inline] -> RR m (Doc Text)
    renderCiteDefault :: forall (m :: * -> *).
    PandocMonad m =>
    [Citation] -> [Inline] -> RR m (Doc Text)
    renderCiteDefault [Citation]
    _ = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode

    renderNoteDefault :: (PandocMonad m) => [Block] -> RR m (Doc Text)
    renderNoteDefault :: forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderNoteDefault [Block]
    blocks = do
      -- NOTE: no BBCode flavor has native syntax for footnotes.
      newN <- (Seq (Doc Text) -> Int)
    -> StateT (Seq (Doc Text)) (ReaderT WriterState m) Int
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (Int -> Int
    forall a. Enum a => a -> a
    succ (Int -> Int) -> (Seq (Doc Text) -> Int) -> Seq (Doc Text) -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Seq (Doc Text) -> Int
    forall a. Seq a -> Int
    Seq.length)
      contents <- blockListToBBCode blocks
      let pointer = Text
    "(" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    newN Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ")"
      let contents' = Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    pointer Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    forall a. Doc a
    space Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    contents
      modify (|> contents')
      pure $ literal pointer

    renderFigureDefault ::
      (PandocMonad m) => Attr -> Caption -> [Block] -> RR m (Doc Text)
    renderFigureDefault :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Caption -> [Block] -> RR m (Doc Text)
    renderFigureDefault Attr
    _ (Caption Maybe [Inline]
    _ [Block]
    caption) [Block]
    blocks = do
      caption' <- [Block] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    blockListToBBCode [Block]
    caption
      contents <- blockListToBBCode blocks
      pure $ contents $$ caption'

    renderQuotedDefault ::
      (PandocMonad m) => QuoteType -> [Inline] -> RR m (Doc Text)
    renderQuotedDefault :: forall (m :: * -> *).
    PandocMonad m =>
    QuoteType -> [Inline] -> RR m (Doc Text)
    renderQuotedDefault QuoteType
    typ [Inline]
    inlines = do
      let quote :: Doc Text
    quote = case QuoteType
    typ of QuoteType
    SingleQuote -> Doc Text
    "'"; QuoteType
    DoubleQuote -> Doc Text
    "\""
      contents <- [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    inlineListToBBCode [Inline]
    inlines
      pure $ mconcat [quote, contents, quote]

    renderMathDefault :: (PandocMonad m) => MathType -> Text -> RR m (Doc Text)
    renderMathDefault :: forall (m :: * -> *).
    PandocMonad m =>
    MathType -> Text -> RR m (Doc Text)
    renderMathDefault MathType
    typ Text
    math = case MathType
    typ of
      MathType
    InlineMath ->
        Inline -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Inline -> RR m (Doc Text)
    inlineToBBCode (Inline -> RR m (Doc Text)) -> Inline -> RR m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $
          Attr -> Text -> Inline
    Code (Text
    "", [Text
    "latex"], []) (Text
    "$" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    math Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "$")
      MathType
    DisplayMath ->
        Block -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => Block -> RR m (Doc Text)
    blockToBBCode (Block -> RR m (Doc Text)) -> Block -> RR m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $
          Attr -> Text -> Block
    CodeBlock (Text
    "", [Text
    "latex"], []) (Text
    "$$" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    math Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "$$")

    {- | Format documentation: <https://www.bbcode.org/reference.php>

    There is no such thing as «Official» bbcode format, nonetheless this spec
    implements what is described on bbcode.org, which is a reasonable base that can
    be extended/contracted as needed.
    -}
    officialSpec :: FlavorSpec
    officialSpec :: FlavorSpec
    officialSpec =
      FlavorSpec
        { renderOrderedList :: forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedList = ListAttributes -> [[Block]] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    ListAttributes -> [[Block]] -> RR m (Doc Text)
    renderOrderedListOfficial
        , renderBulletList :: forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m (Doc Text)
    renderBulletList = [[Block]] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [[Block]] -> RR m (Doc Text)
    renderBulletListOfficial
        , renderDefinitionList :: forall (m :: * -> *).
    PandocMonad m =>
    [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionList = [([Inline], [[Block]])] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [([Inline], [[Block]])] -> RR m (Doc Text)
    renderDefinitionListDefault
        , renderHeader :: forall (m :: * -> *).
    PandocMonad m =>
    Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeader = Int -> Attr -> [Inline] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Int -> Attr -> [Inline] -> RR m (Doc Text)
    renderHeaderDefault
        , renderTable :: forall (m :: * -> *).
    PandocMonad m =>
    PandocTable -> RR m (Doc Text)
    renderTable = PandocTable -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    PandocTable -> RR m (Doc Text)
    renderTableDefault
        , renderLink :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLink = Attr -> [Inline] -> Target -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderLinkEmailAware
        , renderCodeBlock :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderCodeBlock = Attr -> Text -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderCodeBlockDefault
        , renderInlineCode :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderInlineCode = Attr -> Text -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Text -> RR m (Doc Text)
    renderInlineCodeLiteral
        , renderStrikeout :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderStrikeout = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderStrikeoutDefault
        , renderBlockQuote :: forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderBlockQuote = [Block] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderBlockQuoteDefault
        , renderHorizontalRule :: forall (m :: * -> *). PandocMonad m => RR m (Doc Text)
    renderHorizontalRule = RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => RR m (Doc Text)
    renderHorizontalRuleDefault
        , renderLineBlock :: forall (m :: * -> *).
    PandocMonad m =>
    [[Inline]] -> RR m (Doc Text)
    renderLineBlock = [[Inline]] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [[Inline]] -> RR m (Doc Text)
    renderLineBlockDefault
        , renderPara :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderPara = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderParaDefault
        , renderSuperscript :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSuperscript = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSuperscriptDefault
        , renderSubscript :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSubscript = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSubscriptDefault
        , renderSmallCaps :: forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSmallCaps = [Inline] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Inline] -> RR m (Doc Text)
    renderSmallCapsDefault
        , renderCite :: forall (m :: * -> *).
    PandocMonad m =>
    [Citation] -> [Inline] -> RR m (Doc Text)
    renderCite = [Citation] -> [Inline] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Citation] -> [Inline] -> RR m (Doc Text)
    renderCiteDefault
        , renderNote :: forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderNote = [Block] -> RR m (Doc Text)
    forall (m :: * -> *). PandocMonad m => [Block] -> RR m (Doc Text)
    renderNoteDefault
        , renderFigure :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Caption -> [Block] -> RR m (Doc Text)
    renderFigure = Attr -> Caption -> [Block] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> Caption -> [Block] -> RR m (Doc Text)
    renderFigureDefault
        , renderMath :: forall (m :: * -> *).
    PandocMonad m =>
    MathType -> Text -> RR m (Doc Text)
    renderMath = MathType -> Text -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    MathType -> Text -> RR m (Doc Text)
    renderMathDefault
        , renderQuoted :: forall (m :: * -> *).
    PandocMonad m =>
    QuoteType -> [Inline] -> RR m (Doc Text)
    renderQuoted = QuoteType -> [Inline] -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    QuoteType -> [Inline] -> RR m (Doc Text)
    renderQuotedDefault
        , renderImage :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImage = Attr -> [Inline] -> Target -> RR m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> [Inline] -> Target -> RR m (Doc Text)
    renderImageDefault
        , wrapSpanDiv :: Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDiv = Bool -> Map Text (Maybe Text) -> Doc Text -> Doc Text
    wrapSpanDivOfficial
        }

    {- | Format documentation: <https://steamcommunity.com/comment/ForumTopic/formattinghelp>

    Used at: <https://steamcommunity.com/discussions/forum>

    Quirks:

    - There seems to be no way to show external images on steam.
      https://steamcommunity.com/sharedfiles/filedetails/?id=2807121939 shows [img]
      and [previewimg] can (could?) be used to show images, although it is likely
      reserved for steam urls only.
    -}
    steamSpec :: FlavorSpec
    steamSpec :: FlavorSpec
    steamSpec =
      FlavorSpec
    officialSpec
        { renderOrderedList = renderOrderedListSteam
        , renderHeader = renderHeaderSteam
        , renderLink = renderLinkDefault
        , renderInlineCode = renderInlineCodeNoParse
        , renderStrikeout = renderStrikeoutSteam
        , renderImage = renderImageOmit
        , wrapSpanDiv = wrapSpanDivSteam
        , renderHorizontalRule = renderHorizontalRuleHR
        }

    {- | Format documentation: <https://www.phpbb.com/community/help/bbcode>

    Used at: <https://www.phpbb.com/community>

    Quirks:

    - PhpBB docs don't mention strikeout support, but their
      [support forum](https://www.phpbb.com/community) does support it.
    - Same for named code blocks.
    - @[email=example\@example.com]the email[/url]@ is a valid use of [email]
      tag on the phpBB community forum despite not being in the docs.
    -}
    phpbbSpec :: FlavorSpec
    phpbbSpec :: FlavorSpec
    phpbbSpec =
      FlavorSpec
    officialSpec
        { renderTable = renderTableOmit
        , renderImage = renderImagePhpBB
        , wrapSpanDiv = wrapSpanDivPhpBB
        }

    {- | Format documentation: <https://web.archive.org/web/20210623155046/https://fluxbb.org/forums/help.php#bbcode>

    Used at: https://bbs.archlinux.org
    -}
    fluxbbSpec :: FlavorSpec
    fluxbbSpec :: FlavorSpec
    fluxbbSpec =
      FlavorSpec
    officialSpec
        { renderOrderedList = renderOrderedListFluxbb
        , renderCodeBlock = renderCodeBlockSimple
        , renderTable = renderTableOmit
        , renderBlockQuote = renderBlockQuoteFluxBB
        , renderImage = renderImageFluxBB
        , wrapSpanDiv = wrapSpanDivFluxBB
        }

    {- | Format documentation: <https://hubzilla.org/help/member/bbcode>

    Used at: <https://hub.netzgemeinde.eu> (see [other hubs](https://hubzilla.org/pubsites))

    Quirks:

    - If link target is not a URI, it simply points to https://$BASEURL/ when
      rendered by a hub.
    -}
    hubzillaSpec :: FlavorSpec
    hubzillaSpec :: FlavorSpec
    hubzillaSpec =
      FlavorSpec
    officialSpec
        { renderOrderedList = renderOrderedListHubzilla
        , renderBulletList = renderBulletListHubzilla
        , renderDefinitionList = renderDefinitionListHubzilla
        , renderHeader = renderHeaderHubzilla
        , renderInlineCode = renderInlineCodeHubzilla
        , renderLink = renderLinkDefault
        , wrapSpanDiv = wrapSpanDivHubzilla
        , renderHorizontalRule = renderHorizontalRuleHR
        }

    {- | Format documentation: <https://www.xenfocus.com/community/help/bb-codes/>

    Used at: see <https://xenforo.com/>
    -}
    xenforoSpec :: FlavorSpec
    xenforoSpec :: FlavorSpec
    xenforoSpec =
      FlavorSpec
    officialSpec
        { wrapSpanDiv = wrapSpanDivXenforo
        , renderHeader = renderHeaderXenforo
        , renderInlineCode = renderInlineCodeXenforo
        , renderHorizontalRule = renderHorizontalRuleHR
        , renderOrderedList = renderOrderedListXenforo
        , renderImage = renderImageXenforo
        }