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

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

    Conversion of 'Pandoc' documents to MediaWiki markup.

    MediaWiki:  <http://www.mediawiki.org/wiki/MediaWiki>
    -}
    module Text.Pandoc.Writers.MediaWiki ( writeMediaWiki, highlightingLangs ) where
    import Control.Monad.Reader
    import Control.Monad.State.Strict
    import Data.Maybe (fromMaybe)
    import qualified Data.List as DL
    import qualified Data.Set as Set
    import Data.Text (Text)
    import qualified Data.Text as T
    import Data.List.NonEmpty (NonEmpty((:|)))
    import Text.Pandoc.Class.PandocMonad (PandocMonad, report)
    import Text.Pandoc.Definition
    import Text.Pandoc.ImageSize
    import Text.Pandoc.Logging
    import Text.Pandoc.Options
    import Text.DocLayout
    import Text.Pandoc.Shared
    import Text.Pandoc.URI
    import Text.Pandoc.Templates (renderTemplate)
    import qualified Text.Pandoc.Writers.AnnotatedTable as Ann
    import Text.Pandoc.Writers.Shared
    import Text.Pandoc.XML (escapeStringForXML)

    data WriterState = WriterState {
        WriterState -> Bool
    stNotes   :: Bool            -- True if there are notes
      , WriterState -> WriterOptions
    stOptions :: WriterOptions   -- writer options
      , WriterState -> Bool
    stInDefLabel :: Bool         -- True if in definition list label
      }

    data WriterReader = WriterReader {
        WriterReader -> WriterOptions
    options   :: WriterOptions -- Writer options
      , WriterReader -> [Char]
    listLevel :: [Char]        -- String at beginning of list items, e.g. "**"
      , WriterReader -> Bool
    useTags   :: Bool          -- True if we should use HTML tags because we're in a complex list
      }

    type MediaWikiWriter m = ReaderT WriterReader (StateT WriterState m)

    -- | Convert Pandoc to MediaWiki.
    writeMediaWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
    writeMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    WriterOptions -> Pandoc -> m Text
    writeMediaWiki WriterOptions
    opts Pandoc
    document =
      let initialState :: WriterState
    initialState = WriterState {
            stNotes :: Bool
    stNotes = Bool
    False, stOptions :: WriterOptions
    stOptions = WriterOptions
    opts, stInDefLabel :: Bool
    stInDefLabel = Bool
    False }
          env :: WriterReader
    env = WriterReader { options :: WriterOptions
    options = WriterOptions
    opts, listLevel :: [Char]
    listLevel = [], useTags :: Bool
    useTags = Bool
    False }
      in  StateT WriterState m Text -> WriterState -> m Text
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT (ReaderT WriterReader (StateT WriterState m) Text
    -> WriterReader -> StateT WriterState m Text
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
    runReaderT (Pandoc -> ReaderT WriterReader (StateT WriterState m) Text
    forall (m :: * -> *).
    PandocMonad m =>
    Pandoc -> MediaWikiWriter m Text
    pandocToMediaWiki Pandoc
    document) WriterReader
    env) WriterState
    initialState

    -- | Return MediaWiki representation of document.
    pandocToMediaWiki :: PandocMonad m => Pandoc -> MediaWikiWriter m Text
    pandocToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    Pandoc -> MediaWikiWriter m Text
    pandocToMediaWiki (Pandoc Meta
    meta [Block]
    blocks) = do
      opts <- (WriterReader -> WriterOptions)
    -> ReaderT WriterReader (StateT WriterState m) WriterOptions
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterReader -> WriterOptions
    options
      metadata <- metaToContext opts
                  (fmap chomp . blockListToMediaWiki)
                  (fmap chomp . inlineListToMediaWiki)
                  meta
      body <- blockListToMediaWiki blocks
      notesExist <- gets stNotes
      let notes = if Bool
    notesExist
                     then Doc Text
    forall a. Doc a
    cr 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
    "<references />"
                     else Doc Text
    forall a. Monoid a => a
    mempty
      let main = Doc Text
    body Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    notes
      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
    main
                    (Context Text -> Context Text) -> Context Text -> Context Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Bool -> Context Text -> Context Text
    forall a b. ToContext a b => Text -> b -> Context a -> Context a
    defField Text
    "toc" (WriterOptions -> Bool
    writerTableOfContents WriterOptions
    opts) Context Text
    metadata
      return $ render Nothing $
        case writerTemplate opts of
             Maybe (Template Text)
    Nothing  -> Doc Text
    main
             Just Template Text
    tpl -> Template Text -> Context Text -> Doc Text
    forall a b.
    (TemplateTarget a, ToContext a b) =>
    Template a -> b -> Doc a
    renderTemplate Template Text
    tpl Context Text
    context

    -- | Escape special characters for MediaWiki.
    escapeText :: Text -> Text
    escapeText :: Text -> Text
    escapeText =  Text -> Text
    escapeStringForXML

    -- | Convert Pandoc block element to MediaWiki.
    blockToMediaWiki :: PandocMonad m
                     => Block         -- ^ Block element
                     -> MediaWikiWriter m (Doc Text)

    blockToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    Block -> MediaWikiWriter m (Doc Text)
    blockToMediaWiki (Div Attr
    attrs [Block]
    bs) = do
      contents <- [Block] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    bs
      return $ tagWithAttrs "div" attrs $$
                contents $$
                literal "</div>" $$
                blankline

    blockToMediaWiki (Plain [Inline]
    inlines) =
      [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    inlines

    blockToMediaWiki (SimpleFigure Attr
    attr [Inline]
    txt (Text
    src, Text
    tit)) = do
      capt <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    txt
      img  <- imageToMediaWiki attr
      let capt' = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    capt
      let opt = if Text -> Bool
    T.null Text
    tit
                   then
                     if Text -> Bool
    T.null Text
    capt'
                        then Text
    ""
                        else Text
    "alt=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    capt'
                   else Text
    "alt=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    tit
      let separator = Text
    "<nowiki></nowiki>"
      -- External images (URIs) cannot use [[File:...]] syntax;
      -- they must be rendered as bare URLs. MediaWiki will auto-embed
      -- them when $wgAllowExternalImages is enabled.
      return $ if isURI src
               then literal (separator <> src <> separator) <> cr
               else literal ("[[" <>
                      T.intercalate "|"
                      (filter (not . T.null) ["File:" <> src
                                           , "thumb"
                                           , "none"
                                           , img
                                           , opt
                                           , capt'
                                           ]) <>
                      "]]") <> cr

    blockToMediaWiki (Para [Inline]
    inlines) = do
      tags <- (WriterReader -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterReader -> Bool
    useTags
      lev <- asks listLevel
      contents <- inlineListToMediaWiki inlines
      let contents' = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    contents
      let initEsc = if Text -> Bool
    startsWithListMarker Text
    contents'
                       then Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "<nowiki></nowiki>"
                       else Doc Text
    forall a. Monoid a => a
    mempty
      return $ if tags
                  then literal "<p>" <> contents <> literal "</p>"
                  else initEsc <> contents $$
                       if null lev then blankline else mempty

    blockToMediaWiki (LineBlock [[Inline]]
    lns) =
      Block -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Block -> MediaWikiWriter m (Doc Text)
    blockToMediaWiki (Block -> MediaWikiWriter m (Doc Text))
    -> Block -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ [[Inline]] -> Block
    linesToPara [[Inline]]
    lns

    blockToMediaWiki b :: Block
    b@(RawBlock Format
    f Text
    str)
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format Text
    "mediawiki" = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    str
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format Text
    "html"      = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    str
      | Bool
    otherwise               = Doc Text
    forall a. Monoid a => a
    mempty Doc Text
    -> ReaderT WriterReader (StateT WriterState m) ()
    -> MediaWikiWriter m (Doc Text)
    forall a b.
    a
    -> ReaderT WriterReader (StateT WriterState m) b
    -> ReaderT WriterReader (StateT WriterState m) a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> ReaderT WriterReader (StateT WriterState m) ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Block -> LogMessage
    BlockNotRendered Block
    b)

    blockToMediaWiki Block
    HorizontalRule = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Doc Text
    forall a. Doc a
    blankline 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
    "-----" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    forall a. Doc a
    blankline

    blockToMediaWiki (Header Int
    level (Text
    ident,[Text]
    _,[(Text, Text)]
    _) [Inline]
    inlines) = do
      let autoId :: Text
    autoId = HasCallStack => Text -> Text -> Text -> Text
    Text -> Text -> Text -> Text
    T.replace Text
    " " Text
    "_" (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ [Inline] -> Text
    forall a. Walkable Inline a => a -> Text
    stringify [Inline]
    inlines
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    inlines
      let eqs = Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Int -> Text -> Text
    T.replicate Int
    level Text
    "="
      return $
        (if T.null ident || autoId == ident
            then mempty
            else literal ("<span id=\"" <> ident <> "\"></span>") <> cr)
        <> eqs <> space <> contents <> space <> eqs <> blankline

    blockToMediaWiki (CodeBlock (Text
    _,[Text]
    classes,[(Text, Text)]
    keyvals) Text
    str) = do
      let at :: Set Text
    at  = [Text] -> Set Text
    forall a. Ord a => [a] -> Set a
    Set.fromList [Text]
    classes Set Text -> Set Text -> Set Text
    forall a. Ord a => Set a -> Set a -> Set a
    `Set.intersection` Set Text
    highlightingLangs
      let numberLines :: Bool
    numberLines = (Text -> Bool) -> [Text] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Text -> [Text] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [Text
    "number",Text
    "numberLines", Text
    "number-lines"])
                        [Text]
    classes
      let start :: Maybe Text
    start = Text -> [(Text, Text)] -> Maybe Text
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    lookup Text
    "startFrom" [(Text, Text)]
    keyvals
      Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $
        case Set Text -> [Text]
    forall a. Set a -> [a]
    Set.toList Set Text
    at of
           [] -> Text
    "<pre" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> (if [Text] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    classes
                               then Text
    ">"
                               else Text
    " class=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    T.unwords [Text]
    classes Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\">") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                 Text -> Text
    escapeText Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "</pre>"
           (Text
    l:[Text]
    _) -> Text
    "<syntaxhighlight lang=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                    (if Bool
    numberLines then Text
    " line" else Text
    "") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                    Text -> (Text -> Text) -> Maybe Text -> Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Text
    "" (\Text
    x -> Text
    " start=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    x Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\"") Maybe Text
    start Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                    Text
    ">" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                    Text
    "</syntaxhighlight>"
                -- note:  no escape!  even for <!

    blockToMediaWiki (BlockQuote [Block]
    blocks) = do
      contents <- [Block] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    blocks
      return $ literal "<blockquote>" <> chomp contents <> cr <> literal "</blockquote>"

    blockToMediaWiki (Table Attr
    attr Caption
    capt [ColSpec]
    colSpecs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot) = do
        Table -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Table -> MediaWikiWriter m (Doc Text)
    tableToMediaWiki (Attr
    -> Caption
    -> [ColSpec]
    -> TableHead
    -> [TableBody]
    -> TableFoot
    -> Table
    Ann.toTable Attr
    attr Caption
    capt [ColSpec]
    colSpecs TableHead
    thead [TableBody]
    tbody TableFoot
    tfoot)

    blockToMediaWiki x :: Block
    x@(BulletList [[Block]]
    items) = do
      tags <-
        (Bool -> Bool -> Bool
    || Bool -> Bool
    not (Block -> Bool
    isSimpleList Block
    x)) (Bool -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (WriterReader -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterReader -> Bool
    useTags
      if tags
         then do
            contents <- local (\ WriterReader
    s -> WriterReader
    s { useTags = True }) $ mapM listItemToMediaWiki items
            return $ literal "<ul>" <> cr <> vcat contents <> literal "</ul>" <> blankline
         else do
            lev <- asks listLevel
            contents <- local (\WriterReader
    s -> WriterReader
    s { listLevel = listLevel s <> "*" }) $ mapM listItemToMediaWiki items
            return $ vcat contents <> if null lev then blankline else mempty

    blockToMediaWiki x :: Block
    x@(OrderedList ListAttributes
    attribs [[Block]]
    items) = do
      tags <-
        (Bool -> Bool -> Bool
    || Bool -> Bool
    not (Block -> Bool
    isSimpleList Block
    x)) (Bool -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (WriterReader -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterReader -> Bool
    useTags
      if tags
         then do
            contents <- local (\WriterReader
    s -> WriterReader
    s { useTags = True }) $ mapM listItemToMediaWiki items
            return $ literal ("<ol" <> listAttribsToText attribs <> ">") <> cr <> vcat contents <> literal "</ol>" <> blankline
         else do
            lev <- asks listLevel
            contents <- local (\WriterReader
    s -> WriterReader
    s { listLevel = listLevel s <> "#" }) $ mapM listItemToMediaWiki items
            return $ vcat contents <> if null lev then blankline else mempty

    blockToMediaWiki x :: Block
    x@(DefinitionList [([Inline], [[Block]])]
    items) = do
      tags <-
        (Bool -> Bool -> Bool
    || Bool -> Bool
    not (Block -> Bool
    isSimpleList Block
    x)) (Bool -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (WriterReader -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks WriterReader -> Bool
    useTags
      if tags
         then do
            contents <- local (\WriterReader
    s -> WriterReader
    s { useTags = True }) $ mapM definitionListItemToMediaWiki items
            return $ literal "<dl>" <> cr <> vcat contents <> literal "</dl>" <> blankline
         else do
            lev <- asks listLevel
            contents <- local (\WriterReader
    s -> WriterReader
    s { listLevel = listLevel s <> ";" }) $ mapM definitionListItemToMediaWiki items
            return $ vcat contents <> if null lev then blankline else mempty

    blockToMediaWiki (Figure (Text
    ident, [Text]
    classes, [(Text, Text)]
    kvs) Caption
    _ [Block]
    body) =
      Block -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Block -> MediaWikiWriter m (Doc Text)
    blockToMediaWiki (Attr -> [Block] -> Block
    Div (Text
    ident, [Text
    "figure"] [Text] -> [Text] -> [Text]
    forall a. Eq a => [a] -> [a] -> [a]
    `DL.union` [Text]
    classes, [(Text, Text)]
    kvs) [Block]
    body)

    -- Auxiliary functions for lists:

    -- | Convert ordered list attributes to HTML attribute string
    listAttribsToText :: ListAttributes -> Text
    listAttribsToText :: ListAttributes -> Text
    listAttribsToText (Int
    startnum, ListNumberStyle
    numstyle, ListNumberDelim
    _) =
      let numstyle' :: Text
    numstyle' = Text -> Text
    camelCaseToHyphenated (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ ListNumberStyle -> Text
    forall a. Show a => a -> Text
    tshow ListNumberStyle
    numstyle
      in  (if Int
    startnum Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    1
              then Text
    " start=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    startnum Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\""
              else Text
    "") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
          (if ListNumberStyle
    numstyle ListNumberStyle -> ListNumberStyle -> Bool
    forall a. Eq a => a -> a -> Bool
    /= ListNumberStyle
    DefaultStyle
              then Text
    " style=\"list-style-type: " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    numstyle' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ";\""
              else Text
    "")

    -- | Convert bullet or ordered list item (list of blocks) to MediaWiki.
    listItemToMediaWiki :: PandocMonad m => [Block] -> MediaWikiWriter m (Doc Text)
    listItemToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    listItemToMediaWiki [Block]
    items = do
      contents <- [Block] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    items
      tags <- asks useTags
      if tags
         then return $ literal "<li>" <> chomp contents <> literal "</li>"
         else do
           marker <- asks listLevel
           return $ literal (T.pack marker) <> space <> chomp contents

    -- | Convert definition list item (label, list of blocks) to MediaWiki.
    definitionListItemToMediaWiki :: PandocMonad m
                                  => ([Inline],[[Block]])
                                  -> MediaWikiWriter m (Doc Text)
    definitionListItemToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    ([Inline], [[Block]]) -> MediaWikiWriter m (Doc Text)
    definitionListItemToMediaWiki ([Inline]
    label, [[Block]]
    items) = do
      (WriterState -> WriterState)
    -> ReaderT WriterReader (StateT WriterState m) ()
    forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
    modify ((WriterState -> WriterState)
     -> ReaderT WriterReader (StateT WriterState m) ())
    -> (WriterState -> WriterState)
    -> ReaderT WriterReader (StateT WriterState m) ()
    forall a b. (a -> b) -> a -> b
    $ \WriterState
    st -> WriterState
    st{ stInDefLabel = True }
      labelText <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    label
      modify $ \WriterState
    st -> WriterState
    st{ stInDefLabel = False }
      contents <- mapM blockListToMediaWiki items
      tags <- asks useTags
      if tags
         then return $ literal "<dt>" <> chomp labelText <> literal "</dt>" <> cr <>
               vcat (map (\Doc Text
    d -> Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "<dd>" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text -> Doc Text
    forall a. Doc a -> Doc a
    chomp Doc Text
    d 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
    "</dd>") contents)
         else do
           marker <- asks listLevel
           return $ literal (T.pack marker) <> space <> chomp labelText <> cr <>
               vcat (map (\Doc Text
    d -> Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal ([Char] -> Text
    T.pack ([Char] -> [Char]
    forall a. HasCallStack => [a] -> [a]
    init [Char]
    marker)) 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
    ": " Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text -> Doc Text
    forall a. Doc a -> Doc a
    chomp Doc Text
    d) contents)

    -- | True if the list can be handled by simple wiki markup, False if HTML tags will be needed.
    isSimpleList :: Block -> Bool
    isSimpleList :: Block -> Bool
    isSimpleList Block
    x =
      case Block
    x of
           BulletList [[Block]]
    items                 -> ([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    isSimpleListItem [[Block]]
    items
           OrderedList (Int
    num, ListNumberStyle
    sty, ListNumberDelim
    _) [[Block]]
    items  -> ([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    isSimpleListItem [[Block]]
    items Bool -> Bool -> Bool
    &&
                                                Int
    num Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    1 Bool -> Bool -> Bool
    && ListNumberStyle
    sty ListNumberStyle -> [ListNumberStyle] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [ListNumberStyle
    DefaultStyle, ListNumberStyle
    Decimal]
           DefinitionList [([Inline], [[Block]])]
    items             -> ([Block] -> Bool) -> [[Block]] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all [Block] -> Bool
    isSimpleListItem ([[Block]] -> Bool) -> [[Block]] -> Bool
    forall a b. (a -> b) -> a -> b
    $ (([Inline], [[Block]]) -> [[Block]])
    -> [([Inline], [[Block]])] -> [[Block]]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap ([Inline], [[Block]]) -> [[Block]]
    forall a b. (a, b) -> b
    snd [([Inline], [[Block]])]
    items
           Block
    _                                -> Bool
    False

    -- | True if list item can be handled with the simple wiki syntax.  False if
    --   HTML tags will be needed.
    isSimpleListItem :: [Block] -> Bool
    isSimpleListItem :: [Block] -> Bool
    isSimpleListItem []  = Bool
    True
    isSimpleListItem [Block
    x] =
      case Block
    x of
           Plain [Inline]
    _          -> Bool
    True
           Para  [Inline]
    _          -> Bool
    True
           BulletList [[Block]]
    _     -> Block -> Bool
    isSimpleList Block
    x
           OrderedList ListAttributes
    _ [[Block]]
    _  -> Block -> Bool
    isSimpleList Block
    x
           DefinitionList [([Inline], [[Block]])]
    _ -> Block -> Bool
    isSimpleList Block
    x
           Block
    _                -> Bool
    False
    isSimpleListItem [Block
    x, Block
    y] | Block -> Bool
    isPlainOrPara Block
    x =
      case Block
    y of
           BulletList [[Block]]
    _     -> Block -> Bool
    isSimpleList Block
    y
           OrderedList ListAttributes
    _ [[Block]]
    _  -> Block -> Bool
    isSimpleList Block
    y
           DefinitionList [([Inline], [[Block]])]
    _ -> Block -> Bool
    isSimpleList Block
    y
           Block
    _                -> Bool
    False
    isSimpleListItem [Block]
    _ = Bool
    False

    isPlainOrPara :: Block -> Bool
    isPlainOrPara :: Block -> Bool
    isPlainOrPara (Plain [Inline]
    _) = Bool
    True
    isPlainOrPara (Para  [Inline]
    _) = Bool
    True
    isPlainOrPara Block
    _         = Bool
    False

    -- Auxiliary functions for tables:

    tableToMediaWiki :: PandocMonad m => Ann.Table -> MediaWikiWriter m (Doc Text)
    tableToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    Table -> MediaWikiWriter m (Doc Text)
    tableToMediaWiki (Ann.Table Attr
    attr Caption
    capt [ColSpec]
    _ TableHead
    thead [TableBody]
    tbodies TableFoot
    tfoot) = do
        let (Text
    ident,[Text]
    classes,[(Text, Text)]
    kvs) = Attr
    attr
        caption <- case Caption
    capt of
            Caption Maybe [Inline]
    _ [] -> Doc Text -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Monoid a => a
    mempty
            Caption Maybe [Inline]
    _ [Block]
    longCapt -> do
                c <- [Block] -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    longCapt
                return $ literal "|+ " <> chomp c <> cr
        head' <- tableHeadToMW thead
        bodies' <- mconcat <$> mapM tableBodyToMW tbodies
        foot' <- tableFootToMW tfoot
        return $ literal "{|" <> htmlAttrs (ident, "wikitable":classes, kvs) <> cr
                 <> caption <> head' <> bodies' <> foot'
                 <> literal "|}" <> blankline

    tableHeadToMW :: PandocMonad m => Ann.TableHead -> MediaWikiWriter m (Doc Text)
    tableHeadToMW :: forall (m :: * -> *).
    PandocMonad m =>
    TableHead -> MediaWikiWriter m (Doc Text)
    tableHeadToMW (Ann.TableHead Attr
    _ [HeaderRow]
    rows) = [HeaderRow] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [HeaderRow] -> MediaWikiWriter m (Doc Text)
    headerRowsToMW [HeaderRow]
    rows

    tableFootToMW :: PandocMonad m => Ann.TableFoot -> MediaWikiWriter m (Doc Text)
    tableFootToMW :: forall (m :: * -> *).
    PandocMonad m =>
    TableFoot -> MediaWikiWriter m (Doc Text)
    tableFootToMW (Ann.TableFoot Attr
    _ [HeaderRow]
    rows) = [HeaderRow] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [HeaderRow] -> MediaWikiWriter m (Doc Text)
    headerRowsToMW [HeaderRow]
    rows

    tableBodyToMW :: PandocMonad m => Ann.TableBody -> MediaWikiWriter m (Doc Text)
    tableBodyToMW :: forall (m :: * -> *).
    PandocMonad m =>
    TableBody -> MediaWikiWriter m (Doc Text)
    tableBodyToMW (Ann.TableBody Attr
    _ RowHeadColumns
    _ [HeaderRow]
    headerRows [BodyRow]
    bodyRows) = do
      headerRows' <- [HeaderRow] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [HeaderRow] -> MediaWikiWriter m (Doc Text)
    headerRowsToMW [HeaderRow]
    headerRows
      bodyRows' <- bodyRowsToMW bodyRows
      return $ headerRows' <> bodyRows'

    headerRowsToMW :: PandocMonad m => [Ann.HeaderRow] -> MediaWikiWriter m (Doc Text)
    headerRowsToMW :: forall (m :: * -> *).
    PandocMonad m =>
    [HeaderRow] -> MediaWikiWriter m (Doc Text)
    headerRowsToMW [HeaderRow]
    rows = [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat ([Doc Text] -> Doc Text)
    -> ReaderT WriterReader (StateT WriterState m) [Doc Text]
    -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (HeaderRow
     -> ReaderT WriterReader (StateT WriterState m) (Doc Text))
    -> [HeaderRow]
    -> ReaderT WriterReader (StateT 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 HeaderRow -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    HeaderRow -> MediaWikiWriter m (Doc Text)
    headerRowToMW [HeaderRow]
    rows

    headerRowToMW :: PandocMonad m => Ann.HeaderRow -> MediaWikiWriter m (Doc Text)
    headerRowToMW :: forall (m :: * -> *).
    PandocMonad m =>
    HeaderRow -> MediaWikiWriter m (Doc Text)
    headerRowToMW (Ann.HeaderRow Attr
    attr RowNumber
    _ [Cell]
    cells) = do
      cells' <- [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat ([Doc Text] -> Doc Text)
    -> ReaderT WriterReader (StateT WriterState m) [Doc Text]
    -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Cell -> ReaderT WriterReader (StateT WriterState m) (Doc Text))
    -> [Cell] -> ReaderT WriterReader (StateT 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 (Text
    -> Cell -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> Cell -> MediaWikiWriter m (Doc Text)
    cellToMW Text
    "!") [Cell]
    cells
      return $ literal "|-" <> htmlAttrs attr <> cr <> cells'

    bodyRowsToMW :: PandocMonad m => [Ann.BodyRow] -> MediaWikiWriter m (Doc Text)
    bodyRowsToMW :: forall (m :: * -> *).
    PandocMonad m =>
    [BodyRow] -> MediaWikiWriter m (Doc Text)
    bodyRowsToMW [BodyRow]
    rows = [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat ([Doc Text] -> Doc Text)
    -> ReaderT WriterReader (StateT WriterState m) [Doc Text]
    -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (BodyRow -> ReaderT WriterReader (StateT WriterState m) (Doc Text))
    -> [BodyRow]
    -> ReaderT WriterReader (StateT 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 BodyRow -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    BodyRow -> MediaWikiWriter m (Doc Text)
    bodyRowToMW [BodyRow]
    rows

    bodyRowToMW :: PandocMonad m => Ann.BodyRow -> MediaWikiWriter m (Doc Text)
    bodyRowToMW :: forall (m :: * -> *).
    PandocMonad m =>
    BodyRow -> MediaWikiWriter m (Doc Text)
    bodyRowToMW (Ann.BodyRow Attr
    attr RowNumber
    _ [Cell]
    headCells [Cell]
    bodyCells) = do
      headCells' <- [Doc Text] -> Doc Text
    forall a. Monoid a => [a] -> a
    mconcat ([Doc Text] -> Doc Text)
    -> ReaderT WriterReader (StateT WriterState m) [Doc Text]
    -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Cell -> ReaderT WriterReader (StateT WriterState m) (Doc Text))
    -> [Cell] -> ReaderT WriterReader (StateT 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 (Text
    -> Cell -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Text -> Cell -> MediaWikiWriter m (Doc Text)
    cellToMW Text
    "!") [Cell]
    headCells
      bodyCells' <- mconcat <$> mapM (cellToMW "|") bodyCells
      return $ literal "|-" <> htmlAttrs attr <> cr <> headCells' <> bodyCells'

    cellToMW :: PandocMonad m => Text -> Ann.Cell -> MediaWikiWriter m (Doc Text)
    cellToMW :: forall (m :: * -> *).
    PandocMonad m =>
    Text -> Cell -> MediaWikiWriter m (Doc Text)
    cellToMW Text
    marker (Ann.Cell (ColSpec
    colSpec :| [ColSpec]
    _) ColNumber
    _ (Cell Attr
    attr Alignment
    align RowSpan
    rowspan ColSpan
    colspan [Block]
    content)) = do
      content' <- [Block] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    content
      let (ident,classes,keyVals) = attr

      let align' = case Alignment
    align of
            Alignment
    AlignDefault -> ColSpec -> Alignment
    forall a b. (a, b) -> a
    fst ColSpec
    colSpec
            Alignment
    _            -> Alignment
    align
      let keyVals' = case (Alignment -> Maybe Text
    htmlAlignmentToString Alignment
    align') of
                      Maybe Text
    Nothing -> [(Text, Text)]
    keyVals
                      Just Text
    alignStr -> (Text, Text) -> [(Text, Text)] -> [(Text, Text)]
    htmlAddStyle (Text
    "text-align", Text
    alignStr) [(Text, Text)]
    keyVals
      let rowspan' = case RowSpan
    rowspan of
                      RowSpan Int
    1 -> [(Text, Text)]
    forall a. Monoid a => a
    mempty
                      RowSpan Int
    n -> [(Text
    "rowspan", [Char] -> Text
    T.pack(Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    n))]
      let colspan' = case ColSpan
    colspan of
                      ColSpan Int
    1 -> [(Text, Text)]
    forall a. Monoid a => a
    mempty
                      ColSpan Int
    n -> [(Text
    "colspan", [Char] -> Text
    T.pack(Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    n))]
      let attrs' = Attr -> Doc Text
    forall a. HasChars a => Attr -> Doc a
    htmlAttrs (Text
    ident, [Text]
    classes, [(Text, Text)]
    rowspan' [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. Semigroup a => a -> a -> a
    <> [(Text, Text)]
    colspan' [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
    forall a. Semigroup a => a -> a -> a
    <> [(Text, Text)]
    keyVals')
      let attrsRendered = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    attrs'
      let pipeAttr = if Text -> Bool
    T.null Text
    attrsRendered then Doc Text
    forall a. Monoid a => a
    mempty else Doc Text
    attrs' 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
    "|"
      let contentRendered = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    content'
      let spaceContent = if Text -> Bool
    T.null Text
    contentRendered then Doc Text
    forall a. Monoid a => a
    mempty else Doc Text
    forall a. Doc a
    space Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text -> Doc Text
    forall a. Doc a -> Doc a
    chomp Doc Text
    content'
      return $ literal marker <> pipeAttr <> spaceContent <> cr

    imageToMediaWiki :: PandocMonad m => Attr -> MediaWikiWriter m Text
    imageToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    Attr -> MediaWikiWriter m Text
    imageToMediaWiki Attr
    attr = do
      opts <- (WriterState -> WriterOptions)
    -> ReaderT WriterReader (StateT WriterState m) WriterOptions
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> WriterOptions
    stOptions
      let (_, cls, _) = attr
          toPx = (Dimension -> Text) -> Maybe Dimension -> Maybe Text
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (WriterOptions -> Dimension -> Text
    showInPixel WriterOptions
    opts) (Maybe Dimension -> Maybe Text)
    -> (Maybe Dimension -> Maybe Dimension)
    -> Maybe Dimension
    -> Maybe Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe Dimension -> Maybe Dimension
    checkPct
          checkPct (Just (Percent Double
    _)) = Maybe Dimension
    forall a. Maybe a
    Nothing
          checkPct Maybe Dimension
    maybeDim           = Maybe Dimension
    maybeDim
          go (Just a
    w) Maybe a
    Nothing  = a
    w a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "px"
          go (Just a
    w) (Just a
    h) = a
    w a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "x" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    h a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "px"
          go Maybe a
    Nothing  (Just a
    h) = a
    "x" a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    h a -> a -> a
    forall a. Semigroup a => a -> a -> a
    <> a
    "px"
          go Maybe a
    Nothing  Maybe a
    Nothing  = a
    ""
          dims = Maybe Text -> Maybe Text -> Text
    forall {a}. (Semigroup a, IsString a) => Maybe a -> Maybe a -> a
    go (Maybe Dimension -> Maybe Text
    toPx (Maybe Dimension -> Maybe Text) -> Maybe Dimension -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Direction -> Attr -> Maybe Dimension
    dimension Direction
    Width Attr
    attr) (Maybe Dimension -> Maybe Text
    toPx (Maybe Dimension -> Maybe Text) -> Maybe Dimension -> Maybe Text
    forall a b. (a -> b) -> a -> b
    $ Direction -> Attr -> Maybe Dimension
    dimension Direction
    Height Attr
    attr)
          classes = if [Text] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Text]
    cls
                       then Text
    ""
                       else Text
    "class=" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> [Text] -> Text
    T.unwords [Text]
    cls
      return $ T.intercalate "|" $ filter (not . T.null) [dims, classes]

    -- | Convert list of Pandoc block elements to MediaWiki.
    blockListToMediaWiki :: PandocMonad m
                         => [Block]       -- ^ List of block elements
                         -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    blocks =
      [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    vcat ([Doc Text] -> Doc Text)
    -> ReaderT WriterReader (StateT WriterState m) [Doc Text]
    -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Block -> ReaderT WriterReader (StateT WriterState m) (Doc Text))
    -> [Block]
    -> ReaderT WriterReader (StateT 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 -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Block -> MediaWikiWriter m (Doc Text)
    blockToMediaWiki [Block]
    blocks

    -- | Convert list of Pandoc inline elements to MediaWiki.
    inlineListToMediaWiki :: PandocMonad m => [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst =
      [Doc Text] -> Doc Text
    forall a. [Doc a] -> Doc a
    hcat ([Doc Text] -> Doc Text)
    -> ReaderT WriterReader (StateT WriterState m) [Doc Text]
    -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Inline -> ReaderT WriterReader (StateT WriterState m) (Doc Text))
    -> [Inline]
    -> ReaderT WriterReader (StateT 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 -> ReaderT WriterReader (StateT WriterState m) (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    Inline -> MediaWikiWriter m (Doc Text)
    inlineToMediaWiki ([Inline] -> [Inline]
    fixup [Inline]
    lst)
        where
         fixup :: [Inline] -> [Inline]
    fixup [] = []
         fixup (Str Text
    t : Inline
    x : [Inline]
    xs)
           | Bool -> Bool
    not (Text -> Bool
    T.null Text
    t) Bool -> Bool -> Bool
    && HasCallStack => Text -> Char
    Text -> Char
    T.last Text
    t Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '['
           , Inline -> Bool
    isLinkOrImage Inline
    x =
              Text -> Inline
    Str Text
    t Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : Format -> Text -> Inline
    RawInline (Text -> Format
    Format Text
    "mediawiki") Text
    "<nowiki/>" Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : Inline
    x Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : [Inline] -> [Inline]
    fixup [Inline]
    xs
         fixup (Inline
    x:[Inline]
    xs) = Inline
    x Inline -> [Inline] -> [Inline]
    forall a. a -> [a] -> [a]
    : [Inline] -> [Inline]
    fixup [Inline]
    xs
         isLinkOrImage :: Inline -> Bool
    isLinkOrImage Link{}  = Bool
    True
         isLinkOrImage Image{} = Bool
    True
         isLinkOrImage Inline
    _         = Bool
    False

    -- | Convert Pandoc inline element to MediaWiki.
    inlineToMediaWiki :: PandocMonad m => Inline -> MediaWikiWriter m (Doc Text)

    inlineToMediaWiki :: forall (m :: * -> *).
    PandocMonad m =>
    Inline -> MediaWikiWriter m (Doc Text)
    inlineToMediaWiki (Span Attr
    attrs [Inline]
    ils) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    ils
      return $ tagWithAttrs "span" attrs <> contents <> literal "</span>"

    inlineToMediaWiki (Emph [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "''" <> contents <> literal "''"

    inlineToMediaWiki (Underline [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "<u>" <> contents <> literal "</u>"

    inlineToMediaWiki (Strong [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "'''" <> contents <> literal "'''"

    inlineToMediaWiki (Strikeout [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "<s>" <> contents <> literal "</s>"

    inlineToMediaWiki (Superscript [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "<sup>" <> contents <> literal "</sup>"

    inlineToMediaWiki (Subscript [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "<sub>" <> contents <> literal "</sub>"

    inlineToMediaWiki (SmallCaps [Inline]
    lst) = [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst

    inlineToMediaWiki (Quoted QuoteType
    SingleQuote [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "\8216" <> contents <> literal "\8217"

    inlineToMediaWiki (Quoted QuoteType
    DoubleQuote [Inline]
    lst) = do
      contents <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst
      return $ literal "\8220" <> contents <> literal "\8221"

    inlineToMediaWiki (Cite [Citation]
    _  [Inline]
    lst) = [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki [Inline]
    lst

    inlineToMediaWiki (Code Attr
    _ Text
    str) =
      Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "<code>" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text -> Text
    escapeText Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "</code>"

    inlineToMediaWiki (Str Text
    str) = do
      inDefLabel <- (WriterState -> Bool)
    -> ReaderT WriterReader (StateT WriterState m) Bool
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> Bool
    stInDefLabel
      return $ literal $
        if inDefLabel
           then T.intercalate "<nowiki>:</nowiki>" $
                  map escapeText $ T.splitOn ":" str
           else escapeText str

    inlineToMediaWiki (Math MathType
    mt Text
    str) = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $
      Text
    "<math display=\"" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
      (if MathType
    mt MathType -> MathType -> Bool
    forall a. Eq a => a -> a -> Bool
    == MathType
    DisplayMath then Text
    "block" else Text
    "inline") Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
      Text
    "\">" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    str Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "</math>"
      -- note:  str should NOT be escaped

    inlineToMediaWiki il :: Inline
    il@(RawInline Format
    f Text
    str)
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format Text
    "mediawiki" = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    str
      | Format
    f Format -> Format -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text -> Format
    Format Text
    "html"      = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    str
      | Bool
    otherwise               = Doc Text
    forall a. Monoid a => a
    mempty Doc Text
    -> ReaderT WriterReader (StateT WriterState m) ()
    -> MediaWikiWriter m (Doc Text)
    forall a b.
    a
    -> ReaderT WriterReader (StateT WriterState m) b
    -> ReaderT WriterReader (StateT WriterState m) a
    forall (f :: * -> *) a b. Functor f => a -> f b -> f a
    <$ LogMessage -> ReaderT WriterReader (StateT WriterState m) ()
    forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
    report (Inline -> LogMessage
    InlineNotRendered Inline
    il)

    inlineToMediaWiki Inline
    LineBreak = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    "<br />" Doc Text -> Doc Text -> Doc Text
    forall a. Semigroup a => a -> a -> a
    <> Doc Text
    forall a. Doc a
    cr

    inlineToMediaWiki Inline
    SoftBreak = do
      wrapText <- (WriterState -> WrapOption)
    -> ReaderT WriterReader (StateT WriterState m) WrapOption
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets (WriterOptions -> WrapOption
    writerWrapText (WriterOptions -> WrapOption)
    -> (WriterState -> WriterOptions) -> WriterState -> WrapOption
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . WriterState -> WriterOptions
    stOptions)
      listlevel <- asks listLevel
      case wrapText of
           WrapOption
    WrapAuto     -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    space
           WrapOption
    WrapNone     -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    space
           WrapOption
    WrapPreserve -> if [Char] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Char]
    listlevel
                              then Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    cr
                              else Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    space

    inlineToMediaWiki Inline
    Space = Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Doc Text
    forall a. Doc a
    space

    inlineToMediaWiki (Link Attr
    _ [Inline]
    txt (Text
    src, Text
    _)) = do
      -- We need to remove links from link text, because an <a> element is
      -- not allowed inside another <a> element.
      label <- [Inline] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Inline] -> MediaWikiWriter m (Doc Text)
    inlineListToMediaWiki ([Inline] -> [Inline]
    removeLinks [Inline]
    txt)
      let label' = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    label
      case txt of
         [Str Text
    s] | Text -> Bool
    isURI Text
    src Bool -> Bool -> Bool
    && Text -> Text
    escapeURI Text
    s Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    src -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal Text
    src
         [Inline]
    _  -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ if Text -> Bool
    isURI ((Char -> Bool) -> Text -> Text
    T.takeWhile (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Char
    '#') Text
    src) -- see #11562
           then Text
    "[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]"
           else
             if Text
    src Text -> Text -> Bool
    forall a. Eq a => a -> a -> Bool
    == Text
    label'
               then Text
    "[[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]]"
               else Text
    "[[" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    src' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "|" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    label' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "]]"
           -- with leading / it's a link to a help page
           where src' :: Text
    src' = Text -> Maybe Text -> Text
    forall a. a -> Maybe a -> a
    fromMaybe Text
    src (Maybe Text -> Text) -> Maybe Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text -> Text -> Maybe Text
    T.stripPrefix Text
    "/" Text
    src

    inlineToMediaWiki (Image Attr
    attr [Inline]
    alt (Text
    source, Text
    tit)) = do
      let separator :: Text
    separator = Text
    "<nowiki></nowiki>"
      -- External images (URIs) cannot use [[File:...]] syntax;
      -- they must be rendered as bare URLs. MediaWiki will auto-embed
      -- them when $wgAllowExternalImages is enabled.
      if Text -> Bool
    isURI Text
    source
         then Doc Text -> MediaWikiWriter m (Doc Text)
    forall a. a -> ReaderT WriterReader (StateT WriterState m) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Doc Text -> MediaWikiWriter m (Doc Text))
    -> Doc Text -> MediaWikiWriter m (Doc Text)
    forall a b. (a -> b) -> a -> b
    $ Text -> Doc Text
    forall a. HasChars a => a -> Doc a
    literal (Text -> Doc Text) -> Text -> Doc Text
    forall a b. (a -> b) -> a -> b
    $ Text
    separator Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    source Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    separator
         else do
           img  <- Attr -> MediaWikiWriter m Text
    forall (m :: * -> *).
    PandocMonad m =>
    Attr -> MediaWikiWriter m Text
    imageToMediaWiki Attr
    attr
           alt' <- inlineListToMediaWiki alt
           let altText = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    alt'
           let txt = if Text -> Bool
    T.null Text
    altText
                        then if Text -> Bool
    T.null Text
    tit
                                then Text
    ""
                                else Text
    tit
                        else Text
    altText
           return $ literal $ "[[" <>
                    T.intercalate "|"
                    (filter (not . T.null)
                     [ "File:" <> source
                     , img
                     , txt
                     ]) <> "]]"

    inlineToMediaWiki (Note [Block]
    contents) = do
      contents' <- [Block] -> MediaWikiWriter m (Doc Text)
    forall (m :: * -> *).
    PandocMonad m =>
    [Block] -> MediaWikiWriter m (Doc Text)
    blockListToMediaWiki [Block]
    contents
      modify (\WriterState
    s -> WriterState
    s { stNotes = True })
      let rendered = Maybe Int -> Doc Text -> Text
    forall a. HasChars a => Maybe Int -> Doc a -> a
    render Maybe Int
    forall a. Maybe a
    Nothing Doc Text
    contents'
      return $ literal $ "<ref>" <> stripTrailingNewlines rendered <> "</ref>"
      -- note - does not work for notes with multiple blocks

    highlightingLangs :: Set.Set Text
    highlightingLangs :: Set Text
    highlightingLangs = [Text] -> Set Text
    forall a. Ord a => [a] -> Set a
    Set.fromList [
      Text
    "abap",
      Text
    "abl",
      Text
    "abnf",
      Text
    "aconf",
      Text
    "actionscript",
      Text
    "actionscript3",
      Text
    "ada",
      Text
    "ada2005",
      Text
    "ada95",
      Text
    "adl",
      Text
    "agda",
      Text
    "ahk",
      Text
    "alloy",
      Text
    "ambienttalk",
      Text
    "ambienttalk/2",
      Text
    "antlr",
      Text
    "antlr-actionscript",
      Text
    "antlr-as",
      Text
    "antlr-c#",
      Text
    "antlr-cpp",
      Text
    "antlr-csharp",
      Text
    "antlr-java",
      Text
    "antlr-objc",
      Text
    "antlr-perl",
      Text
    "antlr-python",
      Text
    "antlr-rb",
      Text
    "antlr-ruby",
      Text
    "apache",
      Text
    "apacheconf",
      Text
    "apl",
      Text
    "applescript",
      Text
    "arduino",
      Text
    "arexx",
      Text
    "as",
      Text
    "as3",
      Text
    "asm",
      Text
    "aspectj",
      Text
    "aspx-cs",
      Text
    "aspx-vb",
      Text
    "asy",
      Text
    "asymptote",
      Text
    "at",
      Text
    "autohotkey",
      Text
    "autoit",
      Text
    "awk",
      Text
    "b3d",
      Text
    "basemake",
      Text
    "bash",
      Text
    "basic",
      Text
    "bat",
      Text
    "batch",
      Text
    "bbcode",
      Text
    "because",
      Text
    "befunge",
      Text
    "bf",
      Text
    "blitzbasic",
      Text
    "blitzmax",
      Text
    "bmax",
      Text
    "bnf",
      Text
    "boo",
      Text
    "boogie",
      Text
    "bplus",
      Text
    "brainfuck",
      Text
    "bro",
      Text
    "bsdmake",
      Text
    "bugs",
      Text
    "c",
      Text
    "c#",
      Text
    "c++",
      Text
    "c++-objdumb",
      Text
    "c-objdump",
      Text
    "ca65",
      Text
    "cadl",
      Text
    "camkes",
      Text
    "cbmbas",
      Text
    "ceylon",
      Text
    "cf3",
      Text
    "cfc",
      Text
    "cfengine3",
      Text
    "cfg",
      Text
    "cfm",
      Text
    "cfs",
      Text
    "chai",
      Text
    "chaiscript",
      Text
    "chapel",
      Text
    "cheetah",
      Text
    "chpl",
      Text
    "cirru",
      Text
    "cl",
      Text
    "clay",
      Text
    "clipper",
      Text
    "clj",
      Text
    "cljs",
      Text
    "clojure",
      Text
    "clojurescript",
      Text
    "cmake",
      Text
    "cobol",
      Text
    "cobolfree",
      Text
    "coffee",
      Text
    "coffee-script",
      Text
    "coffeescript",
      Text
    "common-lisp",
      Text
    "componentpascal",
      Text
    "console",
      Text
    "control",
      Text
    "coq",
      Text
    "cp",
      Text
    "cpp",
      Text
    "cpp-objdump",
      Text
    "cpsa",
      Text
    "crmsh",
      Text
    "croc",
      Text
    "cry",
      Text
    "cryptol",
      Text
    "csh",
      Text
    "csharp",
      Text
    "csound",
      Text
    "csound-csd",
      Text
    "csound-document",
      Text
    "csound-orc",
      Text
    "csound-sco",
      Text
    "csound-score",
      Text
    "css",
      Text
    "css+django",
      Text
    "css+erb",
      Text
    "css+genshi",
      Text
    "css+genshitext",
      Text
    "css+jinja",
      Text
    "css+lasso",
      Text
    "css+mako",
      Text
    "css+mozpreproc",
      Text
    "css+myghty",
      Text
    "css+php",
      Text
    "css+ruby",
      Text
    "css+smarty",
      Text
    "cu",
      Text
    "cucumber",
      Text
    "cuda",
      Text
    "cxx-objdump",
      Text
    "cypher",
      Text
    "cython",
      Text
    "d",
      Text
    "d-objdump",
      Text
    "dart",
      Text
    "debcontrol",
      Text
    "debsources",
      Text
    "delphi",
      Text
    "dg",
      Text
    "diff",
      Text
    "django",
      Text
    "docker",
      Text
    "dockerfile",
      Text
    "dosbatch",
      Text
    "doscon",
      Text
    "dosini",
      Text
    "dpatch",
      Text
    "dtd",
      Text
    "duby",
      Text
    "duel",
      Text
    "dylan",
      Text
    "dylan-console",
      Text
    "dylan-lid",
      Text
    "dylan-repl",
      Text
    "earl-grey",
      Text
    "earlgrey",
      Text
    "easytrieve",
      Text
    "ebnf",
      Text
    "ec",
      Text
    "ecl",
      Text
    "eg",
      Text
    "eiffel",
      Text
    "elisp",
      Text
    "elixir",
      Text
    "elm",
      Text
    "emacs",
      Text
    "erb",
      Text
    "erl",
      Text
    "erlang",
      Text
    "evoque",
      Text
    "ex",
      Text
    "exs",
      Text
    "ezhil",
      Text
    "f#",
      Text
    "factor",
      Text
    "fan",
      Text
    "fancy",
      Text
    "felix",
      Text
    "fish",
      Text
    "fishshell",
      Text
    "flx",
      Text
    "fortran",
      Text
    "fortranfixed",
      Text
    "foxpro",
      Text
    "fsharp",
      Text
    "fy",
      Text
    "gap",
      Text
    "gas",
      Text
    "gawk",
      Text
    "genshi",
      Text
    "genshitext",
      Text
    "gherkin",
      Text
    "glsl",
      Text
    "gnuplot",
      Text
    "go",
      Text
    "golo",
      Text
    "gooddata-cl",
      Text
    "gosu",
      Text
    "groff",
      Text
    "groovy",
      Text
    "gst",
      Text
    "haml",
      Text
    "handlebars",
      Text
    "haskell",
      Text
    "haxe",
      Text
    "haxeml",
      Text
    "hexdump",
      Text
    "hs",
      Text
    "html",
      Text
    "html+cheetah",
      Text
    "html+django",
      Text
    "html+erb",
      Text
    "html+evoque",
      Text
    "html+genshi",
      Text
    "html+handlebars",
      Text
    "html+jinja",
      Text
    "html+kid",
      Text
    "html+lasso",
      Text
    "html+mako",
      Text
    "html+myghty",
      Text
    "html+php",
      Text
    "html+ruby",
      Text
    "html+smarty",
      Text
    "html+spitfire",
      Text
    "html+twig",
      Text
    "html+velocity",
      Text
    "htmlcheetah",
      Text
    "htmldjango",
      Text
    "http",
      Text
    "hx",
      Text
    "hxml",
      Text
    "hxsl",
      Text
    "hy",
      Text
    "hybris",
      Text
    "hylang",
      Text
    "i6",
      Text
    "i6t",
      Text
    "i7",
      Text
    "idl",
      Text
    "idl4",
      Text
    "idr",
      Text
    "idris",
      Text
    "iex",
      Text
    "igor",
      Text
    "igorpro",
      Text
    "ik",
      Text
    "inform6",
      Text
    "inform7",
      Text
    "ini",
      Text
    "io",
      Text
    "ioke",
      Text
    "irb",
      Text
    "irc",
      Text
    "isabelle",
      Text
    "j",
      Text
    "jade",
      Text
    "jags",
      Text
    "jasmin",
      Text
    "jasminxt",
      Text
    "java",
      Text
    "javascript",
      Text
    "javascript+cheetah",
      Text
    "javascript+django",
      Text
    "javascript+erb",
      Text
    "javascript+genshi",
      Text
    "javascript+genshitext",
      Text
    "javascript+jinja",
      Text
    "javascript+lasso",
      Text
    "javascript+mako",
      Text
    "javascript+mozpreproc",
      Text
    "javascript+myghty",
      Text
    "javascript+php",
      Text
    "javascript+ruby",
      Text
    "javascript+smarty",
      Text
    "javascript+spitfire",
      Text
    "jbst",
      Text
    "jcl",
      Text
    "jinja",
      Text
    "jl",
      Text
    "jlcon",
      Text
    "jproperties",
      Text
    "js",
      Text
    "js+cheetah",
      Text
    "js+django",
      Text
    "js+erb",
      Text
    "js+genshi",
      Text
    "js+genshitext",
      Text
    "js+jinja",
      Text
    "js+lasso",
      Text
    "js+mako",
      Text
    "js+myghty",
      Text
    "js+php",
      Text
    "js+ruby",
      Text
    "js+smarty",
      Text
    "js+spitfire",
      Text
    "json",
      Text
    "json-ld",
      Text
    "jsonld",
      Text
    "jsonml+bst",
      Text
    "jsp",
      Text
    "julia",
      Text
    "kal",
      Text
    "kconfig",
      Text
    "kernel-config",
      Text
    "kid",
      Text
    "koka",
      Text
    "kotlin",
      Text
    "ksh",
      Text
    "lagda",
      Text
    "lasso",
      Text
    "lassoscript",
      Text
    "latex",
      Text
    "lcry",
      Text
    "lcryptol",
      Text
    "lean",
      Text
    "less",
      Text
    "lhaskell",
      Text
    "lhs",
      Text
    "lid",
      Text
    "lidr",
      Text
    "lidris",
      Text
    "lighttpd",
      Text
    "lighty",
      Text
    "limbo",
      Text
    "linux-config",
      Text
    "liquid",
      Text
    "lisp",
      Text
    "literate-agda",
      Text
    "literate-cryptol",
      Text
    "literate-haskell",
      Text
    "literate-idris",
      Text
    "live-script",
      Text
    "livescript",
      Text
    "llvm",
      Text
    "logos",
      Text
    "logtalk",
      Text
    "lsl",
      Text
    "lua",
      Text
    "m2",
      Text
    "make",
      Text
    "makefile",
      Text
    "mako",
      Text
    "man",
      Text
    "maql",
      Text
    "mask",
      Text
    "mason",
      Text
    "mathematica",
      Text
    "matlab",
      Text
    "matlabsession",
      Text
    "mawk",
      Text
    "menuconfig",
      Text
    "mf",
      Text
    "minid",
      Text
    "mma",
      Text
    "modelica",
      Text
    "modula2",
      Text
    "moin",
      Text
    "monkey",
      Text
    "moo",
      Text
    "moocode",
      Text
    "moon",
      Text
    "moonscript",
      Text
    "mozhashpreproc",
      Text
    "mozpercentpreproc",
      Text
    "mq4",
      Text
    "mq5",
      Text
    "mql",
      Text
    "mql4",
      Text
    "mql5",
      Text
    "msc",
      Text
    "mscgen",
      Text
    "mupad",
      Text
    "mxml",
      Text
    "myghty",
      Text
    "mysql",
      Text
    "nasm",
      Text
    "nawk",
      Text
    "nb",
      Text
    "nemerle",
      Text
    "nesc",
      Text
    "newlisp",
      Text
    "newspeak",
      Text
    "nginx",
      Text
    "nim",
      Text
    "nimrod",
      Text
    "nit",
      Text
    "nix",
      Text
    "nixos",
      Text
    "nroff",
      Text
    "nsh",
      Text
    "nsi",
      Text
    "nsis",
      Text
    "numpy",
      Text
    "obj-c",
      Text
    "obj-c++",
      Text
    "obj-j",
      Text
    "objc",
      Text
    "objc++",
      Text
    "objdump",
      Text
    "objdump-nasm",
      Text
    "objective-c",
      Text
    "objective-c++",
      Text
    "objective-j",
      Text
    "objectivec",
      Text
    "objectivec++",
      Text
    "objectivej",
      Text
    "objectpascal",
      Text
    "objj",
      Text
    "ocaml",
      Text
    "octave",
      Text
    "odin",
      Text
    "ooc",
      Text
    "opa",
      Text
    "openbugs",
      Text
    "openedge",
      Text
    "pacmanconf",
      Text
    "pan",
      Text
    "parasail",
      Text
    "pas",
      Text
    "pascal",
      Text
    "pawn",
      Text
    "pcmk",
      Text
    "perl",
      Text
    "perl6",
      Text
    "php",
      Text
    "php3",
      Text
    "php4",
      Text
    "php5",
      Text
    "pig",
      Text
    "pike",
      Text
    "pkgconfig",
      Text
    "pl",
      Text
    "pl6",
      Text
    "plpgsql",
      Text
    "po",
      Text
    "posh",
      Text
    "postgres",
      Text
    "postgres-console",
      Text
    "postgresql",
      Text
    "postgresql-console",
      Text
    "postscr",
      Text
    "postscript",
      Text
    "pot",
      Text
    "pov",
      Text
    "powershell",
      Text
    "praat",
      Text
    "progress",
      Text
    "prolog",
      Text
    "properties",
      Text
    "proto",
      Text
    "protobuf",
      Text
    "ps1",
      Text
    "ps1con",
      Text
    "psm1",
      Text
    "psql",
      Text
    "puppet",
      Text
    "py",
      Text
    "py3",
      Text
    "py3tb",
      Text
    "pycon",
      Text
    "pypy",
      Text
    "pypylog",
      Text
    "pyrex",
      Text
    "pytb",
      Text
    "python",
      Text
    "python3",
      Text
    "pyx",
      Text
    "qbasic",
      Text
    "qbs",
      Text
    "qml",
      Text
    "qvt",
      Text
    "qvto",
      Text
    "r",
      Text
    "racket",
      Text
    "ragel",
      Text
    "ragel-c",
      Text
    "ragel-cpp",
      Text
    "ragel-d",
      Text
    "ragel-em",
      Text
    "ragel-java",
      Text
    "ragel-objc",
      Text
    "ragel-rb",
      Text
    "ragel-ruby",
      Text
    "raw",
      Text
    "rb",
      Text
    "rbcon",
      Text
    "rconsole",
      Text
    "rd",
      Text
    "rebol",
      Text
    "red",
      Text
    "red/system",
      Text
    "redcode",
      Text
    "registry",
      Text
    "resource",
      Text
    "resourcebundle",
      Text
    "rest",
      Text
    "restructuredtext",
      Text
    "rexx",
      Text
    "rhtml",
      Text
    "rkt",
      Text
    "roboconf-graph",
      Text
    "roboconf-instances",
      Text
    "robotframework",
      Text
    "rout",
      Text
    "rql",
      Text
    "rsl",
      Text
    "rst",
      Text
    "rts",
      Text
    "ruby",
      Text
    "rust",
      Text
    "s",
      Text
    "sage",
      Text
    "salt",
      Text
    "sass",
      Text
    "sc",
      Text
    "scala",
      Text
    "scaml",
      Text
    "scheme",
      Text
    "scilab",
      Text
    "scm",
      Text
    "scss",
      Text
    "sh",
      Text
    "shell",
      Text
    "shell-session",
      Text
    "shen",
      Text
    "slim",
      Text
    "sls",
      Text
    "smali",
      Text
    "smalltalk",
      Text
    "smarty",
      Text
    "sml",
      Text
    "snobol",
      Text
    "sources.list",
      Text
    "sourceslist",
      Text
    "sp",
      Text
    "sparql",
      Text
    "spec",
      Text
    "spitfire",
      Text
    "splus",
      Text
    "sql",
      Text
    "sqlite3",
      Text
    "squeak",
      Text
    "squid",
      Text
    "squid.conf",
      Text
    "squidconf",
      Text
    "ssp",
      Text
    "st",
      Text
    "stan",
      Text
    "supercollider",
      Text
    "sv",
      Text
    "swift",
      Text
    "swig",
      Text
    "systemverilog",
      Text
    "tads3",
      Text
    "tap",
      Text
    "tcl",
      Text
    "tcsh",
      Text
    "tcshcon",
      Text
    "tea",
      Text
    "termcap",
      Text
    "terminfo",
      Text
    "terraform",
      Text
    "tex",
      Text
    "text",
      Text
    "tf",
      Text
    "thrift",
      Text
    "todotxt",
      Text
    "trac-wiki",
      Text
    "trafficscript",
      Text
    "treetop",
      Text
    "ts",
      Text
    "turtle",
      Text
    "twig",
      Text
    "typescript",
      Text
    "udiff",
      Text
    "urbiscript",
      Text
    "v",
      Text
    "vala",
      Text
    "vapi",
      Text
    "vb.net",
      Text
    "vbnet",
      Text
    "vctreestatus",
      Text
    "velocity",
      Text
    "verilog",
      Text
    "vfp",
      Text
    "vgl",
      Text
    "vhdl",
      Text
    "vim",
      Text
    "winbatch",
      Text
    "winbugs",
      Text
    "x10",
      Text
    "xbase",
      Text
    "xml",
      Text
    "xml+cheetah",
      Text
    "xml+django",
      Text
    "xml+erb",
      Text
    "xml+evoque",
      Text
    "xml+genshi",
      Text
    "xml+jinja",
      Text
    "xml+kid",
      Text
    "xml+lasso",
      Text
    "xml+mako",
      Text
    "xml+myghty",
      Text
    "xml+php",
      Text
    "xml+ruby",
      Text
    "xml+smarty",
      Text
    "xml+spitfire",
      Text
    "xml+velocity",
      Text
    "xq",
      Text
    "xql",
      Text
    "xqm",
      Text
    "xquery",
      Text
    "xqy",
      Text
    "xslt",
      Text
    "xten",
      Text
    "xtend",
      Text
    "xul+mozpreproc",
      Text
    "yaml",
      Text
    "yaml+jinja",
      Text
    "zephir" ]

    startsWithListMarker :: Text -> Bool
    startsWithListMarker :: Text -> Bool
    startsWithListMarker Text
    t =
      case Text -> Maybe (Char, Text)
    T.uncons Text
    t of
        Maybe (Char, Text)
    Nothing -> Bool
    False
        Just (Char
    c,Text
    _) -> Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '#' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    ':' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    ';' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '*'