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

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

Conversion of 'Pandoc' documents to asciidoc.

Note that some information may be lost in conversion, due to
expressive limitations of asciidoc.  Footnotes and table cells with
paragraphs (or other block items) are not possible in asciidoc.
If pandoc encounters one of these, it will insert a message indicating
that it has omitted the construct.

AsciiDoc:  <http://www.methods.co.nz/asciidoc/>
-}
module Text.Pandoc.Writers.AsciiDoc (
  writeAsciiDoc,
  writeAsciiDocLegacy,
  writeAsciiDoctor
  ) where
import Control.Monad (foldM)
import Control.Monad.State.Strict
    ( StateT, MonadState(get), gets, modify, evalStateT )
import Data.Char (isPunctuation, isSpace)
import Data.List (delete, intercalate, intersperse)
import Data.List.NonEmpty (NonEmpty(..))
import Data.Maybe (fromMaybe, isJust)
import qualified Data.Set as Set
import qualified Data.Text as T
import Data.Text (Text)
import System.FilePath (dropExtension)
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.Pandoc.Parsing hiding (blankline, space)
import Text.DocLayout
import Text.Pandoc.Shared
import Text.Pandoc.URI
import Text.Pandoc.Templates (renderTemplate)
import Text.Pandoc.Writers.Shared
import Text.Pandoc.Walk (walk)

data WriterState = WriterState { WriterState -> Text
defListMarker       :: Text
                               , WriterState -> Int
orderedListLevel    :: Int
                               , WriterState -> Int
bulletListLevel     :: Int
                               , WriterState -> Bool
intraword           :: Bool
                               , WriterState -> Set Text
autoIds             :: Set.Set Text
                               , WriterState -> Bool
legacy              :: Bool
                               , WriterState -> Bool
inList              :: Bool
                               , WriterState -> Bool
hasMath             :: Bool
                               -- |0 is no table
                               -- 1 is top level table
                               -- 2 is a table in a table
                               , WriterState -> Int
tableNestingLevel   :: Int
                               }

defaultWriterState :: WriterState
defaultWriterState :: WriterState
defaultWriterState = WriterState { defListMarker :: Text
defListMarker      = Text
"::"
                                 , orderedListLevel :: Int
orderedListLevel   = Int
0
                                 , bulletListLevel :: Int
bulletListLevel    = Int
0
                                 , intraword :: Bool
intraword          = Bool
False
                                 , autoIds :: Set Text
autoIds            = forall a. Set a
Set.empty
                                 , legacy :: Bool
legacy             = Bool
False
                                 , inList :: Bool
inList             = Bool
False
                                 , hasMath :: Bool
hasMath            = Bool
False
                                 , tableNestingLevel :: Int
tableNestingLevel  = Int
0
                                 }

-- | Convert Pandoc to AsciiDoc.
writeAsciiDoc :: PandocMonad m => WriterOptions -> Pandoc -> m Text
writeAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeAsciiDoc WriterOptions
opts Pandoc
document =
  forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> ADW m Text
pandocToAsciiDoc WriterOptions
opts Pandoc
document) WriterState
defaultWriterState

{-# DEPRECATED writeAsciiDoctor "Use writeAsciiDoc instead" #-}
-- | Deprecated synonym of 'writeAsciiDoc'.
writeAsciiDoctor :: PandocMonad m => WriterOptions -> Pandoc -> m Text
writeAsciiDoctor :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeAsciiDoctor = forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeAsciiDoc

-- | Convert Pandoc to legacy AsciiDoc.
writeAsciiDocLegacy :: PandocMonad m => WriterOptions -> Pandoc -> m Text
writeAsciiDocLegacy :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> m Text
writeAsciiDocLegacy WriterOptions
opts Pandoc
document =
  forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> ADW m Text
pandocToAsciiDoc WriterOptions
opts Pandoc
document)
    WriterState
defaultWriterState{ legacy :: Bool
legacy = Bool
True }

type ADW = StateT WriterState

-- | Return asciidoc representation of document.
pandocToAsciiDoc :: PandocMonad m => WriterOptions -> Pandoc -> ADW m Text
pandocToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Pandoc -> ADW m Text
pandocToAsciiDoc WriterOptions
opts (Pandoc Meta
meta [Block]
blocks) = do
  let titleblock :: Bool
titleblock = Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Meta -> [Inline]
docTitle Meta
meta) Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Meta -> [[Inline]]
docAuthors Meta
meta) Bool -> Bool -> Bool
&&
                         forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Meta -> [Inline]
docDate Meta
meta)
  let colwidth :: Maybe Int
colwidth = if WriterOptions -> WrapOption
writerWrapText WriterOptions
opts forall a. Eq a => a -> a -> Bool
== WrapOption
WrapAuto
                    then forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ WriterOptions -> Int
writerColumns WriterOptions
opts
                    else forall a. Maybe a
Nothing
  Context Text
metadata <- forall (m :: * -> *) a.
(Monad m, TemplateTarget a) =>
WriterOptions
-> ([Block] -> m (Doc a))
-> ([Inline] -> m (Doc a))
-> Meta
-> m (Context a)
metaToContext WriterOptions
opts
              (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts)
              (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Doc a -> Doc a
chomp forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts)
              Meta
meta
  Doc Text
main <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts forall a b. (a -> b) -> a -> b
$ Bool -> Maybe Int -> [Block] -> [Block]
makeSections Bool
False (forall a. a -> Maybe a
Just Int
1) [Block]
blocks
  WriterState
st <- forall s (m :: * -> *). MonadState s m => m s
get
  let context :: Context Text
context  = forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"body" Doc Text
main
               forall a b. (a -> b) -> a -> b
$ forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"toc"
                  (WriterOptions -> Bool
writerTableOfContents WriterOptions
opts Bool -> Bool -> Bool
&&
                   forall a. Maybe a -> Bool
isJust (WriterOptions -> Maybe (Template Text)
writerTemplate WriterOptions
opts))
               forall a b. (a -> b) -> a -> b
$ forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"math" (WriterState -> Bool
hasMath WriterState
st Bool -> Bool -> Bool
&& Bool -> Bool
not (WriterState -> Bool
legacy WriterState
st))
               forall a b. (a -> b) -> a -> b
$ forall a b. ToContext a b => Text -> b -> Context a -> Context a
defField Text
"titleblock" Bool
titleblock Context Text
metadata
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => Maybe Int -> Doc a -> a
render Maybe Int
colwidth forall a b. (a -> b) -> a -> b
$
    case WriterOptions -> Maybe (Template Text)
writerTemplate WriterOptions
opts of
       Maybe (Template Text)
Nothing  -> Doc Text
main
       Just Template Text
tpl -> forall a b.
(TemplateTarget a, ToContext a b) =>
Template a -> b -> Doc a
renderTemplate Template Text
tpl Context Text
context

-- | Escape special characters for AsciiDoc.
escapeString :: PandocMonad m => Text -> ADW m (Doc Text)
escapeString :: forall (m :: * -> *). PandocMonad m => Text -> ADW m (Doc Text)
escapeString Text
t = do
  Int
parentTableLevel <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Int
tableNestingLevel
  let needsEscape :: Char -> Bool
needsEscape Char
'{' = Bool
True
      needsEscape Char
'|' = Int
parentTableLevel forall a. Ord a => a -> a -> Bool
> Int
0
      needsEscape Char
_   = Bool
False
  let escChar :: Char -> Text
escChar Char
c | Char -> Bool
needsEscape Char
c = Text
"\\" forall a. Semigroup a => a -> a -> a
<> Char -> Text
T.singleton Char
c
                | Bool
otherwise     = Char -> Text
T.singleton Char
c
  if (Char -> Bool) -> Text -> Bool
T.any Char -> Bool
needsEscape Text
t
     then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal forall a b. (a -> b) -> a -> b
$ (Char -> Text) -> Text -> Text
T.concatMap Char -> Text
escChar Text
t
     else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal Text
t


-- | Ordered list start parser for use in Para below.
olMarker :: Parsec Text ParserState Char
olMarker :: Parsec Text ParserState Char
olMarker = do (Int
start, ListNumberStyle
style', ListNumberDelim
delim) <- forall s (m :: * -> *).
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s ParserState m (Int, ListNumberStyle, ListNumberDelim)
anyOrderedListMarker
              if ListNumberDelim
delim forall a. Eq a => a -> a -> Bool
== ListNumberDelim
Period Bool -> Bool -> Bool
&&
                          (ListNumberStyle
style' forall a. Eq a => a -> a -> Bool
== ListNumberStyle
UpperAlpha Bool -> Bool -> Bool
|| (ListNumberStyle
style' forall a. Eq a => a -> a -> Bool
== ListNumberStyle
UpperRoman Bool -> Bool -> Bool
&&
                          Int
start forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int
1, Int
5, Int
10, Int
50, Int
100, Int
500, Int
1000]))
                          then forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar
                          else forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar

-- | True if string begins with an ordered list marker
-- or would be interpreted as an AsciiDoc option command
needsEscaping :: Text -> Bool
needsEscaping :: Text -> Bool
needsEscaping Text
s = Text -> Bool
beginsWithOrderedListMarker Text
s Bool -> Bool -> Bool
|| Text -> Bool
isBracketed Text
s
  where
    beginsWithOrderedListMarker :: Text -> Bool
beginsWithOrderedListMarker Text
str =
      case forall s t u a.
Stream s Identity t =>
Parsec s u a -> u -> SourceName -> s -> Either ParseError a
runParser Parsec Text ParserState Char
olMarker ParserState
defaultParserState SourceName
"para start" (Int -> Text -> Text
T.take Int
10 Text
str) of
             Left  ParseError
_ -> Bool
False
             Right Char
_ -> Bool
True
    isBracketed :: Text -> Bool
isBracketed Text
t
      | Just (Char
'[', Text
t') <- Text -> Maybe (Char, Text)
T.uncons Text
t
      , Just (Text
_, Char
']')  <- Text -> Maybe (Text, Char)
T.unsnoc Text
t'
      = Bool
True
      | Bool
otherwise = Bool
False

-- | Convert Pandoc block element to asciidoc.
blockToAsciiDoc :: PandocMonad m
                => WriterOptions -- ^ Options
                -> Block         -- ^ Block element
                -> ADW m (Doc Text)
blockToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> ADW m (Doc Text)
blockToAsciiDoc WriterOptions
opts (Div (Text
id',Text
"section":[Text]
_,[(Text, Text)]
_)
                       (Header Int
level (Text
_,[Text]
cls,[(Text, Text)]
kvs) [Inline]
ils : [Block]
xs)) = do
  Doc Text
hdr <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> ADW m (Doc Text)
blockToAsciiDoc WriterOptions
opts (Int -> (Text, [Text], [(Text, Text)]) -> [Inline] -> Block
Header Int
level (Text
id',[Text]
cls,[(Text, Text)]
kvs) [Inline]
ils)
  Doc Text
rest <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
xs
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
hdr forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
rest
blockToAsciiDoc WriterOptions
opts (Plain [Inline]
inlines) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
inlines
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (Para [Inline]
inlines) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
inlines
  -- escape if para starts with ordered list marker
  let esc :: Doc Text
esc = if Text -> Bool
needsEscaping (forall a. HasChars a => Maybe Int -> Doc a -> a
render forall a. Maybe a
Nothing Doc Text
contents)
               then forall a. HasChars a => SourceName -> Doc a
text SourceName
"{empty}"
               else forall a. Doc a
empty
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
esc forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (LineBlock [[Inline]]
lns) = do
  let docify :: [Inline] -> StateT WriterState m (Doc Text)
docify [Inline]
line = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
line
                    then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
blankline
                    else forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
line
  let joinWithLinefeeds :: [Doc Text] -> Doc Text
joinWithLinefeeds = forall a. IsString a => Doc a -> Doc a
nowrap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Monoid a => [a] -> a
mconcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse forall a. Doc a
cr
  Doc Text
contents <- [Doc Text] -> Doc Text
joinWithLinefeeds forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {m :: * -> *}.
PandocMonad m =>
[Inline] -> StateT WriterState m (Doc Text)
docify [[Inline]]
lns
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"[verse]" forall a. Doc a -> Doc a -> Doc a
$$ forall a. HasChars a => SourceName -> Doc a
text SourceName
"--" forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
contents forall a. Doc a -> Doc a -> Doc a
$$ forall a. HasChars a => SourceName -> Doc a
text SourceName
"--" forall a. Doc a -> Doc a -> Doc a
$$ forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
_ b :: Block
b@(RawBlock Format
f Text
s)
  | Format
f forall a. Eq a => a -> a -> Bool
== Format
"asciidoc" = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal Text
s
  | Bool
otherwise         = do
      forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report forall a b. (a -> b) -> a -> b
$ Block -> LogMessage
BlockNotRendered Block
b
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
empty
blockToAsciiDoc WriterOptions
_ Block
HorizontalRule =
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Doc a
blankline forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
"'''''" forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (Header Int
level (Text
ident,[Text]
_,[(Text, Text)]
_) [Inline]
inlines) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
inlines
  Set Text
ids <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Set Text
autoIds
  let autoId :: Text
autoId = Extensions -> [Inline] -> Set Text -> Text
uniqueIdent (WriterOptions -> Extensions
writerExtensions WriterOptions
opts) [Inline]
inlines Set Text
ids
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ autoIds :: Set Text
autoIds = forall a. Ord a => a -> Set a -> Set a
Set.insert Text
autoId Set Text
ids }
  let identifier :: Doc Text
identifier = if Text -> Bool
T.null Text
ident Bool -> Bool -> Bool
||
                      (forall a. HasSyntaxExtensions a => Extension -> a -> Bool
isEnabled Extension
Ext_auto_identifiers WriterOptions
opts Bool -> Bool -> Bool
&& Text
ident forall a. Eq a => a -> a -> Bool
== Text
autoId)
                      then forall a. Doc a
empty
                      else Doc Text
"[[" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
ident forall a. Semigroup a => a -> a -> a
<> Doc Text
"]]"
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
identifier forall a. Doc a -> Doc a -> Doc a
$$
           forall a. IsString a => Doc a -> Doc a
nowrap (forall a. HasChars a => SourceName -> Doc a
text (forall a. Int -> a -> [a]
replicate (Int
level forall a. Num a => a -> a -> a
+ Int
1) Char
'=') forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
space forall a. Semigroup a => a -> a -> a
<> Doc Text
contents) forall a. Semigroup a => a -> a -> a
<>
           forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (Figure (Text, [Text], [(Text, Text)])
attr (Caption Maybe [Inline]
_ [Block]
longcapt) [Block]
body) = do
  -- Images in figures all get rendered as individual block-level images
  -- with the given caption. Non-image elements are rendered unchanged.
  Doc Text
capt <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts ([Block] -> [Inline]
blocksToInlines [Block]
longcapt)
  let renderFigElement :: Block -> ADW m (Doc Text)
renderFigElement = \case
        Plain [Image (Text, [Text], [(Text, Text)])
imgAttr [Inline]
alternate (Text
src, Text
tit)] -> do
          Doc Text
args <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions
-> (Text, [Text], [(Text, Text)])
-> [Inline]
-> Text
-> Text
-> ADW m (Doc Text)
imageArguments WriterOptions
opts (Text, [Text], [(Text, Text)])
imgAttr [Inline]
alternate Text
src Text
tit
          let figAttributes :: Doc Text
figAttributes = case (Text, [Text], [(Text, Text)])
attr of
                (Text
"", [Text]
_, [(Text, Text)]
_)    -> forall a. Doc a
empty
                (Text
ident, [Text]
_, [(Text, Text)]
_) -> forall a. HasChars a => a -> Doc a
literal forall a b. (a -> b) -> a -> b
$ Text
"[#" forall a. Semigroup a => a -> a -> a
<> Text
ident forall a. Semigroup a => a -> a -> a
<> Text
"]"
          -- .Figure caption
          -- image::images/logo.png[Company logo, title="blah"]
          forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"." forall a. Semigroup a => a -> a -> a
<> forall a. IsString a => Doc a -> Doc a
nowrap Doc Text
capt forall a. Doc a -> Doc a -> Doc a
$$
            Doc Text
figAttributes forall a. Doc a -> Doc a -> Doc a
$$
            Doc Text
"image::" forall a. Semigroup a => a -> a -> a
<> Doc Text
args forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
        Block
blk -> forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> ADW m (Doc Text)
blockToAsciiDoc WriterOptions
opts Block
blk
  forall a. [Doc a] -> Doc a
vcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Block -> ADW m (Doc Text)
renderFigElement [Block]
body
blockToAsciiDoc WriterOptions
_ (CodeBlock (Text
_,[Text]
classes,[(Text, Text)]
_) Text
str) = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Doc a -> Doc a
flush (
  if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
classes
     then Doc Text
"...." forall a. Doc a -> Doc a -> Doc a
$$ forall a. HasChars a => a -> Doc a
literal Text
str forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"...."
     else Doc Text
attrs forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"----" forall a. Doc a -> Doc a -> Doc a
$$ forall a. HasChars a => a -> Doc a
literal Text
str forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"----")
  forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
    where attrs :: Doc Text
attrs = Doc Text
"[" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal (Text -> [Text] -> Text
T.intercalate Text
"," [Text]
classes') forall a. Semigroup a => a -> a -> a
<> Doc Text
"]"
          classes' :: [Text]
classes' = if Text
"numberLines" forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
classes
                        then Text
"source%linesnum" forall a. a -> [a] -> [a]
: forall a. Eq a => a -> [a] -> [a]
delete Text
"numberLines" [Text]
classes
                        else Text
"source" forall a. a -> [a] -> [a]
: [Text]
classes
blockToAsciiDoc WriterOptions
opts (BlockQuote [Block]
blocks) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
blocks
  let isBlock :: Block -> Bool
isBlock (BlockQuote [Block]
_) = Bool
True
      isBlock Block
_              = Bool
False
  -- if there are nested block quotes, put in an open block
  let contents' :: Doc Text
contents' = if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Block -> Bool
isBlock [Block]
blocks
                     then Doc Text
"--" forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
contents forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"--"
                     else Doc Text
contents
  let bar :: Doc Text
bar = forall a. HasChars a => SourceName -> Doc a
text SourceName
"____"
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
bar forall a. Doc a -> Doc a -> Doc a
$$ forall a. Doc a -> Doc a
chomp Doc Text
contents' forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
bar forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts block :: Block
block@(Table (Text, [Text], [(Text, Text)])
_ Caption
blkCapt [ColSpec]
specs TableHead
thead [TableBody]
tbody TableFoot
tfoot) = do
  let ([Inline]
caption, [Alignment]
aligns, [Double]
widths, [[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
  Doc Text
caption' <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
caption
  let caption'' :: Doc Text
caption'' = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
caption
                     then forall a. Doc a
empty
                     else Doc Text
"." forall a. Semigroup a => a -> a -> a
<> Doc Text
caption' forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr
  let isSimple :: Bool
isSimple = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
== Double
0) [Double]
widths
  let relativePercentWidths :: [Double]
relativePercentWidths = if Bool
isSimple
                                 then [Double]
widths
                                 else forall a b. (a -> b) -> [a] -> [b]
map (forall a. Fractional a => a -> a -> a
/ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Double]
widths) [Double]
widths
  let widths'' :: [Integer]
      widths'' :: [Integer]
widths'' = forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (RealFrac a, Integral b) => a -> b
floor forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. Num a => a -> a -> a
* Double
100)) [Double]
relativePercentWidths
  -- ensure that the widths sum to 100
  let widths' :: [Integer]
widths' = case [Integer]
widths'' of
                     [Integer]
_ | Bool
isSimple -> [Integer]
widths''
                     (Integer
w:[Integer]
ws) | forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (Integer
wforall a. a -> [a] -> [a]
:[Integer]
ws) forall a. Ord a => a -> a -> Bool
< Integer
100
                               -> (Integer
100 forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Integer]
ws) forall a. a -> [a] -> [a]
: [Integer]
ws
                     [Integer]
ws        -> [Integer]
ws
  let totalwidth :: Integer
      totalwidth :: Integer
totalwidth = forall a b. (RealFrac a, Integral b) => a -> b
floor forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Double]
widths forall a. Num a => a -> a -> a
* Double
100
  let colspec :: Alignment -> a -> SourceName
colspec Alignment
al a
wi = (case Alignment
al of
                         Alignment
AlignLeft    -> SourceName
"<"
                         Alignment
AlignCenter  -> SourceName
"^"
                         Alignment
AlignRight   -> SourceName
">"
                         Alignment
AlignDefault -> SourceName
"") forall a. [a] -> [a] -> [a]
++
                      if a
wi forall a. Eq a => a -> a -> Bool
== a
0 then SourceName
"" else forall a. Show a => a -> SourceName
show a
wi forall a. [a] -> [a] -> [a]
++ SourceName
"%"
  let headerspec :: Doc Text
headerspec = if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
headers
                      then forall a. Doc a
empty
                      else forall a. HasChars a => SourceName -> Doc a
text SourceName
"options=\"header\","
  let widthspec :: Doc Text
widthspec = if Integer
totalwidth forall a. Eq a => a -> a -> Bool
== Integer
0
                     then forall a. Doc a
empty
                     else forall a. HasChars a => SourceName -> Doc a
text SourceName
"width="
                          forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => Doc a -> Doc a
doubleQuotes (forall a. HasChars a => SourceName -> Doc a
text forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> SourceName
show Integer
totalwidth forall a. [a] -> [a] -> [a]
++ SourceName
"%")
                          forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
","
  let tablespec :: Doc Text
tablespec = forall a. HasChars a => SourceName -> Doc a
text SourceName
"["
         forall a. Semigroup a => a -> a -> a
<> Doc Text
widthspec
         forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
"cols="
         forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => Doc a -> Doc a
doubleQuotes (forall a. HasChars a => SourceName -> Doc a
text forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [[a]] -> [a]
intercalate SourceName
","
             forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall {a}. (Eq a, Num a, Show a) => Alignment -> a -> SourceName
colspec [Alignment]
aligns [Integer]
widths')
         forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
","
         forall a. Semigroup a => a -> a -> a
<> Doc Text
headerspec forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
"]"

  -- construct cells and recurse in case of nested tables
  Int
parentTableLevel <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Int
tableNestingLevel
  let currentNestingLevel :: Int
currentNestingLevel = Int
parentTableLevel forall a. Num a => a -> a -> a
+ Int
1

  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ tableNestingLevel :: Int
tableNestingLevel = Int
currentNestingLevel }

  let separator :: Doc Text
separator = forall a. HasChars a => SourceName -> Doc a
text (if Int
parentTableLevel forall a. Eq a => a -> a -> Bool
== Int
0
                          then SourceName
"|"  -- top level separator
                          else SourceName
"!") -- nested separator

  let makeCell :: [Block] -> StateT WriterState m (Doc Text)
makeCell [Plain [Inline]
x] = do Doc Text
d <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [[Inline] -> Block
Plain [Inline]
x]
                              forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
separator forall a. Semigroup a => a -> a -> a
<> forall a. Doc a -> Doc a
chomp Doc Text
d
      makeCell [Para [Inline]
x]  = [Block] -> StateT WriterState m (Doc Text)
makeCell [[Inline] -> Block
Plain [Inline]
x]
      makeCell []        = forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
separator
      makeCell [Block]
bs        = if Int
currentNestingLevel forall a. Eq a => a -> a -> Bool
== Int
2
                             then do
                               --asciidoc only supports nesting once
                               forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report forall a b. (a -> b) -> a -> b
$ Block -> LogMessage
BlockNotRendered Block
block
                               forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
separator
                             else do
                               Doc Text
d <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
bs
                               forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ (forall a. HasChars a => SourceName -> Doc a
text SourceName
"a" forall a. Semigroup a => a -> a -> a
<> Doc Text
separator) forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
d

  let makeRow :: [[Block]] -> StateT WriterState m (Doc Text)
makeRow [[Block]]
cells = forall a. [Doc a] -> Doc a
hsep forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {m :: * -> *}.
PandocMonad m =>
[Block] -> StateT WriterState m (Doc Text)
makeCell [[Block]]
cells
  [Doc Text]
rows' <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {m :: * -> *}.
PandocMonad m =>
[[Block]] -> StateT WriterState m (Doc Text)
makeRow [[[Block]]]
rows
  Doc Text
head' <- forall {m :: * -> *}.
PandocMonad m =>
[[Block]] -> StateT WriterState m (Doc Text)
makeRow [[Block]]
headers
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ tableNestingLevel :: Int
tableNestingLevel = Int
parentTableLevel }
  let head'' :: Doc Text
head'' = if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Block]]
headers then forall a. Doc a
empty else Doc Text
head'
  let colwidth :: Int
colwidth = if WriterOptions -> WrapOption
writerWrapText WriterOptions
opts forall a. Eq a => a -> a -> Bool
== WrapOption
WrapAuto
                    then WriterOptions -> Int
writerColumns WriterOptions
opts
                    else Int
100000
  let maxwidth :: Int
maxwidth = forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. (IsString a, HasChars a) => Doc a -> Int
offset (Doc Text
head' forall a. a -> [a] -> NonEmpty a
:| [Doc Text]
rows')
  let body :: Doc Text
body = if Int
maxwidth forall a. Ord a => a -> a -> Bool
> Int
colwidth then forall a. [Doc a] -> Doc a
vsep [Doc Text]
rows' else forall a. [Doc a] -> Doc a
vcat [Doc Text]
rows'
  let border :: Doc Text
border = Doc Text
separator forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
"==="
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    Doc Text
caption'' forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
tablespec forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
border forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
head'' forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
body forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
border forall a. Doc a -> Doc a -> Doc a
$$ forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (BulletList [[Block]]
items) = do
  Bool
inlist <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
inList
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ inList :: Bool
inList = Bool
True }
  [Doc Text]
contents <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
bulletListItemToAsciiDoc WriterOptions
opts) [[Block]]
items
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ inList :: Bool
inList = Bool
inlist }
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat [Doc Text]
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (OrderedList (Int
start, ListNumberStyle
sty, ListNumberDelim
_delim) [[Block]]
items) = do
  let listStyle :: [Text]
listStyle = case ListNumberStyle
sty of
                       ListNumberStyle
DefaultStyle -> []
                       ListNumberStyle
Decimal      -> [Text
"arabic"]
                       ListNumberStyle
Example      -> []
                       ListNumberStyle
_            -> [Text -> Text
T.toLower (forall a. Show a => a -> Text
tshow ListNumberStyle
sty)]
  let listStart :: [Text]
listStart = [Text
"start=" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
tshow Int
start | Int
start forall a. Eq a => a -> a -> Bool
/= Int
1]
  let listoptions :: Doc Text
listoptions = case Text -> [Text] -> Text
T.intercalate Text
", " ([Text]
listStyle forall a. [a] -> [a] -> [a]
++ [Text]
listStart) of
                          Text
"" -> forall a. Doc a
empty
                          Text
x  -> forall a. HasChars a => Doc a -> Doc a
brackets (forall a. HasChars a => a -> Doc a
literal Text
x)
  Bool
inlist <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
inList
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ inList :: Bool
inList = Bool
True }
  [Doc Text]
contents <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
orderedListItemToAsciiDoc WriterOptions
opts) [[Block]]
items
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ inList :: Bool
inList = Bool
inlist }
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
listoptions forall a. Doc a -> Doc a -> Doc a
$$ forall a. Monoid a => [a] -> a
mconcat [Doc Text]
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (DefinitionList [([Inline], [[Block]])]
items) = do
  Bool
inlist <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
inList
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ inList :: Bool
inList = Bool
True }
  [Doc Text]
contents <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> ([Inline], [[Block]]) -> ADW m (Doc Text)
definitionListItemToAsciiDoc WriterOptions
opts) [([Inline], [[Block]])]
items
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ inList :: Bool
inList = Bool
inlist }
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat [Doc Text]
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
blankline
blockToAsciiDoc WriterOptions
opts (Div (Text
ident,[Text]
classes,[(Text, Text)]
_) [Block]
bs) = do
  let identifier :: Doc Text
identifier = if Text -> Bool
T.null Text
ident then forall a. Doc a
empty else Doc Text
"[[" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
ident forall a. Semigroup a => a -> a -> a
<> Doc Text
"]]"
  let admonitions :: [Text]
admonitions = [Text
"attention",Text
"caution",Text
"danger",Text
"error",Text
"hint",
                     Text
"important",Text
"note",Text
"tip",Text
"warning"]
  Doc Text
contents <-
       case [Text]
classes of
         (Text
l:[Text]
_) | Text
l forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text]
admonitions -> do
             let ([Block]
titleBs, [Block]
bodyBs) =
                     case [Block]
bs of
                       (Div (Text
_,[Text
"title"],[(Text, Text)]
_) [Block]
ts : [Block]
rest) -> ([Block]
ts, [Block]
rest)
                       [Block]
_ -> ([], [Block]
bs)
             Doc Text
admonitionTitle <- if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Block]
titleBs Bool -> Bool -> Bool
||
                                   -- If title matches class, omit
                                   (Text -> Text
T.toLower (Text -> Text
T.strip (forall a. Walkable Inline a => a -> Text
stringify [Block]
titleBs))) forall a. Eq a => a -> a -> Bool
== Text
l
                                   then forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Monoid a => a
mempty
                                   else (Doc Text
"." forall a. Semigroup a => a -> a -> a
<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                                         forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
titleBs
             Doc Text
admonitionBody <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
bodyBs
             forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"[" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal (Text -> Text
T.toUpper Text
l) forall a. Semigroup a => a -> a -> a
<> Doc Text
"]" forall a. Doc a -> Doc a -> Doc a
$$
                      forall a. Doc a -> Doc a
chomp Doc Text
admonitionTitle forall a. Doc a -> Doc a -> Doc a
$$
                      Doc Text
"====" forall a. Doc a -> Doc a -> Doc a
$$
                      forall a. Doc a -> Doc a
chomp Doc Text
admonitionBody forall a. Doc a -> Doc a -> Doc a
$$
                      Doc Text
"===="
         [Text]
_ -> forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
bs
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
identifier forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
contents forall a. Doc a -> Doc a -> Doc a
$$ forall a. Doc a
blankline

-- | Convert bullet list item (list of blocks) to asciidoc.
bulletListItemToAsciiDoc :: PandocMonad m
                         => WriterOptions -> [Block] -> ADW m (Doc Text)
bulletListItemToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
bulletListItemToAsciiDoc WriterOptions
opts [Block]
blocks = do
  Int
lev <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Int
bulletListLevel
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
s -> WriterState
s{ bulletListLevel :: Int
bulletListLevel = Int
lev forall a. Num a => a -> a -> a
+ Int
1 }
  Bool
isLegacy <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
legacy
  let blocksWithTasks :: [Block]
blocksWithTasks = if Bool
isLegacy
                          then [Block]
blocks
                          else ([Block] -> [Block]
taskListItemToAsciiDoc [Block]
blocks)
  Doc Text
contents <- forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Doc Text -> Block -> ADW m (Doc Text)
addBlock WriterOptions
opts) forall a. Doc a
empty [Block]
blocksWithTasks
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
s -> WriterState
s{ bulletListLevel :: Int
bulletListLevel = Int
lev }
  let marker :: Doc Text
marker = forall a. HasChars a => SourceName -> Doc a
text (forall a. Int -> a -> [a]
replicate (Int
lev forall a. Num a => a -> a -> a
+ Int
1) Char
'*')
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
marker forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
" " forall a. Semigroup a => a -> a -> a
<> [Block] -> Doc Text
listBegin [Block]
blocksWithTasks forall a. Semigroup a => a -> a -> a
<>
    Doc Text
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr

-- | Convert a list item containing text starting with @U+2610 BALLOT BOX@
-- or @U+2612 BALLOT BOX WITH X@ to asciidoctor checkbox syntax (e.g. @[x]@).
taskListItemToAsciiDoc :: [Block] -> [Block]
taskListItemToAsciiDoc :: [Block] -> [Block]
taskListItemToAsciiDoc = ([Inline] -> [Inline]) -> Extensions -> [Block] -> [Block]
handleTaskListItem [Inline] -> [Inline]
toOrg Extensions
listExt
  where
    toOrg :: [Inline] -> [Inline]
toOrg (Str Text
"☐" : Inline
Space : [Inline]
is) = Text -> Inline
Str Text
"[ ]" forall a. a -> [a] -> [a]
: Inline
Space forall a. a -> [a] -> [a]
: [Inline]
is
    toOrg (Str Text
"☒" : Inline
Space : [Inline]
is) = Text -> Inline
Str Text
"[x]" forall a. a -> [a] -> [a]
: Inline
Space forall a. a -> [a] -> [a]
: [Inline]
is
    toOrg [Inline]
is = [Inline]
is
    listExt :: Extensions
listExt = [Extension] -> Extensions
extensionsFromList [Extension
Ext_task_lists]

addBlock :: PandocMonad m
         => WriterOptions -> Doc Text -> Block -> ADW m (Doc Text)
addBlock :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Doc Text -> Block -> ADW m (Doc Text)
addBlock WriterOptions
opts Doc Text
d Block
b = do
  Doc Text
x <- forall a. Doc a -> Doc a
chomp forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> ADW m (Doc Text)
blockToAsciiDoc WriterOptions
opts Block
b
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    case Block
b of
        BulletList{} -> Doc Text
d forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
x
        OrderedList{} -> Doc Text
d forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
x
        Para (Math MathType
DisplayMath Text
_:[Inline]
_) -> Doc Text
d forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
x
        Plain (Math MathType
DisplayMath Text
_:[Inline]
_) -> Doc Text
d forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
x
        Para{} | forall a. Doc a -> Bool
isEmpty Doc Text
d -> Doc Text
x
        Plain{} | forall a. Doc a -> Bool
isEmpty Doc Text
d -> Doc Text
x
        Block
_ -> Doc Text
d forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
"+" forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
x

listBegin :: [Block] -> Doc Text
listBegin :: [Block] -> Doc Text
listBegin [Block]
blocks =
        case [Block]
blocks of
          Para (Math MathType
DisplayMath Text
_:[Inline]
_) : [Block]
_  -> Doc Text
"{blank}"
          Plain (Math MathType
DisplayMath Text
_:[Inline]
_) : [Block]
_ -> Doc Text
"{blank}"
          Para [Inline]
_ : [Block]
_                       -> forall a. Doc a
empty
          Plain [Inline]
_ : [Block]
_                      -> forall a. Doc a
empty
          Block
_ : [Block]
_                            -> Doc Text
"{blank}"
          []                               -> Doc Text
"{blank}"

-- | Convert ordered list item (a list of blocks) to asciidoc.
orderedListItemToAsciiDoc :: PandocMonad m
                          => WriterOptions -- ^ options
                          -> [Block]       -- ^ list item (list of blocks)
                          -> ADW m (Doc Text)
orderedListItemToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
orderedListItemToAsciiDoc WriterOptions
opts [Block]
blocks = do
  Int
lev <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Int
orderedListLevel
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
s -> WriterState
s{ orderedListLevel :: Int
orderedListLevel = Int
lev forall a. Num a => a -> a -> a
+ Int
1 }
  Doc Text
contents <- forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Doc Text -> Block -> ADW m (Doc Text)
addBlock WriterOptions
opts) forall a. Doc a
empty [Block]
blocks
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
s -> WriterState
s{ orderedListLevel :: Int
orderedListLevel = Int
lev }
  let marker :: Doc Text
marker = forall a. HasChars a => SourceName -> Doc a
text (forall a. Int -> a -> [a]
replicate (Int
lev forall a. Num a => a -> a -> a
+ Int
1) Char
'.')
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
marker forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
" " forall a. Semigroup a => a -> a -> a
<> [Block] -> Doc Text
listBegin [Block]
blocks forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr

-- | Convert definition list item (label, list of blocks) to asciidoc.
definitionListItemToAsciiDoc :: PandocMonad m
                             => WriterOptions
                             -> ([Inline],[[Block]])
                             -> ADW m (Doc Text)
definitionListItemToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> ([Inline], [[Block]]) -> ADW m (Doc Text)
definitionListItemToAsciiDoc WriterOptions
opts ([Inline]
label, [[Block]]
defs) = do
  Doc Text
labelText <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
label
  Text
marker <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Text
defListMarker
  if Text
marker forall a. Eq a => a -> a -> Bool
== Text
"::"
     then forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\WriterState
st -> WriterState
st{ defListMarker :: Text
defListMarker = Text
";;"})
     else forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\WriterState
st -> WriterState
st{ defListMarker :: Text
defListMarker = Text
"::"})
  let divider :: Doc Text
divider = forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text SourceName
"+" forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr
  let defsToAsciiDoc :: PandocMonad m => [Block] -> ADW m (Doc Text)
      defsToAsciiDoc :: forall {m :: * -> *}.
PandocMonad m =>
[Block] -> StateT WriterState m (Doc Text)
defsToAsciiDoc [Block]
ds = (forall a. [Doc a] -> Doc a
vcat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> [a] -> [a]
intersperse Doc Text
divider forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map forall a. Doc a -> Doc a
chomp)
           forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> ADW m (Doc Text)
blockToAsciiDoc WriterOptions
opts) [Block]
ds
  [Doc Text]
defs' <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall {m :: * -> *}.
PandocMonad m =>
[Block] -> StateT WriterState m (Doc Text)
defsToAsciiDoc [[Block]]
defs
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\WriterState
st -> WriterState
st{ defListMarker :: Text
defListMarker = Text
marker })
  let contents :: Doc Text
contents = forall a. IsString a => Int -> Doc a -> Doc a
nest Int
2 forall a b. (a -> b) -> a -> b
$ forall a. [Doc a] -> Doc a
vcat forall a b. (a -> b) -> a -> b
$ forall a. a -> [a] -> [a]
intersperse Doc Text
divider forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a. Doc a -> Doc a
chomp [Doc Text]
defs'
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
labelText forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
marker forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr

-- | Convert list of Pandoc block elements to asciidoc.
blockListToAsciiDoc :: PandocMonad m
                    => WriterOptions -- ^ Options
                    -> [Block]       -- ^ List of block elements
                    -> ADW m (Doc Text)
blockListToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Block] -> ADW m (Doc Text)
blockListToAsciiDoc WriterOptions
opts [Block]
blocks =
  forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Block -> ADW m (Doc Text)
blockToAsciiDoc WriterOptions
opts) [Block]
blocks

data SpacyLocation = End | Start

-- | Convert list of Pandoc inline elements to asciidoc.
inlineListToAsciiDoc :: PandocMonad m =>
                        WriterOptions ->
                        [Inline] ->
                        ADW m (Doc Text)
inlineListToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst = do
  Bool
oldIntraword <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
intraword
  forall (m :: * -> *). PandocMonad m => Bool -> ADW m ()
setIntraword Bool
False
  Doc Text
result <- forall {m :: * -> *}.
PandocMonad m =>
[Inline] -> StateT WriterState m (Doc Text)
go [Inline]
lst
  forall (m :: * -> *). PandocMonad m => Bool -> ADW m ()
setIntraword Bool
oldIntraword
  forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
result
 where go :: [Inline] -> StateT WriterState m (Doc Text)
go [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
empty
       go (Inline
y:Inline
x:[Inline]
xs)
         | Bool -> Bool
not (SpacyLocation -> Inline -> Bool
isSpacy SpacyLocation
End Inline
y) = do
           Doc Text
y' <- if SpacyLocation -> Inline -> Bool
isSpacy SpacyLocation
Start Inline
x
                    then forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts Inline
y
                    else forall (m :: * -> *) a. PandocMonad m => ADW m a -> ADW m a
withIntraword forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts Inline
y
           Doc Text
x' <- forall (m :: * -> *) a. PandocMonad m => ADW m a -> ADW m a
withIntraword forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts Inline
x
           Doc Text
xs' <- [Inline] -> StateT WriterState m (Doc Text)
go [Inline]
xs
           forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text
y' forall a. Semigroup a => a -> a -> a
<> Doc Text
x' forall a. Semigroup a => a -> a -> a
<> Doc Text
xs')
         | Bool -> Bool
not (SpacyLocation -> Inline -> Bool
isSpacy SpacyLocation
Start Inline
x) = do
           Doc Text
y' <- forall (m :: * -> *) a. PandocMonad m => ADW m a -> ADW m a
withIntraword forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts Inline
y
           Doc Text
xs' <- [Inline] -> StateT WriterState m (Doc Text)
go (Inline
xforall a. a -> [a] -> [a]
:[Inline]
xs)
           forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text
y' forall a. Semigroup a => a -> a -> a
<> Doc Text
xs')
       go (Inline
x:[Inline]
xs) = do
           Doc Text
x' <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts Inline
x
           Doc Text
xs' <- [Inline] -> StateT WriterState m (Doc Text)
go [Inline]
xs
           forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text
x' forall a. Semigroup a => a -> a -> a
<> Doc Text
xs')
       isSpacy :: SpacyLocation -> Inline -> Bool
       isSpacy :: SpacyLocation -> Inline -> Bool
isSpacy SpacyLocation
_ Inline
Space = Bool
True
       isSpacy SpacyLocation
_ Inline
LineBreak = Bool
True
       isSpacy SpacyLocation
_ Inline
SoftBreak = Bool
True
       -- Note that \W characters count as spacy in AsciiDoc
       -- for purposes of determining interword:
       isSpacy SpacyLocation
End (Str Text
xs) = case Text -> Maybe (Text, Char)
T.unsnoc Text
xs of
                                   Just (Text
_, Char
c) -> Char -> Bool
isPunctuation Char
c Bool -> Bool -> Bool
|| Char -> Bool
isSpace Char
c
                                   Maybe (Text, Char)
_           -> Bool
False
       isSpacy SpacyLocation
Start (Str Text
xs)
         | Just (Char
c, Text
_) <- Text -> Maybe (Char, Text)
T.uncons Text
xs = Char -> Bool
isPunctuation Char
c Bool -> Bool -> Bool
|| Char -> Bool
isSpace Char
c
       isSpacy SpacyLocation
_ Inline
_ = Bool
True

setIntraword :: PandocMonad m => Bool -> ADW m ()
setIntraword :: forall (m :: * -> *). PandocMonad m => Bool -> ADW m ()
setIntraword Bool
b = forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ intraword :: Bool
intraword = Bool
b }

withIntraword :: PandocMonad m => ADW m a -> ADW m a
withIntraword :: forall (m :: * -> *) a. PandocMonad m => ADW m a -> ADW m a
withIntraword ADW m a
p = forall (m :: * -> *). PandocMonad m => Bool -> ADW m ()
setIntraword Bool
True forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ADW m a
p forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* forall (m :: * -> *). PandocMonad m => Bool -> ADW m ()
setIntraword Bool
False

-- | Convert Pandoc inline element to asciidoc.
inlineToAsciiDoc :: PandocMonad m => WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts (Emph [Strong [Inline]
xs]) =
  forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts ([Inline] -> Inline
Strong [[Inline] -> Inline
Emph [Inline]
xs])  -- see #5565
inlineToAsciiDoc WriterOptions
opts (Emph [Inline]
lst) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
  Bool
isIntraword <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
intraword
  let marker :: Doc Text
marker = if Bool
isIntraword then Doc Text
"__" else Doc Text
"_"
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
marker forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
marker
inlineToAsciiDoc WriterOptions
opts (Underline [Inline]
lst) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"[.underline]#" forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"#"
inlineToAsciiDoc WriterOptions
opts (Strong [Inline]
lst) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
  Bool
isIntraword <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
intraword
  let marker :: Doc Text
marker = if Bool
isIntraword then Doc Text
"**" else Doc Text
"*"
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
marker forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
marker
inlineToAsciiDoc WriterOptions
opts (Strikeout [Inline]
lst) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"[line-through]#" forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"#"
inlineToAsciiDoc WriterOptions
opts (Superscript [Inline]
lst) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"^" forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"^"
inlineToAsciiDoc WriterOptions
opts (Subscript [Inline]
lst) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"~" forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"~"
inlineToAsciiDoc WriterOptions
opts (SmallCaps [Inline]
lst) = forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
inlineToAsciiDoc WriterOptions
opts (Quoted QuoteType
qt [Inline]
lst) = do
  Bool
isLegacy <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
legacy
  forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts forall a b. (a -> b) -> a -> b
$
    case QuoteType
qt of
      QuoteType
SingleQuote
        | Bool
isLegacy     -> [Text -> Inline
Str Text
"`"] forall a. [a] -> [a] -> [a]
++ [Inline]
lst forall a. [a] -> [a] -> [a]
++ [Text -> Inline
Str Text
"'"]
        | Bool
otherwise    -> [Text -> Inline
Str Text
"'`"] forall a. [a] -> [a] -> [a]
++ [Inline]
lst forall a. [a] -> [a] -> [a]
++ [Text -> Inline
Str Text
"`'"]
      QuoteType
DoubleQuote
        | Bool
isLegacy     -> [Text -> Inline
Str Text
"``"] forall a. [a] -> [a] -> [a]
++ [Inline]
lst forall a. [a] -> [a] -> [a]
++ [Text -> Inline
Str Text
"''"]
        | Bool
otherwise    -> [Text -> Inline
Str Text
"\"`"] forall a. [a] -> [a] -> [a]
++ [Inline]
lst forall a. [a] -> [a] -> [a]
++ [Text -> Inline
Str Text
"`\""]
inlineToAsciiDoc WriterOptions
_ (Code (Text, [Text], [(Text, Text)])
_ Text
str) = do
  Bool
isLegacy <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
legacy
  let escChar :: Char -> Text
escChar Char
'`' = Text
"\\'"
      escChar Char
c   = Char -> Text
T.singleton Char
c
  let contents :: Doc Text
contents = forall a. HasChars a => a -> Doc a
literal ((Char -> Text) -> Text -> Text
T.concatMap Char -> Text
escChar Text
str)
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    if Bool
isLegacy
       then forall a. HasChars a => SourceName -> Doc a
text SourceName
"`"  forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"`"
       else forall a. HasChars a => SourceName -> Doc a
text SourceName
"`+" forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"+`"
inlineToAsciiDoc WriterOptions
_ (Str Text
str) = forall (m :: * -> *). PandocMonad m => Text -> ADW m (Doc Text)
escapeString Text
str
inlineToAsciiDoc WriterOptions
_ (Math MathType
InlineMath Text
str) = do
  Bool
isLegacy <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
legacy
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ hasMath :: Bool
hasMath = Bool
True }
  let content :: Doc Text
content = if Bool
isLegacy
                then Doc Text
"$" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
str forall a. Semigroup a => a -> a -> a
<> Doc Text
"$"
                else forall a. HasChars a => a -> Doc a
literal Text
str
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
"latexmath:[" forall a. Semigroup a => a -> a -> a
<> Doc Text
content forall a. Semigroup a => a -> a -> a
<> Doc Text
"]"
inlineToAsciiDoc WriterOptions
_ (Math MathType
DisplayMath Text
str) = do
  Bool
isLegacy <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
legacy
  forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify forall a b. (a -> b) -> a -> b
$ \WriterState
st -> WriterState
st{ hasMath :: Bool
hasMath = Bool
True }
  let content :: Doc Text
content = if Bool
isLegacy
                   then Doc Text
"\\[" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
str forall a. Semigroup a => a -> a -> a
<> Doc Text
"\\]"
                   else forall a. HasChars a => a -> Doc a
literal Text
str
  Bool
inlist <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
inList
  let sepline :: Doc Text
sepline = if Bool
inlist
                   then forall a. HasChars a => SourceName -> Doc a
text SourceName
"+"
                   else forall a. Doc a
blankline
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
      (forall a. Doc a
cr forall a. Semigroup a => a -> a -> a
<> Doc Text
sepline) forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"[latexmath]" forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"++++" forall a. Doc a -> Doc a -> Doc a
$$
      Doc Text
content forall a. Doc a -> Doc a -> Doc a
$$ Doc Text
"++++" forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr
inlineToAsciiDoc WriterOptions
_ il :: Inline
il@(RawInline Format
f Text
s)
  | Format
f forall a. Eq a => a -> a -> Bool
== Format
"asciidoc" = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal Text
s
  | Bool
otherwise         = do
      forall (m :: * -> *). PandocMonad m => LogMessage -> m ()
report forall a b. (a -> b) -> a -> b
$ Inline -> LogMessage
InlineNotRendered Inline
il
      forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
empty
inlineToAsciiDoc WriterOptions
_ Inline
LineBreak = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
" +" forall a. Semigroup a => a -> a -> a
<> forall a. Doc a
cr
inlineToAsciiDoc WriterOptions
_ Inline
Space = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
space
inlineToAsciiDoc WriterOptions
opts Inline
SoftBreak =
  case WriterOptions -> WrapOption
writerWrapText WriterOptions
opts of
       WrapOption
WrapAuto     -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
space
       WrapOption
WrapPreserve -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
cr
       WrapOption
WrapNone     -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Doc a
space
inlineToAsciiDoc WriterOptions
opts (Cite [Citation]
_ [Inline]
lst) = forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
lst
inlineToAsciiDoc WriterOptions
opts (Link (Text, [Text], [(Text, Text)])
_ [Inline]
txt (Text
src, Text
_tit)) = do
-- relative:  link:downloads/foo.zip[download foo.zip]
-- abs:  http://google.cod[Google]
-- or my@email.com[email john]
  let fixCommas :: Inline -> [Inline]
fixCommas (Str Text
t) =
        forall a. a -> [a] -> [a]
intersperse (Format -> Text -> Inline
RawInline (Text -> Format
Format Text
"asciidoc") Text
"&#44;")
          forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Text -> Inline
Str forall a b. (a -> b) -> a -> b
$ HasCallStack => Text -> Text -> [Text]
T.splitOn Text
"," Text
t -- see #8070
      fixCommas Inline
x = [Inline
x]

  Doc Text
linktext <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts forall a b. (a -> b) -> a -> b
$ forall a b. Walkable a b => (a -> a) -> b -> b
walk (forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Inline -> [Inline]
fixCommas) [Inline]
txt
  let isRelative :: Bool
isRelative = (Char -> Bool) -> Text -> Bool
T.all (forall a. Eq a => a -> a -> Bool
/= Char
':') Text
src
  let needsPassthrough :: Bool
needsPassthrough = Text
"--" Text -> Text -> Bool
`T.isInfixOf` Text
src
  let prefix :: Doc Text
prefix = if Bool
isRelative
                  then forall a. HasChars a => SourceName -> Doc a
text SourceName
"link:"
                  else forall a. Doc a
empty
  let srcSuffix :: Text
srcSuffix = forall a. a -> Maybe a -> a
fromMaybe Text
src (Text -> Text -> Maybe Text
T.stripPrefix Text
"mailto:" Text
src)
  let useAuto :: Bool
useAuto = case [Inline]
txt of
                      [Str Text
s] | Text -> Text
escapeURI Text
s forall a. Eq a => a -> a -> Bool
== Text
srcSuffix -> Bool
True
                      [Inline]
_       -> Bool
False
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
    if Bool
needsPassthrough
       then
         if Bool
useAuto
            then Doc Text
"link:++" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
srcSuffix forall a. Semigroup a => a -> a -> a
<> Doc Text
"++[]"
            else Doc Text
"link:++" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
src forall a. Semigroup a => a -> a -> a
<> Doc Text
"++[" forall a. Semigroup a => a -> a -> a
<> Doc Text
linktext forall a. Semigroup a => a -> a -> a
<> Doc Text
"]"
       else
         if Bool
useAuto
            then forall a. HasChars a => a -> Doc a
literal Text
srcSuffix
            else Doc Text
prefix forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
src forall a. Semigroup a => a -> a -> a
<> Doc Text
"[" forall a. Semigroup a => a -> a -> a
<> Doc Text
linktext forall a. Semigroup a => a -> a -> a
<> Doc Text
"]"
inlineToAsciiDoc WriterOptions
opts (Image (Text, [Text], [(Text, Text)])
attr [Inline]
alternate (Text
src, Text
tit)) =
  (Doc Text
"image:" forall a. Semigroup a => a -> a -> a
<>) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
PandocMonad m =>
WriterOptions
-> (Text, [Text], [(Text, Text)])
-> [Inline]
-> Text
-> Text
-> ADW m (Doc Text)
imageArguments WriterOptions
opts (Text, [Text], [(Text, Text)])
attr [Inline]
alternate Text
src Text
tit
inlineToAsciiDoc WriterOptions
opts (Note [Para [Inline]
inlines]) =
  forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> Inline -> ADW m (Doc Text)
inlineToAsciiDoc WriterOptions
opts ([Block] -> Inline
Note [[Inline] -> Block
Plain [Inline]
inlines])
inlineToAsciiDoc WriterOptions
opts (Note [Plain [Inline]
inlines]) = do
  Doc Text
contents  <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
inlines
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => SourceName -> Doc a
text SourceName
"footnote:[" forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
"]"
-- asciidoc can't handle blank lines in notes
inlineToAsciiDoc WriterOptions
_ (Note [Block]
_) = forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
"[multiblock footnote omitted]"
inlineToAsciiDoc WriterOptions
opts (Span (Text
ident,[Text]
classes,[(Text, Text)]
_) [Inline]
ils) = do
  Doc Text
contents <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
ils
  Bool
isIntraword <- forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Bool
intraword
  let marker :: Doc Text
marker = if Bool
isIntraword then Doc Text
"##" else Doc Text
"#"
  if Text -> Bool
T.null Text
ident Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
classes
     then forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
contents
     else do
       let modifier :: Doc Text
modifier = forall a. HasChars a => Doc a -> Doc a
brackets forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.unwords forall a b. (a -> b) -> a -> b
$
            [ Text
"#" forall a. Semigroup a => a -> a -> a
<> Text
ident | Bool -> Bool
not (Text -> Bool
T.null Text
ident)] forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map (Text
"." forall a. Semigroup a => a -> a -> a
<>) [Text]
classes
       forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Doc Text
modifier forall a. Semigroup a => a -> a -> a
<> Doc Text
marker forall a. Semigroup a => a -> a -> a
<> Doc Text
contents forall a. Semigroup a => a -> a -> a
<> Doc Text
marker

-- | Provides the arguments for both `image:` and `image::`
-- e.g.: sunset.jpg[Sunset,300,200]
imageArguments :: PandocMonad m => WriterOptions ->
  Attr -> [Inline] -> Text -> Text ->
  ADW m (Doc Text)
imageArguments :: forall (m :: * -> *).
PandocMonad m =>
WriterOptions
-> (Text, [Text], [(Text, Text)])
-> [Inline]
-> Text
-> Text
-> ADW m (Doc Text)
imageArguments WriterOptions
opts (Text, [Text], [(Text, Text)])
attr [Inline]
altText Text
src Text
title = do
  let txt :: [Inline]
txt = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
altText Bool -> Bool -> Bool
|| ([Inline]
altText forall a. Eq a => a -> a -> Bool
== [Text -> Inline
Str Text
""])
               then [Text -> Inline
Str forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceName -> Text
T.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceName -> SourceName
dropExtension forall a b. (a -> b) -> a -> b
$ Text -> SourceName
T.unpack Text
src]
               else [Inline]
altText
  Doc Text
linktext <- forall (m :: * -> *).
PandocMonad m =>
WriterOptions -> [Inline] -> ADW m (Doc Text)
inlineListToAsciiDoc WriterOptions
opts [Inline]
txt
  let linktitle :: Doc Text
linktitle = if Text -> Bool
T.null Text
title
                     then forall a. Doc a
empty
                     else Doc Text
",title=\"" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => a -> Doc a
literal Text
title forall a. Semigroup a => a -> a -> a
<> Doc Text
"\""
      showDim :: Direction -> [Doc Text]
showDim Direction
dir = case Direction -> (Text, [Text], [(Text, Text)]) -> Maybe Dimension
dimension Direction
dir (Text, [Text], [(Text, Text)])
attr of
                      Just (Percent Double
a) ->
                        [Doc Text
"scaledwidth=" forall a. Semigroup a => a -> a -> a
<> forall a. HasChars a => SourceName -> Doc a
text (forall a. Show a => a -> SourceName
show (Double -> Dimension
Percent Double
a))]
                      Just Dimension
dim         ->
                        [forall a. HasChars a => SourceName -> Doc a
text (forall a. Show a => a -> SourceName
show Direction
dir) forall a. Semigroup a => a -> a -> a
<> Doc Text
"=" forall a. Semigroup a => a -> a -> a
<>
                          forall a. HasChars a => a -> Doc a
literal (WriterOptions -> Dimension -> Text
showInPixel WriterOptions
opts Dimension
dim)]
                      Maybe Dimension
Nothing          ->
                        []
      dimList :: [Doc Text]
dimList = Direction -> [Doc Text]
showDim Direction
Width forall a. [a] -> [a] -> [a]
++ Direction -> [Doc Text]
showDim Direction
Height
      dims :: Doc Text
dims = if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Doc Text]
dimList
                then forall a. Doc a
empty
                else Doc Text
"," forall a. Semigroup a => a -> a -> a
<> forall a. Monoid a => [a] -> a
mconcat (forall a. a -> [a] -> [a]
intersperse Doc Text
"," [Doc Text]
dimList)
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. HasChars a => a -> Doc a
literal Text
src forall a. Semigroup a => a -> a -> a
<> Doc Text
"[" forall a. Semigroup a => a -> a -> a
<> Doc Text
linktext forall a. Semigroup a => a -> a -> a
<> Doc Text
linktitle forall a. Semigroup a => a -> a -> a
<> Doc Text
dims forall a. Semigroup a => a -> a -> a
<> Doc Text
"]"