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

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

Conversion from reStructuredText to 'Pandoc' document.
-}
module Text.Pandoc.Readers.RST ( readRST ) where
import Control.Arrow (second)
import Control.Monad (forM_, guard, liftM, mplus, mzero, when, unless)
import Control.Monad.Except (throwError)
import Control.Monad.Identity (Identity (..))
import Data.Char (isHexDigit, isSpace, toUpper, isAlphaNum, generalCategory,
                  GeneralCategory(OpenPunctuation, InitialQuote, FinalQuote,
                                  DashPunctuation, OtherSymbol))
import Data.List (deleteFirstsBy, elemIndex, nub, partition, sort, transpose)
import qualified Data.Map as M
import Data.Maybe (fromMaybe, maybeToList, isJust)
import Data.Sequence (ViewR (..), viewr)
import Data.Text (Text)
import qualified Data.Text as T
import Text.Printf (printf)
import Text.Pandoc.Builder (Blocks, Inlines, fromList, setMeta, trimInlines)
import qualified Text.Pandoc.Builder as B
import Text.Pandoc.Class (PandocMonad, readFileFromDirs, fetchItem, getTimestamp)
import Text.Pandoc.CSV (CSVOptions (..), defaultCSVOptions, parseCSV)
import Text.Pandoc.Definition
import Text.Pandoc.Error
import Text.Pandoc.ImageSize (lengthToDim, scaleDimension)
import Text.Pandoc.Logging
import Text.Pandoc.Options
import Text.Pandoc.Parsing
import Text.Pandoc.Shared
import Text.Pandoc.URI
import Text.Pandoc.Walk (walkM)
import qualified Text.Pandoc.UTF8 as UTF8
import Data.Time.Format
import System.FilePath (takeDirectory)

-- TODO:
-- [ ] .. parsed-literal

-- | Parse reStructuredText string and return Pandoc document.
readRST :: (PandocMonad m, ToSources a)
        => ReaderOptions -- ^ Reader options
        -> a
        -> m Pandoc
readRST :: forall (m :: * -> *) a.
(PandocMonad m, ToSources a) =>
ReaderOptions -> a -> m Pandoc
readRST ReaderOptions
opts a
s = do
  parsed <- ParsecT Sources ParserState m Pandoc
-> ParserState -> Sources -> m (Either PandocError Pandoc)
forall (m :: * -> *) t st a.
(Monad m, ToSources t) =>
ParsecT Sources st m a -> st -> t -> m (Either PandocError a)
readWithM ParsecT Sources ParserState m Pandoc
forall (m :: * -> *). PandocMonad m => RSTParser m Pandoc
parseRST ParserState
forall a. Default a => a
def{ stateOptions = opts }
               (Int -> Sources -> Sources
ensureFinalNewlines Int
2 (a -> Sources
forall a. ToSources a => a -> Sources
toSources a
s))
  case parsed of
    Right Pandoc
result -> Pandoc -> m Pandoc
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Pandoc
result
    Left PandocError
e       -> PandocError -> m Pandoc
forall a. PandocError -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError PandocError
e

type RSTParser m = ParsecT Sources ParserState m

--
-- Constants and data structure definitions
---

bulletListMarkers :: [Char]
bulletListMarkers :: [Char]
bulletListMarkers = [Char]
"*+-•‣⁃"

underlineChars :: [Char]
underlineChars :: [Char]
underlineChars = [Char]
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"

-- treat these as potentially non-text when parsing inline:
specialChars :: [Char]
specialChars :: [Char]
specialChars = [Char]
"\\`|*_<>$:/[]{}()-.\"'\8216\8217\8220\8221"

--
-- parsing documents
--

isHeader :: Int -> Block -> Bool
isHeader :: Int -> Block -> Bool
isHeader Int
n (Header Int
x Attr
_ [Inline]
_) = Int
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n
isHeader Int
_ Block
_              = Bool
False

-- | Promote all headers in a list of blocks.  (Part of
-- title transformation for RST.)
promoteHeaders :: Int -> [Block] -> [Block]
promoteHeaders :: Int -> [Block] -> [Block]
promoteHeaders Int
num (Header Int
level Attr
attr [Inline]
text:[Block]
rest) =
    Int -> Attr -> [Inline] -> Block
Header (Int
level Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
num) Attr
attr [Inline]
textBlock -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:Int -> [Block] -> [Block]
promoteHeaders Int
num [Block]
rest
promoteHeaders Int
num (Block
other:[Block]
rest) = Block
otherBlock -> [Block] -> [Block]
forall a. a -> [a] -> [a]
:Int -> [Block] -> [Block]
promoteHeaders Int
num [Block]
rest
promoteHeaders Int
_   [] = []

-- | If list of blocks starts with a header (or a header and subheader)
-- of level that are not found elsewhere, return it as a title and
-- promote all the other headers.  Also process a definition list right
-- after the title block as metadata.
titleTransform :: ([Block], Meta)  -- ^ list of blocks, metadata
               -> ([Block], Meta)  -- ^ modified list of blocks, metadata
titleTransform :: ([Block], Meta) -> ([Block], Meta)
titleTransform ([Block]
bs, Meta
meta) =
  let ([Block]
bs', Meta
meta') =
       case [Block]
bs of
          (Header Int
1 Attr
_ [Inline]
head1:Header Int
2 Attr
_ [Inline]
head2:[Block]
rest)
           | Bool -> Bool
not ((Block -> Bool) -> [Block] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Int -> Block -> Bool
isHeader Int
1) [Block]
rest Bool -> Bool -> Bool
|| (Block -> Bool) -> [Block] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Int -> Block -> Bool
isHeader Int
2) [Block]
rest) -> -- tit/sub
            (Int -> [Block] -> [Block]
promoteHeaders Int
2 [Block]
rest, Text -> Many Inline -> Meta -> Meta
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
forall b. ToMetaValue b => Text -> b -> Meta -> Meta
setMeta Text
"title" ([Inline] -> Many Inline
forall a. [a] -> Many a
fromList [Inline]
head1) (Meta -> Meta) -> Meta -> Meta
forall a b. (a -> b) -> a -> b
$
              Text -> Many Inline -> Meta -> Meta
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
forall b. ToMetaValue b => Text -> b -> Meta -> Meta
setMeta Text
"subtitle" ([Inline] -> Many Inline
forall a. [a] -> Many a
fromList [Inline]
head2) Meta
meta)
          (Header Int
1 Attr
_ [Inline]
head1:[Block]
rest)
           | Bool -> Bool
not ((Block -> Bool) -> [Block] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Int -> Block -> Bool
isHeader Int
1) [Block]
rest) -> -- title only
            (Int -> [Block] -> [Block]
promoteHeaders Int
1 [Block]
rest,
                Text -> Many Inline -> Meta -> Meta
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
forall b. ToMetaValue b => Text -> b -> Meta -> Meta
setMeta Text
"title" ([Inline] -> Many Inline
forall a. [a] -> Many a
fromList [Inline]
head1) Meta
meta)
          [Block]
_ -> ([Block]
bs, Meta
meta)
  in   case [Block]
bs' of
          (DefinitionList [([Inline], [[Block]])]
ds : [Block]
rest) ->
            ([Block]
rest, [([Inline], [[Block]])] -> Meta -> Meta
metaFromDefList [([Inline], [[Block]])]
ds Meta
meta')
          [Block]
_ -> ([Block]
bs', Meta
meta')

metaFromDefList :: [([Inline], [[Block]])] -> Meta -> Meta
metaFromDefList :: [([Inline], [[Block]])] -> Meta -> Meta
metaFromDefList [([Inline], [[Block]])]
ds Meta
meta = Meta -> Meta
adjustAuthors (Meta -> Meta) -> Meta -> Meta
forall a b. (a -> b) -> a -> b
$ (([Inline], [[Block]]) -> Meta -> Meta)
-> Meta -> [([Inline], [[Block]])] -> Meta
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ([Inline], [[Block]]) -> Meta -> Meta
forall {a} {a}.
(HasMeta a, Walkable Inline a) =>
(a, [[Block]]) -> a -> a
f Meta
meta [([Inline], [[Block]])]
ds
 where f :: (a, [[Block]]) -> a -> a
f (a
k,[[Block]]
v) =
         case [[Block]]
v of
           [[Plain [Inline]
ils]] ->  Text -> MetaValue -> a -> a
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
forall b. ToMetaValue b => Text -> b -> a -> a
setMeta (Text -> Text
T.toLower (a -> Text
forall a. Walkable Inline a => a -> Text
stringify a
k)) (MetaValue -> a -> a) -> MetaValue -> a -> a
forall a b. (a -> b) -> a -> b
$ [Inline] -> MetaValue
MetaInlines [Inline]
ils
           [[Block]]
_ -> Text -> Many Block -> a -> a
forall a b. (HasMeta a, ToMetaValue b) => Text -> b -> a -> a
forall b. ToMetaValue b => Text -> b -> a -> a
setMeta (Text -> Text
T.toLower (a -> Text
forall a. Walkable Inline a => a -> Text
stringify a
k)) (Many Block -> a -> a) -> Many Block -> a -> a
forall a b. (a -> b) -> a -> b
$ [Many Block] -> Many Block
forall a. Monoid a => [a] -> a
mconcat ([Many Block] -> Many Block) -> [Many Block] -> Many Block
forall a b. (a -> b) -> a -> b
$ ([Block] -> Many Block) -> [[Block]] -> [Many Block]
forall a b. (a -> b) -> [a] -> [b]
map [Block] -> Many Block
forall a. [a] -> Many a
fromList [[Block]]
v
       adjustAuthors :: Meta -> Meta
adjustAuthors (Meta Map Text MetaValue
metamap) = Map Text MetaValue -> Meta
Meta (Map Text MetaValue -> Meta) -> Map Text MetaValue -> Meta
forall a b. (a -> b) -> a -> b
$ (MetaValue -> MetaValue)
-> Text -> Map Text MetaValue -> Map Text MetaValue
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
M.adjust MetaValue -> MetaValue
splitAuthors Text
"author"
                                           (Map Text MetaValue -> Map Text MetaValue)
-> Map Text MetaValue -> Map Text MetaValue
forall a b. (a -> b) -> a -> b
$ (Text -> Text) -> Map Text MetaValue -> Map Text MetaValue
forall k2 k1 a. Ord k2 => (k1 -> k2) -> Map k1 a -> Map k2 a
M.mapKeys (\Text
k ->
                                                 if Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"authors"
                                                    then Text
"author"
                                                    else Text
k) Map Text MetaValue
metamap
       splitAuthors :: MetaValue -> MetaValue
splitAuthors (MetaInlines [Inline]
xs)  = [MetaValue] -> MetaValue
MetaList ([MetaValue] -> MetaValue) -> [MetaValue] -> MetaValue
forall a b. (a -> b) -> a -> b
$ ([Inline] -> MetaValue) -> [[Inline]] -> [MetaValue]
forall a b. (a -> b) -> [a] -> [b]
map [Inline] -> MetaValue
MetaInlines
                                                 ([[Inline]] -> [MetaValue]) -> [[Inline]] -> [MetaValue]
forall a b. (a -> b) -> a -> b
$ [Inline] -> [[Inline]]
splitAuthors' [Inline]
xs
       splitAuthors MetaValue
x                 = MetaValue
x
       splitAuthors' :: [Inline] -> [[Inline]]
splitAuthors'                  = ([Inline] -> [Inline]) -> [[Inline]] -> [[Inline]]
forall a b. (a -> b) -> [a] -> [b]
map [Inline] -> [Inline]
normalizeSpaces ([[Inline]] -> [[Inline]])
-> ([Inline] -> [[Inline]]) -> [Inline] -> [[Inline]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                                         [Inline] -> [[Inline]]
splitOnSemi ([Inline] -> [[Inline]])
-> ([Inline] -> [Inline]) -> [Inline] -> [[Inline]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Inline -> [Inline]) -> [Inline] -> [Inline]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Inline -> [Inline]
factorSemi
       normalizeSpaces :: [Inline] -> [Inline]
normalizeSpaces                = [Inline] -> [Inline]
forall a. [a] -> [a]
reverse ([Inline] -> [Inline])
-> ([Inline] -> [Inline]) -> [Inline] -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Inline -> Bool) -> [Inline] -> [Inline]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Inline -> Bool
isSp ([Inline] -> [Inline])
-> ([Inline] -> [Inline]) -> [Inline] -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Inline] -> [Inline]
forall a. [a] -> [a]
reverse ([Inline] -> [Inline])
-> ([Inline] -> [Inline]) -> [Inline] -> [Inline]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                                         (Inline -> Bool) -> [Inline] -> [Inline]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Inline -> Bool
isSp
       isSp :: Inline -> Bool
isSp Inline
Space     = Bool
True
       isSp Inline
SoftBreak = Bool
True
       isSp Inline
LineBreak = Bool
True
       isSp Inline
_         = Bool
False
       splitOnSemi :: [Inline] -> [[Inline]]
splitOnSemi                    = (Inline -> Bool) -> [Inline] -> [[Inline]]
forall a. (a -> Bool) -> [a] -> [[a]]
splitBy (Inline -> Inline -> Bool
forall a. Eq a => a -> a -> Bool
==Text -> Inline
Str Text
";")
       factorSemi :: Inline -> [Inline]
factorSemi (Str Text
"")            = []
       factorSemi (Str Text
s)             = case (Char -> Bool) -> Text -> (Text, Text)
T.break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
';') Text
s of
                                          (Text
xs,Text
"") -> [Text -> Inline
Str Text
xs]
                                          (Text
xs,Text -> Maybe (Char, Text)
T.uncons -> Just (Char
';',Text
ys)) -> Text -> Inline
Str Text
xs Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: Text -> Inline
Str Text
";" Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:
                                            Inline -> [Inline]
factorSemi (Text -> Inline
Str Text
ys)
                                          (Text
xs,Text
ys) -> Text -> Inline
Str Text
xs Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
:
                                            Inline -> [Inline]
factorSemi (Text -> Inline
Str Text
ys)
       factorSemi Inline
x                   = [Inline
x]

parseRST :: PandocMonad m => RSTParser m Pandoc
parseRST :: forall (m :: * -> *). PandocMonad m => RSTParser m Pandoc
parseRST = do
  standalone <- (ReaderOptions -> Bool) -> ParsecT Sources ParserState m Bool
forall st s (m :: * -> *) t b.
(HasReaderOptions st, Stream s m t) =>
(ReaderOptions -> b) -> ParsecT s st m b
forall s (m :: * -> *) t b.
Stream s m t =>
(ReaderOptions -> b) -> ParsecT s ParserState m b
getOption ReaderOptions -> Bool
readerStandalone
  optional blanklines -- skip blank lines at beginning of file
  blocks <- B.toList <$> parseBlocks
  citations <- sort . M.toList . stateCitations <$> getState
  citationItems <- mapM parseCitation citations
  let refBlock = [Attr -> [Block] -> Block
Div (Text
"citations",[],[]) ([Block] -> Block) -> [Block] -> Block
forall a b. (a -> b) -> a -> b
$
                 Many Block -> [Block]
forall a. Many a -> [a]
B.toList (Many Block -> [Block]) -> Many Block -> [Block]
forall a b. (a -> b) -> a -> b
$ [(Many Inline, [Many Block])] -> Many Block
B.definitionList [(Many Inline, [Many Block])]
citationItems | Bool -> Bool
not ([(Many Inline, [Many Block])] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Many Inline, [Many Block])]
citationItems)]
  state <- getState
  let meta = ParserState -> Meta
stateMeta ParserState
state
  let (blocks', meta') = if standalone
                            then titleTransform (blocks, meta)
                            else (blocks, meta)
  let reversedNotes = ParserState -> [(Text, Text)]
stateNotes ParserState
state
  updateState $ \ParserState
s -> ParserState
s { stateNotes = reverse reversedNotes }
  doc <- walkM resolveReferences =<<
         walkM resolveBlockSubstitutions
         (Pandoc meta' (blocks' ++ refBlock))
  reportLogMessages
  return doc

resolveBlockSubstitutions :: PandocMonad m => Block -> RSTParser m Block
resolveBlockSubstitutions :: forall (m :: * -> *). PandocMonad m => Block -> RSTParser m Block
resolveBlockSubstitutions x :: Block
x@(Para [Link Attr
_attr [Inline]
_ (Text
s,Text
_)])
  | Just Text
ref <- Text -> Text -> Maybe Text
T.stripPrefix Text
"##SUBST##" Text
s = do
          substTable <- ParserState -> SubstTable
stateSubstitutions (ParserState -> SubstTable)
-> ParsecT Sources ParserState m ParserState
-> ParsecT Sources ParserState m SubstTable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
          let key@(Key key') = toKey $ stripFirstAndLast ref
          case M.lookup key substTable of
               Maybe (Many Block)
Nothing     -> do
                 pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                 logMessage $ ReferenceNotFound (tshow key') pos
                 return x
               Just Many Block
target -> case
                 Many Block -> [Block]
forall a. Many a -> [a]
B.toList Many Block
target of
                   [Block
bl] -> Block -> ParsecT Sources ParserState m Block
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Block
bl
                   [Block]
bls -> Block -> ParsecT Sources ParserState m Block
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Block -> ParsecT Sources ParserState m Block)
-> Block -> ParsecT Sources ParserState m Block
forall a b. (a -> b) -> a -> b
$ Attr -> [Block] -> Block
Div Attr
nullAttr [Block]
bls
resolveBlockSubstitutions Block
x = Block -> ParsecT Sources ParserState m Block
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Block
x

resolveReferences :: PandocMonad m => Inline -> RSTParser m Inline
resolveReferences :: forall (m :: * -> *). PandocMonad m => Inline -> RSTParser m Inline
resolveReferences x :: Inline
x@(Link Attr
_ [Inline]
ils (Text
s,Text
_))
  | Just Text
ref <- Text -> Text -> Maybe Text
T.stripPrefix Text
"##REF##" Text
s = do
      let isAnonKey :: Key -> Bool
isAnonKey (Key (Text -> Maybe (Char, Text)
T.uncons -> Just (Char
'_',Text
_))) = Bool
True
          isAnonKey Key
_                                = Bool
False
      state <- ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
      let keyTable = ParserState -> KeyTable
stateKeys ParserState
state
      let anonKeys = [Key] -> [Key]
forall a. Ord a => [a] -> [a]
sort ([Key] -> [Key]) -> [Key] -> [Key]
forall a b. (a -> b) -> a -> b
$ (Key -> Bool) -> [Key] -> [Key]
forall a. (a -> Bool) -> [a] -> [a]
filter Key -> Bool
isAnonKey ([Key] -> [Key]) -> [Key] -> [Key]
forall a b. (a -> b) -> a -> b
$ KeyTable -> [Key]
forall k a. Map k a -> [k]
M.keys KeyTable
keyTable
      key <-  if ref == "_" -- anonymous key
                then
                  case anonKeys of
                    []    -> ParsecT Sources ParserState m Key
forall a. ParsecT Sources ParserState m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero -- TODO log?
                    (Key
k:[Key]
_) -> Key -> ParsecT Sources ParserState m Key
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Key
k
                else return $ toKey ref
      ((src,tit), attr) <- lookupKey [] key
      -- if anonymous link, remove key so it won't be used again
      when (isAnonKey key) $ updateState $ \ParserState
st ->
                              ParserState
st{ stateKeys = M.delete key keyTable }
      return $ Link attr ils (src, tit)
  | Just Text
ref <- Text -> Text -> Maybe Text
T.stripPrefix Text
"##NOTE##" Text
s = do
      state <- ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
      let notes = ParserState -> [(Text, Text)]
stateNotes ParserState
state
      case lookup ref notes of
        Maybe Text
Nothing   -> do
          pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
          logMessage $ ReferenceNotFound ref pos
          return x
        Just Text
raw  -> do
          -- We temporarily empty the note list while parsing the note,
          -- so that we don't get infinite loops with notes inside notes...
          -- Note references inside other notes are allowed in reST, but
          -- not yet in this implementation.
          (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((ParserState -> ParserState) -> ParsecT Sources ParserState m ())
-> (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ \ParserState
st -> ParserState
st{ stateNotes = [] }
          contents <- ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
raw
          let newnotes = if Text
ref Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"*" Bool -> Bool -> Bool
|| Text
ref Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"#" -- auto-numbered
                            -- delete the note so the next auto-numbered note
                            -- doesn't get the same contents:
                            then ((Text, Text) -> (Text, Text) -> Bool)
-> [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. (a -> a -> Bool) -> [a] -> [a] -> [a]
deleteFirstsBy (Text, Text) -> (Text, Text) -> Bool
forall a. Eq a => a -> a -> Bool
(==) [(Text, Text)]
notes [(Text
ref,Text
raw)]
                            else [(Text, Text)]
notes
          updateState $ \ParserState
st -> ParserState
st{ stateNotes = newnotes }
          return $ Note (B.toList contents)
  | Just Text
ref <- Text -> Text -> Maybe Text
T.stripPrefix Text
"##SUBST##" Text
s = do
          substTable <- ParserState -> SubstTable
stateSubstitutions (ParserState -> SubstTable)
-> ParsecT Sources ParserState m ParserState
-> ParsecT Sources ParserState m SubstTable
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
          let key@(Key key') = toKey $ stripFirstAndLast ref
          case M.lookup key substTable of
               Maybe (Many Block)
Nothing     -> do
                 pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
                 logMessage $ ReferenceNotFound (tshow key') pos
                 return x
               Just Many Block
target -> case
                 Many Block -> [Block]
forall a. Many a -> [a]
B.toList Many Block
target of
                   [Para [Inline
t]] -> Inline -> ParsecT Sources ParserState m Inline
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Inline
t
                   [Para [Inline]
xs] -> Inline -> ParsecT Sources ParserState m Inline
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> ParsecT Sources ParserState m Inline)
-> Inline -> ParsecT Sources ParserState m Inline
forall a b. (a -> b) -> a -> b
$ Attr -> [Inline] -> Inline
Span Attr
nullAttr [Inline]
xs
                   [Block]
bls -> Inline -> ParsecT Sources ParserState m Inline
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Inline -> ParsecT Sources ParserState m Inline)
-> Inline -> ParsecT Sources ParserState m Inline
forall a b. (a -> b) -> a -> b
$ Attr -> [Inline] -> Inline
Span Attr
nullAttr ([Inline] -> Inline) -> [Inline] -> Inline
forall a b. (a -> b) -> a -> b
$ [Block] -> [Inline]
blocksToInlines [Block]
bls
  | Bool
otherwise = Inline -> ParsecT Sources ParserState m Inline
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Inline
x
resolveReferences Inline
x = Inline -> ParsecT Sources ParserState m Inline
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Inline
x

parseCitation :: PandocMonad m
              => (Text, Text) -> RSTParser m (Inlines, [Blocks])
parseCitation :: forall (m :: * -> *).
PandocMonad m =>
(Text, Text) -> RSTParser m (Many Inline, [Many Block])
parseCitation (Text
ref, Text
raw) = do
  contents <- ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
raw
  return (B.spanWith (ref, ["citation-label"], []) (B.str ref),
           [contents])


--
-- parsing blocks
--

parseBlocks :: PandocMonad m => RSTParser m Blocks
parseBlocks :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks = [Many Block] -> Many Block
forall a. Monoid a => [a] -> a
mconcat ([Many Block] -> Many Block)
-> ParsecT Sources ParserState m [Many Block]
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m [Many Block]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
block ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof

block :: PandocMonad m => RSTParser m Blocks
block :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
block = [ParsecT Sources ParserState m (Many Block)]
-> ParsecT Sources ParserState m (Many Block)
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
codeBlock
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
blockQuote
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
fieldList
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
optionList
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
referenceKey
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
noteBlock
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
citationBlock
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
directive
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
anchor
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
comment
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
header
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) st.
Monad m =>
ParsecT Sources st m (Many Block)
hrule
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
lineBlock     -- must go before definitionList
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
table
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
list
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
lhsCodeBlock
               , ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
para
               , Many Block
forall a. Monoid a => a
mempty Many Block
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m (Many Block)
forall a b.
a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Text
blanklines
               ] ParsecT Sources ParserState m (Many Block)
-> [Char] -> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"block"

--
-- field list
--

rawFieldListItem :: Monad m => Int -> RSTParser m (Text, Text)
rawFieldListItem :: forall (m :: * -> *). Monad m => Int -> RSTParser m (Text, Text)
rawFieldListItem Int
minIndent = ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Text, Text)
 -> ParsecT Sources ParserState m (Text, Text))
-> ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall a b. (a -> b) -> a -> b
$ do
  indent <- [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Char] -> Int)
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
' ')
  guard $ indent >= minIndent
  char ':'
  name <- many1TillChar (noneOf "\n") (char ':')
  (() <$ lookAhead newline) <|> skipMany1 spaceChar
  first <- anyLine
  rest <- option "" $ try $ do lookAhead (count indent (char ' ') >> spaceChar)
                               indentedBlock
  let raw = (if Text -> Bool
T.null Text
first then Text
"" else Text
first Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n") Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rest Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
            (if Text -> Bool
T.null Text
first Bool -> Bool -> Bool
&& Text -> Bool
T.null Text
rest then Text
"" else Text
"\n")
  return (name, raw)

fieldListItem :: PandocMonad m => Int -> RSTParser m (Inlines, [Blocks])
fieldListItem :: forall (m :: * -> *).
PandocMonad m =>
Int -> RSTParser m (Many Inline, [Many Block])
fieldListItem Int
minIndent = ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline, [Many Block])
 -> ParsecT Sources ParserState m (Many Inline, [Many Block]))
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
forall a b. (a -> b) -> a -> b
$ do
  (name, raw) <- Int -> RSTParser m (Text, Text)
forall (m :: * -> *). Monad m => Int -> RSTParser m (Text, Text)
rawFieldListItem Int
minIndent
  term <- parseInlineFromText name
  contents <- parseFromString' parseBlocks raw
  optional blanklines
  let defn = case Many Block -> [Block]
forall a. Many a -> [a]
B.toList Many Block
contents of
                [Para [Inline]
ils] -> [Many Inline -> Many Block
B.plain (Many Inline -> Many Block) -> Many Inline -> Many Block
forall a b. (a -> b) -> a -> b
$ [Inline] -> Many Inline
forall a. [a] -> Many a
B.fromList [Inline]
ils] -- see #7766
                [Block]
_ -> [Many Block
contents]
  return (term, defn)

fieldList :: PandocMonad m => RSTParser m Blocks
fieldList :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
fieldList = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  indent <- [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Char] -> Int)
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar)
  items <- many1 $ fieldListItem indent
  case items of
     []     -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Many Block
forall a. Monoid a => a
mempty
     [(Many Inline, [Many Block])]
items' -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ [(Many Inline, [Many Block])] -> Many Block
B.definitionList [(Many Inline, [Many Block])]
items'

optionList :: PandocMonad m => RSTParser m Blocks
optionList :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
optionList = [(Many Inline, [Many Block])] -> Many Block
B.definitionList ([(Many Inline, [Many Block])] -> Many Block)
-> ParsecT Sources ParserState m [(Many Inline, [Many Block])]
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m [(Many Inline, [Many Block])]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources ParserState m (Many Inline, [Many Block])
forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, [Many Block])
optionListItem

optionListItem :: PandocMonad m => RSTParser m (Inlines, [Blocks])
optionListItem :: forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, [Many Block])
optionListItem = ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline, [Many Block])
 -> ParsecT Sources ParserState m (Many Inline, [Many Block]))
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
forall a b. (a -> b) -> a -> b
$ do
  opts <- ([()], Text) -> Text
forall a b. (a, b) -> b
snd (([()], Text) -> Text)
-> ParsecT Sources ParserState m ([()], Text)
-> ParsecT Sources ParserState m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m [()]
-> ParsecT Sources ParserState m ([()], Text)
forall (m :: * -> *) st a.
Monad m =>
ParsecT Sources st m a -> ParsecT Sources st m (a, Text)
withRaw (do
     let anyOpt :: ParsecT Sources ParserState m ()
anyOpt = ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
shortOpt ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
longOpt ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
dosOpt
     ParsecT Sources ParserState m ()
anyOpt
     ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m [()]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m [()])
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m [()]
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
',' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Sources ParserState m ()
anyOpt))
  -- at least two spaces
  rawfirst <- try (char ' ' *> many1 (char ' ') *> anyLineNewline)
                    <|> try (mempty <$ skipMany spaceChar <* newline)
  bodyElements <- do
    raw <- option "" indentedBlock
    parseFromString' parseBlocks $ (rawfirst <> raw) <> "\n\n"
  optional blanklines
  pure (B.code opts, [bodyElements])

shortOpt :: PandocMonad m => RSTParser m ()
shortOpt :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
shortOpt = ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-'
  ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum
  ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
' ') ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
optArg)

optArg :: PandocMonad m => RSTParser m ()
optArg :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
optArg = do
  c <- ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
letter ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'<'
  if c == '<'
     then () <$ manyTill (noneOf "<>") (char '>')
     else skipMany (alphaNum <|> char '_' <|> char '-')

longOpt :: PandocMonad m => RSTParser m ()
longOpt :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
longOpt = ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-'
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-'
  ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 (ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'_')
  ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
" =" ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
optArg)

dosOpt :: PandocMonad m => RSTParser m ()
dosOpt :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
dosOpt = ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'/'
  ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'?'
  ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
' ' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
optArg)

--
-- line block
--

lineBlock :: PandocMonad m => RSTParser m Blocks
lineBlock :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
lineBlock = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  lines' <- ParsecT Sources ParserState m [Text]
forall (m :: * -> *) st. Monad m => ParsecT Sources st m [Text]
lineBlockLines
  lines'' <- mapM parseInlineFromText lines'
  return $ B.lineBlock lines''

lineBlockDirective :: PandocMonad m => Text -> RSTParser m Blocks
lineBlockDirective :: forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Block)
lineBlockDirective Text
body = do
  lines' <- (Text -> ParsecT Sources ParserState m (Many Inline))
-> [Text] -> ParsecT Sources ParserState m [Many Inline]
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 -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText ([Text] -> ParsecT Sources ParserState m [Many Inline])
-> [Text] -> ParsecT Sources ParserState m [Many Inline]
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ Text -> Text
stripTrailingNewlines Text
body
  return $ B.lineBlock lines'

--
-- paragraph block
--

-- note: paragraph can end in a :: starting a code block
para :: PandocMonad m => RSTParser m Blocks
para :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
para = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  result <- Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline
  option (B.plain result) $ try $ do
    newline
    blanklines
    case viewr (B.unMany result) of
         Seq Inline
ys :> Str Text
xs | Text
"::" Text -> Text -> Bool
`T.isSuffixOf` Text
xs -> do
              raw <- Many Block
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Many Block
forall a. Monoid a => a
mempty ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
codeBlockBody
              return $ B.para (B.Many ys <> B.str (T.take (T.length xs - 1) xs))
                         <> raw
         ViewR Inline
_ -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> Many Block
B.para Many Inline
result)

plain :: PandocMonad m => RSTParser m Blocks
plain :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
plain = Many Inline -> Many Block
B.plain (Many Inline -> Many Block)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Block)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline

--
-- header blocks
--

header :: PandocMonad m => RSTParser m Blocks
header :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
header = RSTParser m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
doubleHeader RSTParser m (Many Block)
-> RSTParser m (Many Block) -> RSTParser m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
singleHeader RSTParser m (Many Block) -> [Char] -> RSTParser m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"header"

-- a header with lines on top and bottom
doubleHeader :: PandocMonad m => RSTParser m Blocks
doubleHeader :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
doubleHeader = do
  (txt, c) <- RSTParser m (Many Inline, Char)
forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, Char)
doubleHeader'
  -- check to see if we've had this kind of header before.
  -- if so, get appropriate level.  if not, add to list.
  state <- getState
  let headerTable = ParserState -> [HeaderType]
stateHeaderTable ParserState
state
  let (headerTable',level) = case elemIndex (DoubleHeader c) headerTable of
        Just Int
ind -> ([HeaderType]
headerTable, Int
ind Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        Maybe Int
Nothing  -> ([HeaderType]
headerTable [HeaderType] -> [HeaderType] -> [HeaderType]
forall a. [a] -> [a] -> [a]
++ [Char -> HeaderType
DoubleHeader Char
c], [HeaderType] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [HeaderType]
headerTable Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  setState (state { stateHeaderTable = headerTable' })
  attr@(ident,_,_) <- registerHeader nullAttr txt
  let key = Text -> Key
toKey (Many Inline -> Text
forall a. Walkable Inline a => a -> Text
stringify Many Inline
txt)
  updateState $ \ParserState
s ->
    ParserState
s { stateKeys = M.insert key (("#" <> ident,""), nullAttr) $ stateKeys s }
  return $ B.headerWith attr level txt

doubleHeader' :: PandocMonad m => RSTParser m (Inlines, Char)
doubleHeader' :: forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, Char)
doubleHeader' = ParsecT Sources ParserState m (Many Inline, Char)
-> ParsecT Sources ParserState m (Many Inline, Char)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline, Char)
 -> ParsecT Sources ParserState m (Many Inline, Char))
-> ParsecT Sources ParserState m (Many Inline, Char)
-> ParsecT Sources ParserState m (Many Inline, Char)
forall a b. (a -> b) -> a -> b
$ do
  c <- [Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
underlineChars
  rest <- many (char c)  -- the top line
  let lenTop = [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Char
cChar -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
rest)
  skipSpaces
  newline
  txt <- trimInlines . mconcat <$> many1 (notFollowedBy blankline >> inline)
  pos <- getPosition
  let len = SourcePos -> Int
sourceColumn SourcePos
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  when (len > lenTop) $ Prelude.fail "title longer than border"
  blankline              -- spaces and newline
  count lenTop (char c)  -- the bottom line
  blanklines
  return (txt, c)

-- a header with line on the bottom only
singleHeader :: PandocMonad m => RSTParser m Blocks
singleHeader :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
singleHeader = do
  (txt, c) <- RSTParser m (Many Inline, Char)
forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, Char)
singleHeader'
  state <- getState
  let headerTable = ParserState -> [HeaderType]
stateHeaderTable ParserState
state
  let (headerTable',level) = case elemIndex (SingleHeader c) headerTable of
        Just Int
ind -> ([HeaderType]
headerTable, Int
ind Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
        Maybe Int
Nothing  -> ([HeaderType]
headerTable [HeaderType] -> [HeaderType] -> [HeaderType]
forall a. [a] -> [a] -> [a]
++ [Char -> HeaderType
SingleHeader Char
c], [HeaderType] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [HeaderType]
headerTable Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  setState (state { stateHeaderTable = headerTable' })
  attr@(ident,_,_) <- registerHeader nullAttr txt
  let key = Text -> Key
toKey (Many Inline -> Text
forall a. Walkable Inline a => a -> Text
stringify Many Inline
txt)
  updateState $ \ParserState
s ->
    ParserState
s { stateKeys = M.insert key (("#" <> ident,""), nullAttr) $ stateKeys s }
  return $ B.headerWith attr level txt

singleHeader' :: PandocMonad m => RSTParser m (Inlines, Char)
singleHeader' :: forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, Char)
singleHeader' = ParsecT Sources ParserState m (Many Inline, Char)
-> ParsecT Sources ParserState m (Many Inline, Char)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline, Char)
 -> ParsecT Sources ParserState m (Many Inline, Char))
-> ParsecT Sources ParserState m (Many Inline, Char)
-> ParsecT Sources ParserState m (Many Inline, Char)
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m ()
forall b s (m :: * -> *) a st.
(Show b, Stream s m a) =>
ParsecT s st m b -> ParsecT s st m ()
notFollowedBy' ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
whitespace
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT Sources ParserState m Char
 -> ParsecT Sources ParserState m Char)
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
underlineChars
  txt <- Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline)
  pos <- getPosition
  let len = SourcePos -> Int
sourceColumn SourcePos
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
  blankline
  c <- oneOf underlineChars
  count (len - 1) (char c)
  many (char c)
  blanklines
  return (txt, c)

--
-- hrule block
--

hrule :: Monad m => ParsecT Sources st m Blocks
hrule :: forall (m :: * -> *) st.
Monad m =>
ParsecT Sources st m (Many Block)
hrule = ParsecT Sources st m (Many Block)
-> ParsecT Sources st m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m (Many Block)
 -> ParsecT Sources st m (Many Block))
-> ParsecT Sources st m (Many Block)
-> ParsecT Sources st m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  chr <- [Char] -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
underlineChars
  count 3 (char chr)
  skipMany (char chr)
  blankline
  blanklines
  return B.horizontalRule

--
-- code blocks
--

-- read a line indented by a given string
indentedLine :: (HasReaderOptions st, Monad m)
             => Int -> ParsecT Sources st m Text
indentedLine :: forall st (m :: * -> *).
(HasReaderOptions st, Monad m) =>
Int -> ParsecT Sources st m Text
indentedLine Int
indents = ParsecT Sources st m Text -> ParsecT Sources st m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m Text -> ParsecT Sources st m Text)
-> ParsecT Sources st m Text -> ParsecT Sources st m Text
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources st m Char -> ParsecT Sources st m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT Sources st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar
  Int -> ParsecT Sources st m Int
forall st (m :: * -> *).
(HasReaderOptions st, Monad m) =>
Int -> ParsecT Sources st m Int
gobbleAtMostSpaces Int
indents
  ParsecT Sources st m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine

-- one or more indented lines, possibly separated by blank lines.
-- any amount of indentation will work.
indentedBlock :: (HasReaderOptions st, Monad m)
              => ParsecT Sources st m Text
indentedBlock :: forall st (m :: * -> *).
(HasReaderOptions st, Monad m) =>
ParsecT Sources st m Text
indentedBlock = ParsecT Sources st m Text -> ParsecT Sources st m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m Text -> ParsecT Sources st m Text)
-> ParsecT Sources st m Text -> ParsecT Sources st m Text
forall a b. (a -> b) -> a -> b
$ do
  indents <- [Char] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Char] -> Int)
-> ParsecT Sources st m [Char] -> ParsecT Sources st m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources st m [Char] -> ParsecT Sources st m [Char]
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT Sources st m Char -> ParsecT Sources st m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar)
  lns <- many1 $ try $ do b <- option "" blanklines
                          l <- indentedLine indents
                          return (b <> l)
  optional blanklines
  return $ T.unlines lns

quotedBlock :: Monad m => ParsecT Sources st m Text
quotedBlock :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
quotedBlock = ParsecT Sources st m Text -> ParsecT Sources st m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m Text -> ParsecT Sources st m Text)
-> ParsecT Sources st m Text -> ParsecT Sources st m Text
forall a b. (a -> b) -> a -> b
$ do
    quote <- ParsecT Sources st m Char -> ParsecT Sources st m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT Sources st m Char -> ParsecT Sources st m Char)
-> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall a b. (a -> b) -> a -> b
$ [Char] -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"
    lns <- many1 $ lookAhead (char quote) >> anyLine
    optional blanklines
    return $ T.unlines lns

codeBlockStart :: Monad m => ParsecT Sources st m Char
codeBlockStart :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m Char
codeBlockStart = [Char] -> ParsecT Sources st m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"::" ParsecT Sources st m [Char]
-> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall a b.
ParsecT Sources st m a
-> ParsecT Sources st m b -> ParsecT Sources st m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline ParsecT Sources st m Char
-> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall a b.
ParsecT Sources st m a
-> ParsecT Sources st m b -> ParsecT Sources st m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline

codeBlock :: Monad m => ParsecT Sources ParserState m Blocks
codeBlock :: forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
codeBlock = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m Char
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Char
codeBlockStart ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
codeBlockBody

codeBlockBody :: Monad m => ParsecT Sources ParserState m Blocks
codeBlockBody :: forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
codeBlockBody = do
  lang <- ParserState -> Maybe Text
stateRstHighlight (ParserState -> Maybe Text)
-> ParsecT Sources ParserState m ParserState
-> ParsecT Sources ParserState m (Maybe Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  try $ B.codeBlockWith ("", maybeToList lang, []) . stripTrailingNewlines <$>
                (indentedBlock <|> quotedBlock)

lhsCodeBlock :: Monad m => RSTParser m Blocks
lhsCodeBlock :: forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
lhsCodeBlock = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition ParsecT Sources ParserState m SourcePos
-> (SourcePos -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> (a -> ParsecT Sources ParserState m b)
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Bool -> ParsecT Sources ParserState m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT Sources ParserState m ())
-> (SourcePos -> Bool)
-> SourcePos
-> ParsecT Sources ParserState m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
==Int
1) (Int -> Bool) -> (SourcePos -> Int) -> SourcePos -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourcePos -> Int
sourceColumn
  Extension -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasReaderOptions st) =>
Extension -> ParsecT s st m ()
guardEnabled Extension
Ext_literate_haskell
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Sources ParserState m Char
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Char
codeBlockStart
  lns <- ParsecT Sources ParserState m [Text]
forall (m :: * -> *) st. Monad m => ParsecT Sources st m [Text]
latexCodeBlock ParsecT Sources ParserState m [Text]
-> ParsecT Sources ParserState m [Text]
-> ParsecT Sources ParserState m [Text]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m [Text]
forall (m :: * -> *) st. Monad m => ParsecT Sources st m [Text]
birdCodeBlock
  blanklines
  return $ B.codeBlockWith ("", ["haskell","literate"], [])
         $ T.intercalate "\n" lns

latexCodeBlock :: Monad m => ParsecT Sources st m [Text]
latexCodeBlock :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m [Text]
latexCodeBlock = ParsecT Sources st m [Text] -> ParsecT Sources st m [Text]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m [Text] -> ParsecT Sources st m [Text])
-> ParsecT Sources st m [Text] -> ParsecT Sources st m [Text]
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources st m Char -> ParsecT Sources st m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT Sources st m Char
forall {s} {m :: * -> *} {u}.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
latexBlockLine [Char]
"\\begin{code}")
  ParsecT Sources st m Text
-> ParsecT Sources st m Char -> ParsecT Sources st m [Text]
forall end s (m :: * -> *) t st a.
(Show end, Stream s m t) =>
ParsecT s st m a -> ParsecT s st m end -> ParsecT s st m [a]
many1Till ParsecT Sources st m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine (ParsecT Sources st m Char -> ParsecT Sources st m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m Char -> ParsecT Sources st m Char)
-> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall a b. (a -> b) -> a -> b
$ [Char] -> ParsecT Sources st m Char
forall {s} {m :: * -> *} {u}.
(Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
latexBlockLine [Char]
"\\end{code}")
 where
  latexBlockLine :: [Char] -> ParsecT s u m Char
latexBlockLine [Char]
s = ParsecT s u m Char -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT s u m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar ParsecT s u m () -> ParsecT s u m [Char] -> ParsecT s u m [Char]
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Char] -> ParsecT s u m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
s ParsecT s u m [Char] -> ParsecT s u m Char -> ParsecT s u m Char
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT s u m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline

birdCodeBlock :: Monad m => ParsecT Sources st m [Text]
birdCodeBlock :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m [Text]
birdCodeBlock = [Text] -> [Text]
filterSpace ([Text] -> [Text])
-> ParsecT Sources st m [Text] -> ParsecT Sources st m [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources st m Text -> ParsecT Sources st m [Text]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources st m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
birdTrackLine
  where filterSpace :: [Text] -> [Text]
filterSpace [Text]
lns =
            -- if (as is normal) there is always a space after >, drop it
            if (Text -> Bool) -> [Text] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Text
ln -> Text -> Bool
T.null Text
ln Bool -> Bool -> Bool
|| Int -> Text -> Text
T.take Int
1 Text
ln Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
" ") [Text]
lns
               then (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Text -> Text
T.drop Int
1) [Text]
lns
               else [Text]
lns

birdTrackLine :: Monad m => ParsecT Sources st m Text
birdTrackLine :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
birdTrackLine = Char -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'>' ParsecT Sources st m Char
-> ParsecT Sources st m Text -> ParsecT Sources st m Text
forall a b.
ParsecT Sources st m a
-> ParsecT Sources st m b -> ParsecT Sources st m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources st m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine

--
-- block quotes
--

blockQuote :: PandocMonad m => RSTParser m Blocks
blockQuote :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
blockQuote = do
  raw <- ParsecT Sources ParserState m Text
forall st (m :: * -> *).
(HasReaderOptions st, Monad m) =>
ParsecT Sources st m Text
indentedBlock
  -- parse the extracted block, which may contain various block elements:
  contents <- parseFromString' parseBlocks $ raw <> "\n\n"
  return $ B.blockQuote contents

{-
Unsupported options for include:
tab-width
encoding
-}

includeDirective :: PandocMonad m
                 => Text
                 -> [(Text, Text)]
                 -> Text
                 -> RSTParser m Blocks
includeDirective :: forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
includeDirective Text
top [(Text, Text)]
fields Text
body = do
  let f :: [Char]
f = Text -> [Char]
T.unpack (Text -> [Char]) -> Text -> [Char]
forall a b. (a -> b) -> a -> b
$ Text -> Text
trim Text
top
  Bool -> ParsecT Sources ParserState m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT Sources ParserState m ())
-> Bool -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Char] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Char]
f
  Bool -> ParsecT Sources ParserState m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> ParsecT Sources ParserState m ())
-> Bool -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ Text -> Bool
T.null (Text -> Text
trim Text
body)
  let startLine :: Maybe Int
startLine = Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"start-line" [(Text, Text)]
fields Maybe Text -> (Text -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead
  let endLine :: Maybe Int
endLine = Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"end-line" [(Text, Text)]
fields Maybe Text -> (Text -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead
  let classes :: [Text]
classes =  [Text] -> (Text -> [Text]) -> Maybe Text -> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Text -> [Text]
T.words (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"class" [(Text, Text)]
fields)
  let ident :: Text
ident = Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" Text -> Text
trimr (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"name" [(Text, Text)]
fields
  let parser :: ParsecT Sources ParserState m (Many Block)
parser =
       case Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"code" [(Text, Text)]
fields Maybe Text -> Maybe Text -> Maybe Text
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"literal" [(Text, Text)]
fields of
         Just Text
lang ->
           (Text
-> [Text] -> [(Text, Text)] -> Text -> Bool -> Text -> Many Block
codeblock Text
ident [Text]
classes [(Text, Text)]
fields (Text -> Text
trimr Text
lang) Bool
False
            (Text -> Many Block) -> (Sources -> Text) -> Sources -> Many Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sources -> Text
sourcesToText) (Sources -> Many Block)
-> ParsecT Sources ParserState m Sources
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m Sources
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
         Maybe Text
Nothing   -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks
  let isLiteral :: Bool
isLiteral = Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"code" [(Text, Text)]
fields Maybe Text -> Maybe Text -> Maybe Text
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"literal" [(Text, Text)]
fields)
  let selectLines :: [Text] -> [Text]
selectLines =
        (case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"end-before" [(Text, Text)]
fields of
                         Just Text
patt -> (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
patt Text -> Text -> Bool
`T.isInfixOf`))
                         Maybe Text
Nothing   -> [Text] -> [Text]
forall a. a -> a
id) ([Text] -> [Text]) -> ([Text] -> [Text]) -> [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
        (case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"start-after" [(Text, Text)]
fields of
                         Just Text
patt -> Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
drop Int
1 ([Text] -> [Text]) -> ([Text] -> [Text]) -> [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                                        (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Text -> Bool) -> Text -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
patt Text -> Text -> Bool
`T.isInfixOf`))
                         Maybe Text
Nothing   -> [Text] -> [Text]
forall a. a -> a
id)

  let toStream :: Text -> Sources
toStream Text
t =
        [(SourcePos, Text)] -> Sources
Sources [([Char] -> SourcePos
initialPos [Char]
f,
                   ([Text] -> Text
T.unlines ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> [Text]
selectLines ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
T.lines (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text
t) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>
                    if Bool
isLiteral then Text
forall a. Monoid a => a
mempty else Text
"\n")]  -- see #7436
  currentDir <- [Char] -> [Char]
takeDirectory ([Char] -> [Char]) -> (SourcePos -> [Char]) -> SourcePos -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourcePos -> [Char]
sourceName (SourcePos -> [Char])
-> ParsecT Sources ParserState m SourcePos
-> ParsecT Sources ParserState m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  insertIncludedFile parser toStream [currentDir] f startLine endLine

--
-- list blocks
--

list :: PandocMonad m => RSTParser m Blocks
list :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
list = [ParsecT Sources ParserState m (Many Block)]
-> ParsecT Sources ParserState m (Many Block)
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
bulletList, ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
orderedList, ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
definitionList ] ParsecT Sources ParserState m (Many Block)
-> [Char] -> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"list"

definitionListItem :: PandocMonad m => RSTParser m (Inlines, [Blocks])
definitionListItem :: forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, [Many Block])
definitionListItem = ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline, [Many Block])
 -> ParsecT Sources ParserState m (Many Inline, [Many Block]))
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m (Many Inline, [Many Block])
forall a b. (a -> b) -> a -> b
$ do
  -- avoid capturing a directive or comment
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Char
 -> ParsecT Sources ParserState m Char)
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'.' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'.')
  term <- Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall end s (m :: * -> *) t st a.
(Show end, Stream s m t) =>
ParsecT s st m a -> ParsecT s st m end -> ParsecT s st m [a]
many1Till ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
endline
  raw <- indentedBlock
  -- parse the extracted block, which may contain various block elements:
  contents <- parseFromString' parseBlocks $ raw <> "\n"
  return (term, [contents])

definitionList :: PandocMonad m => RSTParser m Blocks
definitionList :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
definitionList = [(Many Inline, [Many Block])] -> Many Block
B.definitionList ([(Many Inline, [Many Block])] -> Many Block)
-> ParsecT Sources ParserState m [(Many Inline, [Many Block])]
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline, [Many Block])
-> ParsecT Sources ParserState m [(Many Inline, [Many Block])]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources ParserState m (Many Inline, [Many Block])
forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, [Many Block])
definitionListItem

-- parses bullet list start and returns its length (inc. following whitespace)
bulletListStart :: Monad m => ParsecT Sources st m Int
bulletListStart :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m Int
bulletListStart = ParsecT Sources st m Int -> ParsecT Sources st m Int
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m Int -> ParsecT Sources st m Int)
-> ParsecT Sources st m Int -> ParsecT Sources st m Int
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources st m (Many Block) -> ParsecT Sources st m ()
forall b s (m :: * -> *) a st.
(Show b, Stream s m a) =>
ParsecT s st m b -> ParsecT s st m ()
notFollowedBy' ParsecT Sources st m (Many Block)
forall (m :: * -> *) st.
Monad m =>
ParsecT Sources st m (Many Block)
hrule  -- because hrules start out just like lists
  marker <- [Char] -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
bulletListMarkers
  white <- many1 spaceChar <|> "" <$ lookAhead (char '\n')
  return $ length (marker:white)

-- parses ordered list start and returns its length (inc following whitespace)
orderedListStart :: Monad m => ListNumberStyle
                 -> ListNumberDelim
                 -> RSTParser m Int
orderedListStart :: forall (m :: * -> *).
Monad m =>
ListNumberStyle -> ListNumberDelim -> RSTParser m Int
orderedListStart ListNumberStyle
style ListNumberDelim
delim = ParsecT Sources ParserState m Int
-> ParsecT Sources ParserState m Int
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Int
 -> ParsecT Sources ParserState m Int)
-> ParsecT Sources ParserState m Int
-> ParsecT Sources ParserState m Int
forall a b. (a -> b) -> a -> b
$ do
  (_, markerLen) <- ParsecT Sources ParserState m Int
-> ParsecT Sources ParserState m (Int, Int)
forall s (m :: * -> *) st a.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m a -> ParsecT s st m (a, Int)
withHorizDisplacement (ListNumberStyle
-> ListNumberDelim -> ParsecT Sources ParserState m Int
forall s (m :: * -> *).
(Stream s m Char, UpdateSourcePos s Char) =>
ListNumberStyle -> ListNumberDelim -> ParsecT s ParserState m Int
orderedListMarker ListNumberStyle
style ListNumberDelim
delim)
  white <- many1 spaceChar <|> "" <$ lookAhead (char '\n')
  return $ markerLen + length white

-- parse a line of a list item
listLine :: Monad m => Int -> RSTParser m Text
listLine :: forall (m :: * -> *). Monad m => Int -> RSTParser m Text
listLine Int
markerLength = ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Text
 -> ParsecT Sources ParserState m Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline
  Int -> ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char, HasReaderOptions st) =>
Int -> ParsecT s st m Text
indentWith Int
markerLength
  ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLineNewline

-- parse raw text for one list item, excluding start marker and continuations
rawListItem :: Monad m => RSTParser m Int
            -> RSTParser m (Int, Text)
rawListItem :: forall (m :: * -> *).
Monad m =>
RSTParser m Int -> RSTParser m (Int, Text)
rawListItem RSTParser m Int
start = ParsecT Sources ParserState m (Int, Text)
-> ParsecT Sources ParserState m (Int, Text)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Int, Text)
 -> ParsecT Sources ParserState m (Int, Text))
-> ParsecT Sources ParserState m (Int, Text)
-> ParsecT Sources ParserState m (Int, Text)
forall a b. (a -> b) -> a -> b
$ do
  markerLength <- RSTParser m Int
start
  firstLine <- anyLineNewline
  restLines <- many (listLine markerLength)
  return (markerLength, firstLine <> T.concat restLines)

-- continuation of a list item - indented and separated by blankline or
-- (in compact lists) endline.
-- Note: nested lists are parsed as continuations.
listContinuation :: Monad m => Int -> RSTParser m Text
listContinuation :: forall (m :: * -> *). Monad m => Int -> RSTParser m Text
listContinuation Int
markerLength = ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Text
 -> ParsecT Sources ParserState m Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b. (a -> b) -> a -> b
$ do
  blanks <- ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
many1Char ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline
  result <- many1 (listLine markerLength)
  return $ blanks <> T.concat result

listItem :: PandocMonad m
         => RSTParser m Int
         -> RSTParser m Blocks
listItem :: forall (m :: * -> *).
PandocMonad m =>
RSTParser m Int -> RSTParser m (Many Block)
listItem RSTParser m Int
start = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  (markerLength, first) <- RSTParser m Int -> RSTParser m (Int, Text)
forall (m :: * -> *).
Monad m =>
RSTParser m Int -> RSTParser m (Int, Text)
rawListItem RSTParser m Int
start
  rest <- many (listContinuation markerLength)
  skipMany1 blankline <|> () <$ lookAhead start
  -- parsing with ListItemState forces markers at beginning of lines to
  -- count as list item markers, even if not separated by blank space.
  -- see definition of "endline"
  state <- getState
  let oldContext = ParserState -> ParserContext
stateParserContext ParserState
state
  setState $ state {stateParserContext = ListItemState}
  -- parse the extracted block, which may itself contain block elements
  parsed <- parseFromString' parseBlocks $ T.concat (first:rest) <> "\n"
  updateState (\ParserState
st -> ParserState
st {stateParserContext = oldContext})
  return $ case B.toList parsed of
                [Para [Inline]
xs] ->
                   Block -> Many Block
forall a. a -> Many a
B.singleton (Block -> Many Block) -> Block -> Many Block
forall a b. (a -> b) -> a -> b
$ [Inline] -> Block
Plain [Inline]
xs
                [Para [Inline]
xs, BulletList [[Block]]
ys] ->
                   [Block] -> Many Block
forall a. [a] -> Many a
B.fromList [[Inline] -> Block
Plain [Inline]
xs, [[Block]] -> Block
BulletList [[Block]]
ys]
                [Para [Inline]
xs, OrderedList ListAttributes
s [[Block]]
ys] ->
                   [Block] -> Many Block
forall a. [a] -> Many a
B.fromList [[Inline] -> Block
Plain [Inline]
xs, ListAttributes -> [[Block]] -> Block
OrderedList ListAttributes
s [[Block]]
ys]
                [Para [Inline]
xs, DefinitionList [([Inline], [[Block]])]
ys] ->
                   [Block] -> Many Block
forall a. [a] -> Many a
B.fromList [[Inline] -> Block
Plain [Inline]
xs, [([Inline], [[Block]])] -> Block
DefinitionList [([Inline], [[Block]])]
ys]
                [Block]
_         -> Many Block
parsed

orderedList :: PandocMonad m => RSTParser m Blocks
orderedList :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
orderedList = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  (start, style, delim) <- ParsecT Sources ParserState m ListAttributes
-> ParsecT Sources ParserState m ListAttributes
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (ParsecT Sources ParserState m ListAttributes
forall s (m :: * -> *).
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s ParserState m ListAttributes
anyOrderedListMarker ParsecT Sources ParserState m ListAttributes
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ListAttributes
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar)
  items <- many1 (listItem (orderedListStart style delim))
  let items' = [Many Block] -> [Many Block]
compactify [Many Block]
items
  return $ B.orderedListWith (start, style, delim) items'

bulletList :: PandocMonad m => RSTParser m Blocks
bulletList :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
bulletList = [Many Block] -> Many Block
B.bulletList ([Many Block] -> Many Block)
-> ([Many Block] -> [Many Block]) -> [Many Block] -> Many Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Block] -> [Many Block]
compactify ([Many Block] -> Many Block)
-> ParsecT Sources ParserState m [Many Block]
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m [Many Block]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (RSTParser m Int -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
RSTParser m Int -> RSTParser m (Many Block)
listItem RSTParser m Int
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Int
bulletListStart)

--
-- directive (e.g. comment, container, compound-paragraph)
--

comment :: Monad m => RSTParser m Blocks
comment :: forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
comment = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
".."
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (() ()
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall a b.
a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
newline)
  -- notFollowedBy' directiveLabel -- comment comes after directive so unnec.
  _ <- ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine
  optional indentedBlock
  optional blanklines
  return mempty

directiveLabel :: Monad m => RSTParser m Text
directiveLabel :: forall (m :: * -> *). Monad m => RSTParser m Text
directiveLabel = Text -> Text
T.toLower
  (Text -> Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m Text
forall end s (m :: * -> *) t st.
(Show end, Stream s m t) =>
ParsecT s st m Char -> ParsecT s st m end -> ParsecT s st m Text
many1TillChar (ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
letter ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-') (ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m [Char]
 -> ParsecT Sources ParserState m [Char])
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"::")

directive :: PandocMonad m => RSTParser m Blocks
directive :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
directive = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
".."
  ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
directive'

directive' :: PandocMonad m => RSTParser m Blocks
directive' :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
directive' = do
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar
  label <- RSTParser m Text
forall (m :: * -> *). Monad m => RSTParser m Text
directiveLabel
  skipMany spaceChar
  top <- manyChar $ satisfy (/='\n')
             <|> try (char '\n' <*
                      notFollowedBy' (rawFieldListItem 1) <*
                      many1 (char ' ') <*
                      notFollowedBy blankline)
  newline
  fields <- do
    fieldIndent <- length <$> lookAhead (many (char ' '))
    if fieldIndent == 0
       then return []
       else many $ rawFieldListItem fieldIndent
  let mbfile = Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"file" [(Text, Text)]
fields
  body <- case mbfile of
            Just Text
f | Text
label Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"raw" -> do
               currentDir <- [Char] -> [Char]
takeDirectory ([Char] -> [Char]) -> (SourcePos -> [Char]) -> SourcePos -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourcePos -> [Char]
sourceName (SourcePos -> [Char])
-> ParsecT Sources ParserState m SourcePos
-> ParsecT Sources ParserState m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
               fromMaybe mempty <$> readFileFromDirs [currentDir] (T.unpack f)
            Maybe Text
_ -> Text -> RSTParser m Text -> RSTParser m Text
forall s (m :: * -> *) t a u.
Stream s m t =>
a -> ParsecT s u m a -> ParsecT s u m a
option Text
"" (RSTParser m Text -> RSTParser m Text)
-> RSTParser m Text -> RSTParser m Text
forall a b. (a -> b) -> a -> b
$ RSTParser m Text -> RSTParser m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (RSTParser m Text -> RSTParser m Text)
-> RSTParser m Text -> RSTParser m Text
forall a b. (a -> b) -> a -> b
$ RSTParser m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Text
blanklines RSTParser m Text -> RSTParser m Text -> RSTParser m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> RSTParser m Text
forall st (m :: * -> *).
(HasReaderOptions st, Monad m) =>
ParsecT Sources st m Text
indentedBlock
  optional blanklines
  let body' = Text
body Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n\n"
      name = Text -> Text
trim (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"" (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"name" [(Text, Text)]
fields)
      classes = Text -> [Text]
T.words (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" Text -> Text
trim (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"class" [(Text, Text)]
fields)
      keyvals = [(Text
k, Text -> Text
trim Text
v) | (Text
k, Text
v) <- [(Text, Text)]
fields, Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"name", Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"class"]
      imgAttr Text
cl = (Text
name, [Text]
classes, [Text]
alignClasses, [(a, Text)]
widthAttr [(a, Text)] -> [(a, Text)] -> [(a, Text)]
forall a. [a] -> [a] -> [a]
++ [(a, Text)]
heightAttr)
        where
          alignClasses :: [Text]
alignClasses = Text -> [Text]
T.words (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" Text -> Text
trim (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
cl [(Text, Text)]
fields) 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
"align-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
trim Text
x)
                          (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"align" [(Text, Text)]
fields)
          scale :: Double
scale = case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"scale" [(Text, Text)]
fields of
                    Just Text
v -> case Text -> Maybe (Text, Char)
T.unsnoc Text
v of
                      Just (Text
vv, Char
'%') -> case Text -> Maybe Double
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead Text
vv of
                                          Just (Double
percent :: Double)
                                            -> Double
percent Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
100.0
                                          Maybe Double
Nothing -> Double
1.0
                      Maybe (Text, Char)
_ -> case Text -> Maybe Double
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead Text
v of
                             Just (Double
s :: Double) -> Double
s
                             Maybe Double
Nothing            -> Double
1.0
                    Maybe Text
Nothing -> Double
1.0
          widthAttr :: [(a, Text)]
widthAttr = [(a, Text)]
-> (Dimension -> [(a, Text)]) -> Maybe Dimension -> [(a, Text)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Dimension
x -> [(a
"width",
                                        Dimension -> Text
forall a. Show a => a -> Text
tshow (Dimension -> Text) -> Dimension -> Text
forall a b. (a -> b) -> a -> b
$ Double -> Dimension -> Dimension
scaleDimension Double
scale Dimension
x)])
                        (Maybe Dimension -> [(a, Text)]) -> Maybe Dimension -> [(a, Text)]
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"width" [(Text, Text)]
fields Maybe Text -> (Text -> Maybe Dimension) -> Maybe Dimension
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                          (Text -> Maybe Dimension
lengthToDim (Text -> Maybe Dimension)
-> (Text -> Text) -> Text -> Maybe Dimension
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Text
T.filter (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace))
          heightAttr :: [(a, Text)]
heightAttr = [(a, Text)]
-> (Dimension -> [(a, Text)]) -> Maybe Dimension -> [(a, Text)]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (\Dimension
x -> [(a
"height",
                                         Dimension -> Text
forall a. Show a => a -> Text
tshow (Dimension -> Text) -> Dimension -> Text
forall a b. (a -> b) -> a -> b
$ Double -> Dimension -> Dimension
scaleDimension Double
scale Dimension
x)])
                        (Maybe Dimension -> [(a, Text)]) -> Maybe Dimension -> [(a, Text)]
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"height" [(Text, Text)]
fields Maybe Text -> (Text -> Maybe Dimension) -> Maybe Dimension
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                          (Text -> Maybe Dimension
lengthToDim (Text -> Maybe Dimension)
-> (Text -> Text) -> Text -> Maybe Dimension
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> Text
T.filter (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace))
  case label of
        Text
"include" -> Text
-> [(Text, Text)]
-> Text
-> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
includeDirective Text
top [(Text, Text)]
fields Text
body'
        Text
"table" -> Text
-> [(Text, Text)]
-> Text
-> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
tableDirective Text
top [(Text, Text)]
fields Text
body'
        Text
"list-table" -> Text
-> [(Text, Text)]
-> Text
-> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
listTableDirective Text
top [(Text, Text)]
fields Text
body'
        Text
"csv-table" -> Text
-> [(Text, Text)]
-> Text
-> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
csvTableDirective Text
top [(Text, Text)]
fields Text
body'
        Text
"line-block" -> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Block)
lineBlockDirective Text
body'
        Text
"raw" -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Many Block
B.rawBlock (Text -> Text
trim Text
top) (Text -> Text
stripTrailingNewlines Text
body)
        Text
"role" -> Text
-> [(Text, Text)] -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> RSTParser m (Many Block)
addNewRole Text
top ([(Text, Text)] -> ParsecT Sources ParserState m (Many Block))
-> [(Text, Text)] -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ ((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text, Text) -> (Text, Text)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Text -> Text
trim) [(Text, Text)]
fields
        Text
"container" -> Attr -> Many Block -> Many Block
B.divWith
                         (Text
name, Text
"container" Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: Text -> [Text]
T.words Text
top [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
classes, []) (Many Block -> Many Block)
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                          ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body'
        Text
"replace" -> Many Inline -> Many Block
B.para (Many Inline -> Many Block)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>  -- consumed by substKey
                   Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText (Text -> Text
trim Text
top)
        Text
"date" -> Many Inline -> Many Block
B.para (Many Inline -> Many Block)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do  -- consumed by substKey
                     t <- ParsecT Sources ParserState m UTCTime
forall (m :: * -> *). PandocMonad m => m UTCTime
getTimestamp
                     let format = case Text -> [Char]
T.unpack (Text -> Text
T.strip Text
top) of
                                    [] -> [Char]
"%Y-%m-%d"
                                    [Char]
x  -> [Char]
x
                     return $ B.text $
                              T.pack $ formatTime defaultTimeLocale format t
        Text
"unicode" -> Many Inline -> Many Block
B.para (Many Inline -> Many Block)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>  -- consumed by substKey
                   Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText (Text -> Text
trim (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
unicodeTransform Text
top)
        Text
"compound" -> ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body'
        Text
"pull-quote" -> Many Block -> Many Block
B.blockQuote (Many Block -> Many Block)
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body'
        Text
"epigraph" -> Many Block -> Many Block
B.blockQuote (Many Block -> Many Block)
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body'
        Text
"highlights" -> Many Block -> Many Block
B.blockQuote (Many Block -> Many Block)
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body'
        Text
"rubric" -> Many Inline -> Many Block
B.para (Many Inline -> Many Block)
-> (Many Inline -> Many Inline) -> Many Inline -> Many Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Many Inline -> Many Inline
B.strong (Many Inline -> Many Block)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText Text
top
        Text
_ | Text
label Text -> [Text] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"attention",Text
"caution",Text
"danger",Text
"error",Text
"hint",
                          Text
"important",Text
"note",Text
"tip",Text
"warning",Text
"admonition"] ->
           do bod <- ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks (Text -> ParsecT Sources ParserState m (Many Block))
-> Text -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Text
top Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
body'
              let lab = case Text
label of
                          Text
"admonition" -> Many Block
forall a. Monoid a => a
mempty
                          (Text -> Maybe (Char, Text)
T.uncons -> Just (Char
l, Text
ls))
                            -> Attr -> Many Block -> Many Block
B.divWith (Text
"",[Text
"title"],[])
                                          (Many Inline -> Many Block
B.para (Text -> Many Inline
B.str (Text -> Many Inline) -> Text -> Many Inline
forall a b. (a -> b) -> a -> b
$ Char -> Text -> Text
T.cons (Char -> Char
toUpper Char
l)  Text
ls))
                          Text
_ -> Many Block
forall a. Monoid a => a
mempty
              return $ B.divWith (name,label:classes,keyvals) (lab <> bod)
        Text
"sidebar" ->
           do let subtit :: Text
subtit = Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" Text -> Text
trim (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"subtitle" [(Text, Text)]
fields
              tit <- Many Inline -> Many Block
B.para (Many Inline -> Many Block)
-> (Many Inline -> Many Inline) -> Many Inline -> Many Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Many Inline -> Many Inline
B.strong (Many Inline -> Many Block)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText
                          (Text -> Text
trim Text
top Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> if Text -> Bool
T.null Text
subtit
                                          then Text
""
                                          else Text
":  " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
subtit)
              bod <- parseFromString' parseBlocks body'
              return $ B.divWith (name,"sidebar":classes,keyvals) $ tit <> bod
        Text
"topic" ->
           do tit <- Many Inline -> Many Block
B.para (Many Inline -> Many Block)
-> (Many Inline -> Many Inline) -> Many Inline -> Many Block
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Many Inline -> Many Inline
B.strong (Many Inline -> Many Block)
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText Text
top
              bod <- parseFromString' parseBlocks body'
              return $ B.divWith (name,"topic":classes,keyvals) $ tit <> bod
        Text
"default-role" -> Many Block
forall a. Monoid a => a
mempty Many Block
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m (Many Block)
forall a b.
a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState (\ParserState
s ->
                              ParserState
s { stateRstDefaultRole =
                                  case trim top of
                                     Text
""   -> ParserState -> Text
stateRstDefaultRole ParserState
forall a. Default a => a
def
                                     Text
role -> Text
role })
        Text
"highlight" -> Many Block
forall a. Monoid a => a
mempty Many Block
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m (Many Block)
forall a b.
a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState (\ParserState
s ->
                              ParserState
s { stateRstHighlight =
                                  case trim top of
                                     Text
""   -> ParserState -> Maybe Text
stateRstHighlight ParserState
forall a. Default a => a
def
                                     Text
lang -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
lang })
        Text
x | Text
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"code" Bool -> Bool -> Bool
|| Text
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"code-block" Bool -> Bool -> Bool
|| Text
x Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"sourcecode" ->
          Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Text
-> [Text] -> [(Text, Text)] -> Text -> Bool -> Text -> Many Block
codeblock Text
name [Text]
classes (((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text, Text) -> (Text, Text)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Text -> Text
trimr) [(Text, Text)]
fields)
             (Text -> Text
trim Text
top) Bool
True Text
body
        Text
"aafig" -> do
          let attribs :: Attr
attribs = (Text
name, [Text
"aafig"], ((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text, Text) -> (Text, Text)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Text -> Text
trimr) [(Text, Text)]
fields)
          Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Attr -> Text -> Many Block
B.codeBlockWith Attr
attribs (Text -> Many Block) -> Text -> Many Block
forall a b. (a -> b) -> a -> b
$ Text -> Text
stripTrailingNewlines Text
body
        Text
"math" -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Block
B.para
                  (Many Inline -> Many Block) -> Many Inline -> Many Block
forall a b. (a -> b) -> a -> b
$ (case Text -> [Text] -> [(Text, Text)] -> Attr
mkAttr Text
name [Text]
classes [(Text, Text)]
fields of
                       Attr
attr | Attr
attr Attr -> Attr -> Bool
forall a. Eq a => a -> a -> Bool
== Attr
nullAttr -> Many Inline -> Many Inline
forall a. a -> a
id
                            | Bool
otherwise        -> Attr -> Many Inline -> Many Inline
B.spanWith Attr
attr)
                  (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall a b. (a -> b) -> a -> b
$ (Text -> Many Inline) -> [Text] -> [Many Inline]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Many Inline
B.displayMath
                  ([Text] -> [Many Inline]) -> [Text] -> [Many Inline]
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
toChunks (Text -> [Text]) -> Text -> [Text]
forall a b. (a -> b) -> a -> b
$ Text
top Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
body
        Text
"figure" -> do
           (caption, legend) <- ParsecT Sources ParserState m (Many Inline, Many Block)
-> Text -> ParsecT Sources ParserState m (Many Inline, Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Inline, Many Block)
forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, Many Block)
extractCaption Text
body'
           let src = Text -> Text
escapeURI (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
trim Text
top
           let (imgident, imgcls, aligncls, imgkvs) = imgAttr "class"
           let (figclasskv, _) = partition ((== "figclass") . fst) keyvals
           let figcls = ((Text, Text) -> [Text]) -> [(Text, Text)] -> [Text]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Text -> [Text]
T.words (Text -> [Text])
-> ((Text, Text) -> Text) -> (Text, Text) -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, Text) -> Text
forall a b. (a, b) -> b
snd) [(Text, Text)]
figclasskv
           let figattr = (Text
"", [Text]
figcls [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
aligncls, [])
           let capt = Maybe [Inline] -> Many Block -> Caption
B.caption Maybe [Inline]
forall a. Maybe a
Nothing (Many Inline -> Many Block
B.plain Many Inline
caption Many Block -> Many Block -> Many Block
forall a. Semigroup a => a -> a -> a
<> Many Block
legend)
           return $ B.figureWith figattr capt $
             B.plain (B.imageWith (imgident, imgcls, imgkvs) src "" (B.text src))
        Text
"image" -> do
           let src :: Text
src = Text -> Text
escapeURI (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
trim Text
top
           let alt :: Many Inline
alt = Text -> Many Inline
B.str (Text -> Many Inline) -> Text -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"image" Text -> Text
trim (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"alt" [(Text, Text)]
fields
           let attr :: Attr
attr = (Text
ident, [Text]
cls [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
align, [(Text, Text)]
dims) where
                 (Text
ident, [Text]
cls, [Text]
align, [(Text, Text)]
dims) = Text -> (Text, [Text], [Text], [(Text, Text)])
forall {a}.
IsString a =>
Text -> (Text, [Text], [Text], [(a, Text)])
imgAttr Text
"class"
           Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Block
B.para
                  (Many Inline -> Many Block) -> Many Inline -> Many Block
forall a b. (a -> b) -> a -> b
$ case Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"target" [(Text, Text)]
fields of
                          Just Text
t  -> Text -> Text -> Many Inline -> Many Inline
B.link (Text -> Text
escapeURI (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
trim Text
t) Text
""
                                     (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Attr -> Text -> Text -> Many Inline -> Many Inline
B.imageWith Attr
attr Text
src Text
"" Many Inline
alt
                          Maybe Text
Nothing -> Attr -> Text -> Text -> Many Inline -> Many Inline
B.imageWith Attr
attr Text
src Text
"" Many Inline
alt
        Text
"bibliography" -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Attr -> Many Block -> Many Block
B.divWith (Text
"refs",[],[]) Many Block
forall a. Monoid a => a
mempty
        Text
"class" -> do
            let attrs :: Attr
attrs = (Text
name, Text -> [Text]
T.words (Text -> Text
trim Text
top), ((Text, Text) -> (Text, Text)) -> [(Text, Text)] -> [(Text, Text)]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Text) -> (Text, Text) -> (Text, Text)
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Text -> Text
trimr) [(Text, Text)]
fields)
            --  directive content or the first immediately following element
            children <- case Text
body of
                Text
"" -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
block
                Text
_  -> ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks  Text
body'
            return $
              case B.toList children of
                [Header Int
lev Attr
attrs' [Inline]
ils]
                  | Text -> Bool
T.null Text
body -> -- # see #6699
                     Attr -> Int -> Many Inline -> Many Block
B.headerWith (Attr
attrs' Attr -> Attr -> Attr
forall a. Semigroup a => a -> a -> a
<> Attr
attrs) Int
lev ([Inline] -> Many Inline
forall a. [a] -> Many a
B.fromList [Inline]
ils)
                [Block]
_ -> Attr -> Many Block -> Many Block
B.divWith Attr
attrs Many Block
children
        Text
other     -> do
            pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
            logMessage $ SkippedContent (".. " <> other) pos
            bod <- parseFromString' parseBlocks $ top <> "\n\n" <> body'
            return $ B.divWith (name, other:classes, keyvals) bod

tableDirective :: PandocMonad m
               => Text -> [(Text, Text)] -> Text -> RSTParser m Blocks
tableDirective :: forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
tableDirective Text
top [(Text, Text)]
fields Text
body = do
  bs <- ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body
  case B.toList bs of
       [Table Attr
attr Caption
_ [ColSpec]
tspecs' thead :: TableHead
thead@(TableHead Attr
_ [Row]
thrs) [TableBody]
tbody TableFoot
tfoot] -> do
         let ([Alignment]
aligns', [ColWidth]
widths') = [ColSpec] -> ([Alignment], [ColWidth])
forall a b. [(a, b)] -> ([a], [b])
unzip [ColSpec]
tspecs'
         title <- ParsecT Sources ParserState m (Many Inline)
-> Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' (Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline) Text
top
         columns <- getOption readerColumns
         let numOfCols = case [Row]
thrs of
               [] -> Int
0
               (Row
r:[Row]
_) -> Row -> Int
rowLength Row
r
         let normWidths f Double
ws =
                Double -> ColWidth
strictPos (Double -> ColWidth) -> (Double -> Double) -> Double -> ColWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1.0 (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
columns Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
numOfCols))) (Double -> ColWidth) -> f Double -> f ColWidth
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f Double
ws
         let widths = case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"widths" [(Text, Text)]
fields of
                           Just Text
"auto" -> Int -> ColWidth -> [ColWidth]
forall a. Int -> a -> [a]
replicate Int
numOfCols ColWidth
ColWidthDefault
                           Just Text
"grid" -> [ColWidth]
widths'
                           Just Text
specs -> [Double] -> [ColWidth]
forall {f :: * -> *}. Functor f => f Double -> f ColWidth
normWidths
                               ([Double] -> [ColWidth]) -> [Double] -> [ColWidth]
forall a b. (a -> b) -> a -> b
$ (Text -> Double) -> [Text] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe (Double
0 :: Double) (Maybe Double -> Double)
-> (Text -> Maybe Double) -> Text -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Double
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead)
                               ([Text] -> [Double]) -> [Text] -> [Double]
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Text -> [Text]
splitTextBy (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
" ," :: String)) Text
specs
                           Maybe Text
Nothing -> [ColWidth]
widths'
         -- align is not applicable since we can't represent whole table align
         let tspecs = [Alignment] -> [ColWidth] -> [ColSpec]
forall a b. [a] -> [b] -> [(a, b)]
zip [Alignment]
aligns' [ColWidth]
widths
         return $ B.singleton $ Table attr (B.caption Nothing (B.plain title))
                                  tspecs thead tbody tfoot
       [Block]
_ -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Many Block
forall a. Monoid a => a
mempty
  where
    -- only valid on the very first row of a table section
    rowLength :: Row -> Int
rowLength (Row Attr
_ [Cell]
rb) = [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ Cell -> Int
cellLength (Cell -> Int) -> [Cell] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Cell]
rb
    cellLength :: Cell -> Int
cellLength (Cell Attr
_ Alignment
_ RowSpan
_ (ColSpan Int
w) [Block]
_) = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
w
    strictPos :: Double -> ColWidth
strictPos Double
w
      | Double
w Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0     = Double -> ColWidth
ColWidth Double
w
      | Bool
otherwise = ColWidth
ColWidthDefault

-- TODO: :stub-columns:.
-- Only the first row becomes the header even if header-rows: > 1,
-- since Pandoc doesn't support a table with multiple header rows.
-- We don't need to parse :align: as it represents the whole table align.
listTableDirective :: PandocMonad m
                   => Text -> [(Text, Text)] -> Text
                   -> RSTParser m Blocks
listTableDirective :: forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
listTableDirective Text
top [(Text, Text)]
fields Text
body = do
  bs <- ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks Text
body
  title <- parseFromString' (trimInlines . mconcat <$> many inline) top
  let rows = [Block] -> [[Many Block]]
takeRows ([Block] -> [[Many Block]]) -> [Block] -> [[Many Block]]
forall a b. (a -> b) -> a -> b
$ Many Block -> [Block]
forall a. Many a -> [a]
B.toList Many Block
bs
      headerRowsNum = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (Int
0 :: Int) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$
         Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"header-rows" [(Text, Text)]
fields Maybe Text -> (Text -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead
      (headerRow,bodyRows,numOfCols) = case rows of
        [Many Block]
x:[[Many Block]]
xs -> if Int
headerRowsNum Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                   then ([Many Block]
x, [[Many Block]]
xs, [Many Block] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Many Block]
x)
                   else ([], [[Many Block]]
rows, [Many Block] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Many Block]
x)
        [[Many Block]]
_ -> ([],[],Int
0)
      widths = case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"widths" [(Text, Text)]
fields of
        Just Text
"auto" -> Int -> ColWidth -> [ColWidth]
forall a. Int -> a -> [a]
replicate Int
numOfCols ColWidth
ColWidthDefault
        Just Text
specs -> [Double] -> [ColWidth]
forall {f :: * -> *}.
(Functor f, Foldable f) =>
f Double -> f ColWidth
normWidths ([Double] -> [ColWidth]) -> [Double] -> [ColWidth]
forall a b. (a -> b) -> a -> b
$ (Text -> Double) -> [Text] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe (Double
0 :: Double) (Maybe Double -> Double)
-> (Text -> Maybe Double) -> Text -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Double
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead) ([Text] -> [Double]) -> [Text] -> [Double]
forall a b. (a -> b) -> a -> b
$
                           (Char -> Bool) -> Text -> [Text]
splitTextBy (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
" ," :: String)) Text
specs
        Maybe Text
_ -> Int -> ColWidth -> [ColWidth]
forall a. Int -> a -> [a]
replicate Int
numOfCols ColWidth
ColWidthDefault
      toRow = Attr -> [Cell] -> Row
Row Attr
nullAttr ([Cell] -> Row) -> ([Many Block] -> [Cell]) -> [Many Block] -> Row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Many Block -> Cell) -> [Many Block] -> [Cell]
forall a b. (a -> b) -> [a] -> [b]
map Many Block -> Cell
B.simpleCell
      toHeaderRow [Many Block]
l = [[Many Block] -> Row
toRow [Many Block]
l | Bool -> Bool
not ([Many Block] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Many Block]
l)]
  return $ B.table (B.simpleCaption $ B.plain title)
             (zip (replicate numOfCols AlignDefault) widths)
             (TableHead nullAttr $ toHeaderRow headerRow)
             [TableBody nullAttr 0 [] $ map toRow bodyRows]
             (TableFoot nullAttr [])
    where takeRows :: [Block] -> [[Many Block]]
takeRows [BulletList [[Block]]
rows] = ([Block] -> [Many Block]) -> [[Block]] -> [[Many Block]]
forall a b. (a -> b) -> [a] -> [b]
map [Block] -> [Many Block]
takeCells [[Block]]
rows
          takeRows [Block]
_                 = []
          takeCells :: [Block] -> [Many Block]
takeCells [BulletList [[Block]]
cells] = ([Block] -> Many Block) -> [[Block]] -> [Many Block]
forall a b. (a -> b) -> [a] -> [b]
map [Block] -> Many Block
forall a. [a] -> Many a
B.fromList [[Block]]
cells
          takeCells [Block]
_                  = []
          normWidths :: f Double -> f ColWidth
normWidths f Double
ws = Double -> ColWidth
strictPos (Double -> ColWidth) -> (Double -> Double) -> Double -> ColWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1 (f Double -> Double
forall a. Num a => f a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum f Double
ws)) (Double -> ColWidth) -> f Double -> f ColWidth
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f Double
ws
          strictPos :: Double -> ColWidth
strictPos Double
w
            | Double
w Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0     = Double -> ColWidth
ColWidth Double
w
            | Bool
otherwise = ColWidth
ColWidthDefault

csvTableDirective :: PandocMonad m
                   => Text -> [(Text, Text)] -> Text
                   -> RSTParser m Blocks
csvTableDirective :: forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> Text -> RSTParser m (Many Block)
csvTableDirective Text
top [(Text, Text)]
fields Text
rawcsv = do
  let explicitHeader :: Maybe Text
explicitHeader = Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"header" [(Text, Text)]
fields
  let opts :: CSVOptions
opts = CSVOptions
defaultCSVOptions{
                csvDelim = case trim <$> lookup "delim" fields of
                                Just Text
"tab"   -> Char
'\t'
                                Just Text
"space" -> Char
' '
                                Just (Text -> [Char]
T.unpack -> [Char
c])
                                             -> Char
c
                                Maybe Text
_            -> Char
','
              , csvQuote = case trim <$> lookup "quote" fields of
                                Just (Text -> [Char]
T.unpack -> [Char
c])
                                  -> Char -> Maybe Char
forall a. a -> Maybe a
Just Char
c
                                Maybe Text
_ -> Char -> Maybe Char
forall a. a -> Maybe a
Just Char
'"'
              , csvEscape = case trim <$> lookup "escape" fields of
                                Just (Text -> [Char]
T.unpack -> [Char
c])
                                  -> Char -> Maybe Char
forall a. a -> Maybe a
Just Char
c
                                Maybe Text
_ -> Maybe Char
forall a. Maybe a
Nothing
              , csvKeepSpace = case trim <$> lookup "keepspace" fields of
                                       Just Text
"true" -> Bool
True
                                       Maybe Text
_           -> Bool
False
              }
  let headerRowsNum :: Int
headerRowsNum = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (case Maybe Text
explicitHeader of
                                       Just Text
_  -> Int
1 :: Int
                                       Maybe Text
Nothing -> Int
0 :: Int) (Maybe Int -> Int) -> Maybe Int -> Int
forall a b. (a -> b) -> a -> b
$
           Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"header-rows" [(Text, Text)]
fields Maybe Text -> (Text -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text -> Maybe Int
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead
  rawcsv' <- case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
                    Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"file" [(Text, Text)]
fields Maybe Text -> Maybe Text -> Maybe Text
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"url" [(Text, Text)]
fields of
                  Just Text
u  -> do
                    (bs, _) <- Text -> ParsecT Sources ParserState m (ByteString, Maybe Text)
forall (m :: * -> *).
PandocMonad m =>
Text -> m (ByteString, Maybe Text)
fetchItem Text
u
                    return $ UTF8.toText bs
                  Maybe Text
Nothing -> Text -> ParsecT Sources ParserState m Text
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
rawcsv
  let header' = case Maybe Text
explicitHeader of
                  Just Text
h  -> CSVOptions -> Text -> Either ParseError [[Text]]
parseCSV CSVOptions
defaultCSVOptions Text
h
                  Maybe Text
Nothing -> [[Text]] -> Either ParseError [[Text]]
forall a b. b -> Either a b
Right []
  let res = CSVOptions -> Text -> Either ParseError [[Text]]
parseCSV CSVOptions
opts Text
rawcsv'
  case (<>) <$> header' <*> res of
       Left ParseError
e  ->
         PandocError -> ParsecT Sources ParserState m (Many Block)
forall a. PandocError -> ParsecT Sources ParserState m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> ParsecT Sources ParserState m (Many Block))
-> PandocError -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Sources -> ParseError -> PandocError
fromParsecError (Text -> Sources
forall a. ToSources a => a -> Sources
toSources Text
rawcsv') ParseError
e
       Right [[Text]]
rawrows -> do
         let parseRow :: [Text] -> ParsecT Sources ParserState m [Many Block]
parseRow = (Text -> ParsecT Sources ParserState m (Many Block))
-> [Text] -> ParsecT Sources ParserState m [Many Block]
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 -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Block)
parseCell
         rows <- ([Text] -> ParsecT Sources ParserState m [Many Block])
-> [[Text]] -> ParsecT Sources ParserState m [[Many Block]]
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] -> ParsecT Sources ParserState m [Many Block]
parseRow [[Text]]
rawrows
         let (headerRow,bodyRows,numOfCols) =
              case rows of
                   [Many Block]
x:[[Many Block]]
xs -> if Int
headerRowsNum Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                          then ([Many Block]
x, [[Many Block]]
xs, [Many Block] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Many Block]
x)
                          else ([], [[Many Block]]
rows, [Many Block] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Many Block]
x)
                   [[Many Block]]
_ -> ([],[],Int
0)
         title <- parseFromString' (trimInlines . mconcat <$> many inline) top
         let strictPos Double
w
               | Double
w Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
0     = Double -> ColWidth
ColWidth Double
w
               | Bool
otherwise = ColWidth
ColWidthDefault
         let normWidths f Double
ws = Double -> ColWidth
strictPos (Double -> ColWidth) -> (Double -> Double) -> Double -> ColWidth
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
1 (f Double -> Double
forall a. Num a => f a -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum f Double
ws)) (Double -> ColWidth) -> f Double -> f ColWidth
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f Double
ws
         let widths =
               case Text -> Text
trim (Text -> Text) -> Maybe Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"widths" [(Text, Text)]
fields of
                 Just Text
"auto" -> Int -> ColWidth -> [ColWidth]
forall a. Int -> a -> [a]
replicate Int
numOfCols ColWidth
ColWidthDefault
                 Just Text
specs -> [Double] -> [ColWidth]
forall {f :: * -> *}.
(Functor f, Foldable f) =>
f Double -> f ColWidth
normWidths
                               ([Double] -> [ColWidth]) -> [Double] -> [ColWidth]
forall a b. (a -> b) -> a -> b
$ (Text -> Double) -> [Text] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe (Double
0 :: Double) (Maybe Double -> Double)
-> (Text -> Maybe Double) -> Text -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Maybe Double
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead)
                               ([Text] -> [Double]) -> [Text] -> [Double]
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Text -> [Text]
splitTextBy (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
" ," :: String)) Text
specs
                 Maybe Text
_ -> Int -> ColWidth -> [ColWidth]
forall a. Int -> a -> [a]
replicate Int
numOfCols ColWidth
ColWidthDefault
         let toRow = Attr -> [Cell] -> Row
Row Attr
nullAttr ([Cell] -> Row) -> ([Many Block] -> [Cell]) -> [Many Block] -> Row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Many Block -> Cell) -> [Many Block] -> [Cell]
forall a b. (a -> b) -> [a] -> [b]
map Many Block -> Cell
B.simpleCell
             toHeaderRow [Many Block]
l = [[Many Block] -> Row
toRow [Many Block]
l | Bool -> Bool
not ([Many Block] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Many Block]
l)]
         return $ B.table (B.simpleCaption $ B.plain title)
                          (zip (replicate numOfCols AlignDefault) widths)
                          (TableHead nullAttr $ toHeaderRow headerRow)
                          [TableBody nullAttr 0 [] $ map toRow bodyRows]
                          (TableFoot nullAttr [])

singleParaToPlain :: Blocks -> Blocks
singleParaToPlain :: Many Block -> Many Block
singleParaToPlain Many Block
bs =
  case Many Block -> [Block]
forall a. Many a -> [a]
B.toList Many Block
bs of
    [Para [Inline]
ils] -> [Block] -> Many Block
forall a. [a] -> Many a
B.fromList [[Inline] -> Block
Plain [Inline]
ils]
    [Block]
_          -> Many Block
bs

parseCell :: PandocMonad m => Text -> RSTParser m Blocks
parseCell :: forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Block)
parseCell Text
t = Many Block -> Many Block
singleParaToPlain
   (Many Block -> Many Block)
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
-> Text -> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks (Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n\n")


-- TODO:
--  - Only supports :format: fields with a single format for :raw: roles,
--    change Text.Pandoc.Definition.Format to fix
addNewRole :: PandocMonad m
           => Text -> [(Text, Text)] -> RSTParser m Blocks
addNewRole :: forall (m :: * -> *).
PandocMonad m =>
Text -> [(Text, Text)] -> RSTParser m (Many Block)
addNewRole Text
roleText [(Text, Text)]
fields = do
    pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
    (role, parentRole) <- parseFromString' inheritedRole roleText
    customRoles <- stateRstCustomRoles <$> getState
    let getBaseRole (a
r, b
f, c
a) Map a (a, b, c)
roles =
            case a -> Map a (a, b, c) -> Maybe (a, b, c)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup a
r Map a (a, b, c)
roles of
                 Just (a
r', b
f', c
a') -> (a, b, c) -> Map a (a, b, c) -> (a, b, c)
getBaseRole (a
r', b
f', c
a') Map a (a, b, c)
roles
                 Maybe (a, b, c)
Nothing           -> (a
r, b
f, c
a)
        (baseRole, baseFmt, baseAttr) =
               getBaseRole (parentRole, Nothing, nullAttr) customRoles
        fmt = if Text
parentRole Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"raw" then Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"format" [(Text, Text)]
fields else Maybe Text
baseFmt

        updateClasses :: [Text] -> [Text]
        updateClasses [Text]
oldClasses = let

          codeLanguageClass :: [Text]
codeLanguageClass = if Text
baseRole Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"code"
            then Maybe Text -> [Text]
forall a. Maybe a -> [a]
maybeToList (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"language" [(Text, Text)]
fields)
            else []

          -- if no ":class:" field is given, the default is the role name
          classFieldClasses :: [Text]
classFieldClasses = [Text] -> (Text -> [Text]) -> Maybe Text -> [Text]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Text
role] Text -> [Text]
T.words (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"class" [(Text, Text)]
fields)

          -- nub in case role name & language class are the same
          in [Text] -> [Text]
forall a. Eq a => [a] -> [a]
nub ([Text]
classFieldClasses [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
codeLanguageClass [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
oldClasses)

        attr = let (Text
ident, [Text]
baseClasses, [(Text, Text)]
keyValues) = Attr
baseAttr
               in (Text
ident, [Text] -> [Text]
updateClasses [Text]
baseClasses, [(Text, Text)]
keyValues)

    -- warn about syntax we ignore
    forM_ fields $ \(Text
key, Text
_) -> case Text
key of
                 Text
"language" -> Bool
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Text
baseRole Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"code") (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ LogMessage -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasLogMessages st) =>
LogMessage -> ParsecT s st m ()
logMessage (LogMessage -> ParsecT Sources ParserState m ())
-> LogMessage -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$
                     Text -> SourcePos -> LogMessage
SkippedContent Text
":language: [because parent of role is not :code:]"
                        SourcePos
pos
                 Text
"format" -> Bool
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Text
baseRole Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"raw") (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ LogMessage -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasLogMessages st) =>
LogMessage -> ParsecT s st m ()
logMessage (LogMessage -> ParsecT Sources ParserState m ())
-> LogMessage -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$
                     Text -> SourcePos -> LogMessage
SkippedContent Text
":format: [because parent of role is not :raw:]" SourcePos
pos
                 Text
_ -> LogMessage -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasLogMessages st) =>
LogMessage -> ParsecT s st m ()
logMessage (LogMessage -> ParsecT Sources ParserState m ())
-> LogMessage -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
SkippedContent (Text
":" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
key Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
":") SourcePos
pos
    when (parentRole == "raw" && countKeys "format" > 1) $
        logMessage $ SkippedContent
                  ":format: [after first in definition of role]"
                  pos
    when (parentRole == "code" && countKeys "language" > 1) $
        logMessage $ SkippedContent
          ":language: [after first in definition of role]" pos

    updateState $ \ParserState
s -> ParserState
s {
        stateRstCustomRoles =
          M.insert role (baseRole, fmt, attr) customRoles
    }

    return mempty
  where
    countKeys :: Text -> Int
countKeys Text
k = [Text] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Text] -> Int)
-> ([(Text, Text)] -> [Text]) -> [(Text, Text)] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
filter (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
k) ([Text] -> [Text])
-> ([(Text, Text)] -> [Text]) -> [(Text, Text)] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Text, Text) -> Text) -> [(Text, Text)] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text, Text) -> Text
forall a b. (a, b) -> a
fst ([(Text, Text)] -> Int) -> [(Text, Text)] -> Int
forall a b. (a -> b) -> a -> b
$ [(Text, Text)]
fields
    inheritedRole :: ParsecT Sources ParserState m (Text, Text)
inheritedRole =
        (,) (Text -> Text -> (Text, Text))
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m (Text -> (Text, Text))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleName ParsecT Sources ParserState m (Text -> (Text, Text))
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m (Text, Text)
forall a b.
ParsecT Sources ParserState m (a -> b)
-> ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'(' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Sources ParserState m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleName ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
')')
                            ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Text -> ParsecT Sources ParserState m Text
forall a. a -> ParsecT Sources ParserState m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
"span")


-- Can contain character codes as decimal numbers or
-- hexadecimal numbers, prefixed by 0x, x, \x, U+, u, or \u
-- or as XML-style hexadecimal character entities, e.g. &#x1a2b;
-- or text, which is used as-is.  Comments start with ..
unicodeTransform :: Text -> Text
unicodeTransform :: Text -> Text
unicodeTransform Text
t
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
".." Text
t  = Text -> Text
unicodeTransform (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Text -> Text
T.dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\n') Text
xs -- comment
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"0x" Text
t  = Text -> Text -> Text
go Text
"0x" Text
xs
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"x" Text
t   = Text -> Text -> Text
go Text
"x" Text
xs
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"\\x" Text
t = Text -> Text -> Text
go Text
"\\x" Text
xs
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"U+" Text
t  = Text -> Text -> Text
go Text
"U+" Text
xs
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"u" Text
t   = Text -> Text -> Text
go Text
"u" Text
xs
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"\\u" Text
t = Text -> Text -> Text
go Text
"\\u" Text
xs
  | Just Text
xs <- Text -> Text -> Maybe Text
T.stripPrefix Text
"&#x" Text
t = Text -> ((Char, Text) -> Text) -> Maybe (Char, Text) -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text
"&#x" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
unicodeTransform Text
xs)
                                       -- drop semicolon
                                       (\(Char
c,Text
s) -> Char -> Text -> Text
T.cons Char
c (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
unicodeTransform (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Text -> Text
T.drop Int
1 Text
s)
                                       (Maybe (Char, Text) -> Text) -> Maybe (Char, Text) -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Maybe (Char, Text)
extractUnicodeChar Text
xs
  | Just (Char
x, Text
xs) <- Text -> Maybe (Char, Text)
T.uncons Text
t       = Char -> Text -> Text
T.cons Char
x (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
unicodeTransform Text
xs
  | Bool
otherwise                        = Text
""
  where go :: Text -> Text -> Text
go Text
pref Text
zs = Text -> ((Char, Text) -> Text) -> Maybe (Char, Text) -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Text
pref Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text
unicodeTransform Text
zs)
                     (\(Char
c,Text
s) -> Char -> Text -> Text
T.cons Char
c (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
unicodeTransform Text
s)
                     (Maybe (Char, Text) -> Text) -> Maybe (Char, Text) -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Maybe (Char, Text)
extractUnicodeChar Text
zs

extractUnicodeChar :: Text -> Maybe (Char, Text)
extractUnicodeChar :: Text -> Maybe (Char, Text)
extractUnicodeChar Text
s = (Char -> (Char, Text)) -> Maybe Char -> Maybe (Char, Text)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Char
c -> (Char
c,Text
rest)) Maybe Char
mbc
  where (Text
ds,Text
rest) = (Char -> Bool) -> Text -> (Text, Text)
T.span Char -> Bool
isHexDigit Text
s
        mbc :: Maybe Char
mbc = Text -> Maybe Char
forall (m :: * -> *) a. (MonadPlus m, Read a) => Text -> m a
safeRead (Text
"'\\x" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ds Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"'")

extractCaption :: PandocMonad m => RSTParser m (Inlines, Blocks)
extractCaption :: forall (m :: * -> *).
PandocMonad m =>
RSTParser m (Many Inline, Many Block)
extractCaption = do
  capt <- Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline
  legend <- optional blanklines >> (mconcat <$> many block)
  return (capt,legend)

-- divide string by blanklines, and surround with
-- \begin{aligned}...\end{aligned} if needed.
toChunks :: Text -> [Text]
toChunks :: Text -> [Text]
toChunks = (Text -> Bool) -> [Text] -> [Text]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile Text -> Bool
T.null
           ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Text] -> Text) -> [[Text]] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (Text -> Text
addAligned (Text -> Text) -> ([Text] -> Text) -> [Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
trim (Text -> Text) -> ([Text] -> Text) -> [Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> Text
T.unlines)
           ([[Text]] -> [Text]) -> (Text -> [[Text]]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Bool) -> [Text] -> [[Text]]
forall a. (a -> Bool) -> [a] -> [[a]]
splitBy ((Char -> Bool) -> Text -> Bool
T.all (Char -> [Char] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` ([Char]
" \t" :: String))) ([Text] -> [[Text]]) -> (Text -> [Text]) -> Text -> [[Text]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text]
T.lines
  -- we put this in an aligned environment if it contains \\, see #4254
  where addAligned :: Text -> Text
addAligned Text
s = if Text
"\\\\" Text -> Text -> Bool
`T.isInfixOf` Text
s
                          then Text
"\\begin{aligned}\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n\\end{aligned}"
                          else Text
s

codeblock :: Text -> [Text] -> [(Text, Text)] -> Text -> Bool -> Text
          -> Blocks
codeblock :: Text
-> [Text] -> [(Text, Text)] -> Text -> Bool -> Text -> Many Block
codeblock Text
ident [Text]
classes [(Text, Text)]
fields Text
lang Bool
rmTrailingNewlines Text
body =
  Attr -> Text -> Many Block
B.codeBlockWith Attr
attribs (Text -> Many Block) -> Text -> Many Block
forall a b. (a -> b) -> a -> b
$ Text -> Text
stripTrailingNewlines' Text
body
    where stripTrailingNewlines' :: Text -> Text
stripTrailingNewlines' = if Bool
rmTrailingNewlines
                                     then Text -> Text
stripTrailingNewlines
                                     else Text -> Text
forall a. a -> a
id
          attribs :: Attr
attribs = (Text
ident, [Text]
classes', [(Text, Text)]
kvs)
          classes' :: [Text]
classes' = Text
lang
                    Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: [Text
"numberLines" | Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"number-lines" [(Text, Text)]
fields)]
                    [Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ [Text]
classes
          kvs :: [(Text, Text)]
kvs = [(Text
k,Text
v) | (Text
k,Text
v) <- [(Text, Text)]
fields, Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"number-lines", Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"class",
                                          Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"id", Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"name"]
                [(Text, Text)] -> [(Text, Text)] -> [(Text, Text)]
forall a. [a] -> [a] -> [a]
++ case Text -> [(Text, Text)] -> Maybe Text
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Text
"number-lines" [(Text, Text)]
fields of
                     Just Text
v | Bool -> Bool
not (Text -> Bool
T.null Text
v) -> [(Text
"startFrom", Text
v)]
                     Maybe Text
_ -> []

-- | Creates element attributes from a name, list of classes, and fields.
-- Removes fields named @name@, @id@, or @class@.
mkAttr :: Text -> [Text] -> [(Text, Text)] -> Attr
mkAttr :: Text -> [Text] -> [(Text, Text)] -> Attr
mkAttr Text
ident [Text]
classes [(Text, Text)]
fields = (Text
ident, [Text]
classes, [(Text, Text)]
fields')
  where fields' :: [(Text, Text)]
fields' = [(Text
k, Text
v') | (Text
k, Text
v) <- [(Text, Text)]
fields
                           , let v' :: Text
v' = Text -> Text
trimr Text
v
                           , Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"name", Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"id", Text
k Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Text
"class"]

---
--- note block
---

noteBlock :: Monad m => RSTParser m Blocks
noteBlock :: forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
noteBlock = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  (ref, raw) <- RSTParser m Text -> RSTParser m (Text, Text)
forall (m :: * -> *).
Monad m =>
RSTParser m Text -> RSTParser m (Text, Text)
noteBlock' RSTParser m Text
forall (m :: * -> *). Monad m => RSTParser m Text
noteMarker
  updateState $ \ParserState
s -> ParserState
s { stateNotes = (ref, raw) : stateNotes s }
  return mempty

citationBlock :: Monad m => RSTParser m Blocks
citationBlock :: forall (m :: * -> *).
Monad m =>
ParsecT Sources ParserState m (Many Block)
citationBlock = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  (ref, raw) <- RSTParser m Text -> RSTParser m (Text, Text)
forall (m :: * -> *).
Monad m =>
RSTParser m Text -> RSTParser m (Text, Text)
noteBlock' RSTParser m Text
forall (m :: * -> *). Monad m => RSTParser m Text
citationMarker
  updateState $ \ParserState
s ->
     ParserState
s { stateCitations = M.insert ref raw (stateCitations s),
         stateKeys = M.insert (toKey ref) (("#" <> ref,""), ("",["citation"],[]))
                               (stateKeys s) }
  return mempty

noteBlock' :: Monad m
           => RSTParser m Text -> RSTParser m (Text, Text)
noteBlock' :: forall (m :: * -> *).
Monad m =>
RSTParser m Text -> RSTParser m (Text, Text)
noteBlock' RSTParser m Text
marker = ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Text, Text)
 -> ParsecT Sources ParserState m (Text, Text))
-> ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
".."
  ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar
  ref <- RSTParser m Text
marker
  first <- (spaceChar >> skipMany spaceChar >> anyLine)
        <|> (newline >> return "")
  blanks <- option "" blanklines
  rest <- option "" indentedBlock
  let raw = Text
first Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
blanks Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rest Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\n"
  return (ref, raw)

citationMarker :: Monad m => RSTParser m Text
citationMarker :: forall (m :: * -> *). Monad m => RSTParser m Text
citationMarker = do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'['
  res <- ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
simpleReferenceName
  char ']'
  return res

noteMarker :: Monad m => RSTParser m Text
noteMarker :: forall (m :: * -> *). Monad m => RSTParser m Text
noteMarker = do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'['
  res <- ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
many1Char ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
digit
      ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                  ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'#' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Text -> Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Text
"#" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
simpleReferenceName)
      ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Int
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char, Monad m) =>
Int -> ParsecT s st m Char -> ParsecT s st m Text
countChar Int
1 ([Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"#*")
  char ']'
  return res

--
-- reference key
--

quotedReferenceName :: PandocMonad m => RSTParser m Text
quotedReferenceName :: forall (m :: * -> *). PandocMonad m => RSTParser m Text
quotedReferenceName = ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Text
 -> ParsecT Sources ParserState m Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b. (a -> b) -> a -> b
$ do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`') -- `` means inline code!
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st a.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m a -> ParsecT s st m Text
manyTillChar ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
anyChar (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`')

-- Simple reference names are single words consisting of alphanumerics
-- plus isolated (no two adjacent) internal hyphens, underscores,
-- periods, colons and plus signs; no whitespace or other characters
-- are allowed.
simpleReferenceName :: Monad m => ParsecT Sources st m Text
simpleReferenceName :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
simpleReferenceName = do
  x <- ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum
  xs <- many $  alphaNum
            <|> try (oneOf "-_:+." <* lookAhead alphaNum)
  return $ T.pack (x:xs)

referenceName :: PandocMonad m => RSTParser m Text
referenceName :: forall (m :: * -> *). PandocMonad m => RSTParser m Text
referenceName = RSTParser m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
quotedReferenceName RSTParser m Text -> RSTParser m Text -> RSTParser m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
simpleReferenceName

referenceKey :: PandocMonad m => RSTParser m Blocks
referenceKey :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
referenceKey = do
  [ParsecT Sources ParserState m ()]
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
substKey, ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
anonymousKey, ParsecT Sources ParserState m ()
forall (m :: * -> *). PandocMonad m => RSTParser m ()
regularKey]
  ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Text
blanklines
  Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Many Block
forall a. Monoid a => a
mempty

targetURI :: Monad m => ParsecT Sources st m Text
targetURI :: forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
targetURI = do
  ParsecT Sources st m ()
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m ()
skipSpaces
  ParsecT Sources st m () -> ParsecT Sources st m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (ParsecT Sources st m () -> ParsecT Sources st m ())
-> ParsecT Sources st m () -> ParsecT Sources st m ()
forall a b. (a -> b) -> a -> b
$ ParsecT Sources st m () -> ParsecT Sources st m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m () -> ParsecT Sources st m ())
-> ParsecT Sources st m () -> ParsecT Sources st m ()
forall a b. (a -> b) -> a -> b
$ ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
newline ParsecT Sources st m Char
-> ParsecT Sources st m () -> ParsecT Sources st m ()
forall a b.
ParsecT Sources st m a
-> ParsecT Sources st m b -> ParsecT Sources st m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources st m Char -> ParsecT Sources st m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy ParsecT Sources st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline
  contents <- Text -> Text
trim (Text -> Text)
-> ParsecT Sources st m Text -> ParsecT Sources st m Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
     ParsecT Sources st m Char -> ParsecT Sources st m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
many1Char ((Char -> Bool) -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/=Char
'\n')
     ParsecT Sources st m Char
-> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
newline ParsecT Sources st m Char
-> ParsecT Sources st m [Char] -> ParsecT Sources st m [Char]
forall a b.
ParsecT Sources st m a
-> ParsecT Sources st m b -> ParsecT Sources st m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources st m Char -> ParsecT Sources st m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT Sources st m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar ParsecT Sources st m [Char]
-> ParsecT Sources st m Char -> ParsecT Sources st m Char
forall a b.
ParsecT Sources st m a
-> ParsecT Sources st m b -> ParsecT Sources st m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [Char] -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
noneOf [Char]
" \t\n"))
  blanklines
  return $ stripBackticks contents
  where
    stripBackticks :: Text -> Text
stripBackticks Text
t
      | Just Text
xs <- Text -> Text -> Maybe Text
T.stripSuffix Text
"`_" Text
t = (Char -> Bool) -> Text -> Text
T.dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'`') Text
xs Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_"
      | Just Text
_  <- Text -> Text -> Maybe Text
T.stripSuffix Text
"_"  Text
t = Text
t
      | Bool
otherwise                       = Text -> Text
escapeURI Text
t

substKey :: PandocMonad m => RSTParser m ()
substKey :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
substKey = ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
".."
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar
  (alt,ref) <- ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline, Text)
forall (m :: * -> *) st a.
Monad m =>
ParsecT Sources st m a -> ParsecT Sources st m (a, Text)
withRaw (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline, Text))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline, Text)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat
                      ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall end s (m :: * -> *) st t a.
(Show end, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m t
-> ParsecT s st m end -> ParsecT s st m a -> ParsecT s st m [a]
enclosed (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'|') (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'|') ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline
  res <- B.toList <$> directive'
  bls <- case res of
             -- use alt unless :alt: attribute on image:
             [Para [Image Attr
attr [Str Text
"image"] (Text
src,Text
tit)]] ->
                Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Block
B.para (Many Inline -> Many Block) -> Many Inline -> Many Block
forall a b. (a -> b) -> a -> b
$ Attr -> Text -> Text -> Many Inline -> Many Inline
B.imageWith Attr
attr Text
src Text
tit Many Inline
alt
             [Para [Link Attr
_ [Image Attr
attr [Str Text
"image"] (Text
src,Text
tit)] (Text
src',Text
tit')]] ->
                Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Block
B.para (Many Inline -> Many Block) -> Many Inline -> Many Block
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Many Inline -> Many Inline
B.link Text
src' Text
tit' (Attr -> Text -> Text -> Many Inline -> Many Inline
B.imageWith Attr
attr Text
src Text
tit Many Inline
alt)
             [Block]
_          -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ [Block] -> Many Block
forall a. [a] -> Many a
B.fromList [Block]
res
  let key = Text -> Key
toKey (Text -> Key) -> Text -> Key
forall a b. (a -> b) -> a -> b
$ Text -> Text
stripFirstAndLast Text
ref
  updateState $ \ParserState
s -> ParserState
s{ stateSubstitutions =
                          M.insert key bls $ stateSubstitutions s }

anonymousKey :: PandocMonad m => RSTParser m ()
anonymousKey :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
anonymousKey = ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ do
  [Text] -> ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
[Text] -> ParsecT s st m Text
oneOfStrings [Text
".. __:", Text
"__"]
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar
  src <- ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
targetURI
  -- we need to ensure that the keys are ordered by occurrence in
  -- the document.
  numKeys <- M.size . stateKeys <$> getState
  let key = Text -> Key
toKey (Text -> Key) -> Text -> Key
forall a b. (a -> b) -> a -> b
$ Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> [Char] -> Text
T.pack ([Char] -> Int -> [Char]
forall r. PrintfType r => [Char] -> r
printf [Char]
"%04d" Int
numKeys)
  updateState $ \ParserState
s -> ParserState
s { stateKeys = M.insert key ((src,""), nullAttr) $
                          stateKeys s }

referenceNames :: PandocMonad m => RSTParser m [Text]
referenceNames :: forall (m :: * -> *). PandocMonad m => RSTParser m [Text]
referenceNames = do
  let rn :: ParsecT Sources ParserState m Text
rn = ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Text
 -> ParsecT Sources ParserState m Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b. (a -> b) -> a -> b
$ do
             [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
".. _"
             ref <- ParsecT Sources ParserState m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
quotedReferenceName
                  ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
manyChar (  [Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
noneOf [Char]
"\\:\n"
                              ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\n' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
                                       [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"   " ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
                                       ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline)
                              ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\\' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
':')
                              ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
':' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum)
                               )
             char ':'
             return ref
  first <- ParsecT Sources ParserState m Text
rn
  rest  <- many (try (blanklines *> rn))
  return (first:rest)

regularKey :: PandocMonad m => RSTParser m ()
regularKey :: forall (m :: * -> *). PandocMonad m => RSTParser m ()
regularKey = ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ()
 -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ do
  -- we allow several references to the same URL, e.g.
  -- .. _hello:
  -- .. _goodbye: url.com
  refs <- RSTParser m [Text]
forall (m :: * -> *). PandocMonad m => RSTParser m [Text]
referenceNames
  src <- targetURI
  guard $ not (T.null src)
  let keys = (Text -> Key) -> [Text] -> [Key]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Key
toKey [Text]
refs
  forM_ keys $ \Key
key ->
    (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((ParserState -> ParserState) -> ParsecT Sources ParserState m ())
-> (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ \ParserState
s -> ParserState
s { stateKeys = M.insert key ((src,""), nullAttr) $
                            stateKeys s }

anchor :: PandocMonad m => RSTParser m Blocks
anchor :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
anchor = ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Block)
 -> ParsecT Sources ParserState m (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ do
  refs <- RSTParser m [Text]
forall (m :: * -> *). PandocMonad m => RSTParser m [Text]
referenceNames
  blanklines
  forM_ refs $ \Text
rawkey ->
    (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall (m :: * -> *) u s. Monad m => (u -> u) -> ParsecT s u m ()
updateState ((ParserState -> ParserState) -> ParsecT Sources ParserState m ())
-> (ParserState -> ParserState) -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ \ParserState
s -> ParserState
s { stateKeys =
       M.insert (toKey rawkey) (("#" <> rawkey,""), nullAttr)
         (stateKeys s) }
  b <- block
  let addDiv Text
ref = Attr -> Many Block -> Many Block
B.divWith (Text
ref, [], [])
  let emptySpanWithId Text
id' = Attr -> [Inline] -> Inline
Span (Text
id',[],[]) []
  -- put identifier on next block:
  case B.toList b of
       [Header Int
lev (Text
_,[Text]
classes,[(Text, Text)]
kvs) [Inline]
txt] ->
         case [Text] -> [Text]
forall a. [a] -> [a]
reverse [Text]
refs of
              [] -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Many Block
b
              (Text
r:[Text]
rs) -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Block -> Many Block
forall a. a -> Many a
B.singleton (Block -> Many Block) -> Block -> Many Block
forall a b. (a -> b) -> a -> b
$
                           Int -> Attr -> [Inline] -> Block
Header Int
lev (Text
r,[Text]
classes,[(Text, Text)]
kvs)
                             ([Inline]
txt [Inline] -> [Inline] -> [Inline]
forall a. [a] -> [a] -> [a]
++ (Text -> Inline) -> [Text] -> [Inline]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Inline
emptySpanWithId [Text]
rs)
                -- we avoid generating divs for headers,
                -- because it hides them from promoteHeader, see #4240
       [Block]
_ -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ (Text -> Many Block -> Many Block)
-> Many Block -> [Text] -> Many Block
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Text -> Many Block -> Many Block
addDiv Many Block
b [Text]
refs

--
-- tables
--

-- General tables TODO:
--  - figure out if leading spaces are acceptable and if so, add
--    support for them
--
-- Simple tables TODO:
--  - column spans
--  - multiline support
--  - ensure that rightmost column span does not need to reach end
--  - require at least 2 columns

dashedLine :: Monad m => Char -> ParsecT Sources st m (Int, Int)
dashedLine :: forall (m :: * -> *) st.
Monad m =>
Char -> ParsecT Sources st m (Int, Int)
dashedLine Char
ch = do
  dashes <- ParsecT Sources st m Char -> ParsecT Sources st m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (Char -> ParsecT Sources st m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
ch)
  sp     <- many (char ' ')
  return (length dashes, length $ dashes ++ sp)

simpleDashedLines :: Monad m => Char -> ParsecT Sources st m [(Int,Int)]
simpleDashedLines :: forall (m :: * -> *) st.
Monad m =>
Char -> ParsecT Sources st m [(Int, Int)]
simpleDashedLines Char
ch = ParsecT Sources st m [(Int, Int)]
-> ParsecT Sources st m [(Int, Int)]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources st m [(Int, Int)]
 -> ParsecT Sources st m [(Int, Int)])
-> ParsecT Sources st m [(Int, Int)]
-> ParsecT Sources st m [(Int, Int)]
forall a b. (a -> b) -> a -> b
$ ParsecT Sources st m (Int, Int)
-> ParsecT Sources st m [(Int, Int)]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 (Char -> ParsecT Sources st m (Int, Int)
forall (m :: * -> *) st.
Monad m =>
Char -> ParsecT Sources st m (Int, Int)
dashedLine Char
ch)

-- Parse a table row separator
simpleTableSep :: Monad m => Char -> RSTParser m Char
simpleTableSep :: forall (m :: * -> *). Monad m => Char -> RSTParser m Char
simpleTableSep Char
ch = ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Char
 -> ParsecT Sources ParserState m Char)
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT Sources ParserState m [(Int, Int)]
forall (m :: * -> *) st.
Monad m =>
Char -> ParsecT Sources st m [(Int, Int)]
simpleDashedLines Char
ch ParsecT Sources ParserState m [(Int, Int)]
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
newline

-- Parse a table footer
simpleTableFooter :: Monad m => RSTParser m Text
simpleTableFooter :: forall (m :: * -> *). Monad m => RSTParser m Text
simpleTableFooter = ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Text
 -> ParsecT Sources ParserState m Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b. (a -> b) -> a -> b
$ Char -> RSTParser m Char
forall (m :: * -> *). Monad m => Char -> RSTParser m Char
simpleTableSep Char
'=' RSTParser m Char
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Text
blanklines

-- Parse a raw line and split it into chunks by indices.
simpleTableRawLine :: Monad m => [Int] -> RSTParser m [Text]
simpleTableRawLine :: forall (m :: * -> *). Monad m => [Int] -> RSTParser m [Text]
simpleTableRawLine [Int]
indices = [Int] -> Text -> [Text]
simpleTableSplitLine [Int]
indices (Text -> [Text])
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine

simpleTableRawLineWithInitialEmptyCell :: Monad m => [Int] -> RSTParser m [Text]
simpleTableRawLineWithInitialEmptyCell :: forall (m :: * -> *). Monad m => [Int] -> RSTParser m [Text]
simpleTableRawLineWithInitialEmptyCell [Int]
indices = ParsecT Sources ParserState m [Text]
-> ParsecT Sources ParserState m [Text]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m [Text]
 -> ParsecT Sources ParserState m [Text])
-> ParsecT Sources ParserState m [Text]
-> ParsecT Sources ParserState m [Text]
forall a b. (a -> b) -> a -> b
$ do
  cs <- [Int] -> ParsecT Sources ParserState m [Text]
forall (m :: * -> *). Monad m => [Int] -> RSTParser m [Text]
simpleTableRawLine [Int]
indices
  let isEmptyCell = (Char -> Bool) -> Text -> Bool
T.all (\Char
c -> 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
'\t')
  case cs of
    Text
c:[Text]
_ | Text -> Bool
isEmptyCell Text
c -> [Text] -> ParsecT Sources ParserState m [Text]
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return [Text]
cs
    [Text]
_ -> ParsecT Sources ParserState m [Text]
forall a. ParsecT Sources ParserState m a
forall (m :: * -> *) a. MonadPlus m => m a
mzero

-- Parse a table row and return a list of blocks (columns).
simpleTableRow :: PandocMonad m => [Int] -> RSTParser m [Blocks]
simpleTableRow :: forall (m :: * -> *).
PandocMonad m =>
[Int] -> RSTParser m [Many Block]
simpleTableRow [Int]
indices = do
  ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m ()
forall b s (m :: * -> *) a st.
(Show b, Stream s m a) =>
ParsecT s st m b -> ParsecT s st m ()
notFollowedBy' ParsecT Sources ParserState m Text
forall (m :: * -> *). Monad m => RSTParser m Text
simpleTableFooter
  firstLine <- [Int] -> RSTParser m [Text]
forall (m :: * -> *). Monad m => [Int] -> RSTParser m [Text]
simpleTableRawLine [Int]
indices
  conLines  <- many $ simpleTableRawLineWithInitialEmptyCell indices
  let cols = ([Text] -> Text) -> [[Text]] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map [Text] -> Text
T.unlines ([[Text]] -> [Text])
-> ([[Text]] -> [[Text]]) -> [[Text]] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Text]] -> [[Text]]
forall a. [[a]] -> [[a]]
transpose ([[Text]] -> [Text]) -> [[Text]] -> [Text]
forall a b. (a -> b) -> a -> b
$ [Text]
firstLine [Text] -> [[Text]] -> [[Text]]
forall a. a -> [a] -> [a]
: [[Text]]
conLines [[Text]] -> [[Text]] -> [[Text]]
forall a. [a] -> [a] -> [a]
++
                                  [Int -> Text -> [Text]
forall a. Int -> a -> [a]
replicate ([Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
indices) Text
""
                                    | Bool -> Bool
not ([[Text]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Text]]
conLines)]
  mapM parseCell cols

simpleTableSplitLine :: [Int] -> Text -> [Text]
simpleTableSplitLine :: [Int] -> Text -> [Text]
simpleTableSplitLine [Int]
indices Text
line =
  (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
trimr ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
drop Int
1 ([Text] -> [Text]) -> [Text] -> [Text]
forall a b. (a -> b) -> a -> b
$ [Int] -> Text -> [Text]
splitTextByIndices ([Int] -> [Int]
forall a. HasCallStack => [a] -> [a]
init [Int]
indices) Text
line

simpleTableHeader :: PandocMonad m
                  => Bool  -- ^ Headerless table
                  -> RSTParser m ([Blocks], [Alignment], [Int])
simpleTableHeader :: forall (m :: * -> *).
PandocMonad m =>
Bool -> RSTParser m ([Many Block], [Alignment], [Int])
simpleTableHeader Bool
headless = ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
-> ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
 -> ParsecT
      Sources ParserState m ([Many Block], [Alignment], [Int]))
-> ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
-> ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Sources ParserState m Text
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Text
blanklines
  rawContent  <- if Bool
headless
                    then Text -> ParsecT Sources ParserState m Text
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
""
                    else Char -> RSTParser m Char
forall (m :: * -> *). Monad m => Char -> RSTParser m Char
simpleTableSep Char
'=' RSTParser m Char
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
anyLine
  dashes      <- if headless
                    then simpleDashedLines '='
                    else simpleDashedLines '=' <|> simpleDashedLines '-'
  newline
  let lines'   = ((Int, Int) -> Int) -> [(Int, Int)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Int) -> Int
forall a b. (a, b) -> b
snd [(Int, Int)]
dashes
  let indices  = (Int -> Int -> Int) -> Int -> [Int] -> [Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Int
0 [Int]
lines'
  let aligns   = Int -> Alignment -> [Alignment]
forall a. Int -> a -> [a]
replicate ([Int] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
lines') Alignment
AlignDefault
  let rawHeads = if Bool
headless
                    then []
                    else [Int] -> Text -> [Text]
simpleTableSplitLine [Int]
indices Text
rawContent
  heads <- mapM ( parseFromString' (mconcat <$> many plain) . trim) rawHeads
  return (heads, aligns, indices)

-- Parse a simple table.
simpleTable :: PandocMonad m
            => Bool  -- ^ Headerless table
            -> RSTParser m Blocks
simpleTable :: forall (m :: * -> *).
PandocMonad m =>
Bool -> RSTParser m (Many Block)
simpleTable Bool
headless = do
  let wrapIdFst :: (a, b, c) -> (Identity a, b, c)
wrapIdFst (a
a, b
b, c
c) = (a -> Identity a
forall a. a -> Identity a
Identity a
a, b
b, c
c)
      wrapId :: ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m (Identity a)
wrapId = (a -> Identity a)
-> ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m (Identity a)
forall a b.
(a -> b)
-> ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Identity a
forall a. a -> Identity a
Identity
  tbl <- Identity (Many Block) -> Many Block
forall a. Identity a -> a
runIdentity (Identity (Many Block) -> Many Block)
-> ParsecT Sources ParserState m (Identity (Many Block))
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT
  Sources ParserState m (Identity [Many Block], [Alignment], [Int])
-> ([Int] -> ParsecT Sources ParserState m (Identity [Many Block]))
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m (Identity (Many Block))
forall s (m :: * -> *) st (mf :: * -> *) sep end.
(Stream s m Char, UpdateSourcePos s Char, HasReaderOptions st,
 Monad mf) =>
ParsecT s st m (mf [Many Block], [Alignment], [Int])
-> ([Int] -> ParsecT s st m (mf [Many Block]))
-> ParsecT s st m sep
-> ParsecT s st m end
-> ParsecT s st m (mf (Many Block))
tableWith
           (([Many Block], [Alignment], [Int])
-> (Identity [Many Block], [Alignment], [Int])
forall {a} {b} {c}. (a, b, c) -> (Identity a, b, c)
wrapIdFst (([Many Block], [Alignment], [Int])
 -> (Identity [Many Block], [Alignment], [Int]))
-> ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
-> ParsecT
     Sources ParserState m (Identity [Many Block], [Alignment], [Int])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool
-> ParsecT Sources ParserState m ([Many Block], [Alignment], [Int])
forall (m :: * -> *).
PandocMonad m =>
Bool -> RSTParser m ([Many Block], [Alignment], [Int])
simpleTableHeader Bool
headless)
           (ParsecT Sources ParserState m [Many Block]
-> ParsecT Sources ParserState m (Identity [Many Block])
forall {a}.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m (Identity a)
wrapId (ParsecT Sources ParserState m [Many Block]
 -> ParsecT Sources ParserState m (Identity [Many Block]))
-> ([Int] -> ParsecT Sources ParserState m [Many Block])
-> [Int]
-> ParsecT Sources ParserState m (Identity [Many Block])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Int] -> ParsecT Sources ParserState m [Many Block]
forall (m :: * -> *).
PandocMonad m =>
[Int] -> RSTParser m [Many Block]
simpleTableRow)
           ParsecT Sources ParserState m ()
sep ParsecT Sources ParserState m Text
forall (m :: * -> *). Monad m => RSTParser m Text
simpleTableFooter
  -- Simple tables get 0s for relative column widths (i.e., use default)
  case B.toList tbl of
       [Table Attr
attr Caption
cap [ColSpec]
spec TableHead
th [TableBody]
tb TableFoot
tf] -> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Block -> ParsecT Sources ParserState m (Many Block))
-> Many Block -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Block -> Many Block
forall a. a -> Many a
B.singleton (Block -> Many Block) -> Block -> Many Block
forall a b. (a -> b) -> a -> b
$
                                         Attr
-> Caption
-> [ColSpec]
-> TableHead
-> [TableBody]
-> TableFoot
-> Block
Table Attr
attr Caption
cap ([ColSpec] -> [ColSpec]
forall {a}. [(Alignment, a)] -> [ColSpec]
rewidth [ColSpec]
spec) TableHead
th [TableBody]
tb TableFoot
tf
       [Block]
_ ->
         PandocError -> ParsecT Sources ParserState m (Many Block)
forall a. PandocError -> ParsecT Sources ParserState m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> ParsecT Sources ParserState m (Many Block))
-> PandocError -> ParsecT Sources ParserState m (Many Block)
forall a b. (a -> b) -> a -> b
$ Text -> PandocError
PandocShouldNeverHappenError
            Text
"tableWith returned something unexpected"
 where
  sep :: ParsecT Sources ParserState m ()
sep = () -> ParsecT Sources ParserState m ()
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return () -- optional (simpleTableSep '-')
  rewidth :: [(Alignment, a)] -> [ColSpec]
rewidth = ((Alignment, a) -> ColSpec) -> [(Alignment, a)] -> [ColSpec]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((Alignment, a) -> ColSpec) -> [(Alignment, a)] -> [ColSpec])
-> ((Alignment, a) -> ColSpec) -> [(Alignment, a)] -> [ColSpec]
forall a b. (a -> b) -> a -> b
$ (a -> ColWidth) -> (Alignment, a) -> ColSpec
forall a b. (a -> b) -> (Alignment, a) -> (Alignment, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> ColWidth) -> (Alignment, a) -> ColSpec)
-> (a -> ColWidth) -> (Alignment, a) -> ColSpec
forall a b. (a -> b) -> a -> b
$ ColWidth -> a -> ColWidth
forall a b. a -> b -> a
const ColWidth
ColWidthDefault

gridTable :: PandocMonad m
          => RSTParser m Blocks
gridTable :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
gridTable = Identity (Many Block) -> Many Block
forall a. Identity a -> a
runIdentity (Identity (Many Block) -> Many Block)
-> ParsecT Sources ParserState m (Identity (Many Block))
-> ParsecT Sources ParserState m (Many Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
  ParsecT Sources ParserState m (Identity (Many Block))
-> ParsecT Sources ParserState m (Identity (Many Block))
forall (m :: * -> *) (mf :: * -> *) st.
(Monad m, Monad mf, HasLastStrPosition st, HasReaderOptions st) =>
ParsecT Sources st m (mf (Many Block))
-> ParsecT Sources st m (mf (Many Block))
gridTableWith (Many Block -> Identity (Many Block)
forall a. a -> Identity a
Identity (Many Block -> Identity (Many Block))
-> ParsecT Sources ParserState m (Many Block)
-> ParsecT Sources ParserState m (Identity (Many Block))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
parseBlocks)

table :: PandocMonad m => RSTParser m Blocks
table :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
table = RSTParser m (Many Block)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Block)
gridTable RSTParser m (Many Block)
-> RSTParser m (Many Block) -> RSTParser m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> RSTParser m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Bool -> RSTParser m (Many Block)
simpleTable Bool
False RSTParser m (Many Block)
-> RSTParser m (Many Block) -> RSTParser m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Bool -> RSTParser m (Many Block)
forall (m :: * -> *).
PandocMonad m =>
Bool -> RSTParser m (Many Block)
simpleTable Bool
True RSTParser m (Many Block) -> [Char] -> RSTParser m (Many Block)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"table"

--
-- inline
--

inline :: PandocMonad m => RSTParser m Inlines
inline :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline =
  (RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
note          -- can start with whitespace, so try before ws
    RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do ParsecT Sources ParserState m Bool
forall s (m :: * -> *) a st.
(Stream s m a, HasLastStrPosition st) =>
ParsecT s st m Bool
notAfterString ParsecT Sources ParserState m Bool
-> (Bool -> ParsecT Sources ParserState m ())
-> ParsecT Sources ParserState m ()
forall a b.
ParsecT Sources ParserState m a
-> (a -> ParsecT Sources ParserState m b)
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Bool -> ParsecT Sources ParserState m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard
           (RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
link RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineAnchor RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
strong RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
emph)
    RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
code
    RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
subst
    RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
interpretedRole
    RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineContent) RSTParser m (Many Inline) -> [Char] -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"inline"

-- strings, spaces and other characters that can appear either by
-- themselves or within inline markup
inlineContent :: PandocMonad m => RSTParser m Inlines
inlineContent :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineContent = [ParsecT Sources ParserState m (Many Inline)]
-> ParsecT Sources ParserState m (Many Inline)
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
whitespace
                       , ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
str
                       , ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
endline
                       , ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
smart
                       , ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
hyphens
                       , ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
escapedChar
                       , ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
symbol ] ParsecT Sources ParserState m (Many Inline)
-> [Char] -> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"inline content"

parseInlineFromText :: PandocMonad m => Text -> RSTParser m Inlines
parseInlineFromText :: forall (m :: * -> *).
PandocMonad m =>
Text -> RSTParser m (Many Inline)
parseInlineFromText = ParsecT Sources ParserState m (Many Inline)
-> Text -> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *) u a.
(Monad m, HasLastStrPosition u) =>
ParsecT Sources u m a -> Text -> ParsecT Sources u m a
parseFromString' (Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline)

hyphens :: Monad m => RSTParser m Inlines
hyphens :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
hyphens = do
  result <- ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
many1Char (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'-')
  optional endline
  -- don't want to treat endline after hyphen or dash as a space
  return $ B.str result

escapedChar :: Monad m => RSTParser m Inlines
escapedChar :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
escapedChar = do c <- ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char -> ParsecT s st m Char
escaped ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
anyChar
                 unless (canPrecedeOpener c) $ updateLastStrPos
                 return $ if c == ' ' || c == '\n' || c == '\r'
                             -- '\ ' is null in RST
                             then mempty
                             else B.str $ T.singleton c

canPrecedeOpener :: Char -> Bool
canPrecedeOpener :: Char -> Bool
canPrecedeOpener Char
c =
  Char -> GeneralCategory
generalCategory Char
c GeneralCategory -> [GeneralCategory] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
   [GeneralCategory
OpenPunctuation, GeneralCategory
InitialQuote, GeneralCategory
FinalQuote, GeneralCategory
DashPunctuation, GeneralCategory
OtherSymbol]

symbol :: Monad m => RSTParser m Inlines
symbol :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
symbol = do
  c <- [Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
specialChars
  unless (canPrecedeOpener c) $ updateLastStrPos
  return $ B.str $ T.singleton c

-- parses inline code, between codeStart and codeEnd
code :: Monad m => RSTParser m Inlines
code :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
code = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"``"
  result <- ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st a.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m a -> ParsecT s st m Text
manyTillChar ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
anyChar (ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"``"))
  return $ B.code
         $ trim $ T.unwords $ T.lines result

-- succeeds only if we're not right after a str (ie. in middle of word)
atStart :: Monad m => RSTParser m a -> RSTParser m a
atStart :: forall (m :: * -> *) a. Monad m => RSTParser m a -> RSTParser m a
atStart RSTParser m a
p = do
  pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  st <- getState
  -- single quote start can't be right after str
  guard $ stateLastStrPos st /= Just pos
  p

emph :: PandocMonad m => RSTParser m Inlines
emph :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
emph = Many Inline -> Many Inline
B.emph (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
         ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall end s (m :: * -> *) st t a.
(Show end, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m t
-> ParsecT s st m end -> ParsecT s st m a -> ParsecT s st m [a]
enclosed (ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall (m :: * -> *) a. Monad m => RSTParser m a -> RSTParser m a
atStart (ParsecT Sources ParserState m Char
 -> ParsecT Sources ParserState m Char)
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b. (a -> b) -> a -> b
$ Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'*') (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'*') ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineContent

strong :: PandocMonad m => RSTParser m Inlines
strong :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
strong = Many Inline -> Many Inline
B.strong (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
          ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall end s (m :: * -> *) st t a.
(Show end, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m t
-> ParsecT s st m end -> ParsecT s st m a -> ParsecT s st m [a]
enclosed (ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) a. Monad m => RSTParser m a -> RSTParser m a
atStart (ParsecT Sources ParserState m [Char]
 -> ParsecT Sources ParserState m [Char])
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"**") (ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m [Char]
 -> ParsecT Sources ParserState m [Char])
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"**") ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineContent

-- Note, this doesn't precisely implement the complex rule in
-- http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
-- but it should be good enough for most purposes
--
-- TODO:
--  - Classes are silently discarded in addNewRole
--  - Allows direct use of the :raw: role, rST only allows inherited use.
interpretedRole :: PandocMonad m => RSTParser m Inlines
interpretedRole :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
interpretedRole = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  (role, contents) <- RSTParser m (Text, Text)
forall (m :: * -> *). PandocMonad m => RSTParser m (Text, Text)
roleBefore RSTParser m (Text, Text)
-> RSTParser m (Text, Text) -> RSTParser m (Text, Text)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Text, Text)
forall (m :: * -> *). PandocMonad m => RSTParser m (Text, Text)
roleAfter
  renderRole contents Nothing role nullAttr

renderRole :: PandocMonad m
           => Text -> Maybe Text -> Text -> Attr -> RSTParser m Inlines
renderRole :: forall (m :: * -> *).
PandocMonad m =>
Text -> Maybe Text -> Text -> Attr -> RSTParser m (Many Inline)
renderRole Text
contents Maybe Text
fmt Text
role Attr
attr = case Text
role of
    Text
"sup"  -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
B.superscript (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"superscript" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
B.superscript (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"sub"  -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
B.subscript (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"subscript"  -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
B.subscript (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"mark"  -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Attr -> Many Inline -> Many Inline
B.spanWith (Text
"",[Text
"mark"],[]) (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"emphasis" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
B.emph (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"strong" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Many Inline -> Many Inline
B.strong (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"rfc-reference" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
rfcLink Text
contents
    Text
"RFC" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
rfcLink Text
contents
    Text
"pep-reference" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
pepLink Text
contents
    Text
"PEP" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
pepLink Text
contents
    Text
"literal" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Attr -> Text -> Many Inline
B.codeWith Attr
attr Text
contents
    Text
"math" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
B.math Text
contents
    Text
"title-reference" -> Text -> RSTParser m (Many Inline)
forall {m :: * -> *}. Monad m => Text -> m (Many Inline)
titleRef Text
contents
    Text
"title" -> Text -> RSTParser m (Many Inline)
forall {m :: * -> *}. Monad m => Text -> m (Many Inline)
titleRef Text
contents
    Text
"t" -> Text -> RSTParser m (Many Inline)
forall {m :: * -> *}. Monad m => Text -> m (Many Inline)
titleRef Text
contents
    Text
"code" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Attr -> Text -> Many Inline
B.codeWith Attr
attr Text
contents
    Text
"span" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Attr -> Many Inline -> Many Inline
B.spanWith Attr
attr (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
contents
    Text
"raw" -> Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Many Inline
B.rawInline (Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"" Maybe Text
fmt) Text
contents
    Text
custom
     | Just Text
citeType <- Text -> Text -> Maybe Text
T.stripPrefix Text
"cite" Text
custom
       -> Text -> Text -> RSTParser m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> Text -> RSTParser m (Many Inline)
cite Text
citeType Text
contents
     | Bool
otherwise -> do
        customRoles <- ParserState -> Map Text (Text, Maybe Text, Attr)
stateRstCustomRoles (ParserState -> Map Text (Text, Maybe Text, Attr))
-> ParsecT Sources ParserState m ParserState
-> ParsecT
     Sources ParserState m (Map Text (Text, Maybe Text, Attr))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
        case M.lookup custom customRoles of
            Just (Text
newRole, Maybe Text
newFmt, Attr
newAttr) ->
                Text -> Maybe Text -> Text -> Attr -> RSTParser m (Many Inline)
forall (m :: * -> *).
PandocMonad m =>
Text -> Maybe Text -> Text -> Attr -> RSTParser m (Many Inline)
renderRole Text
contents Maybe Text
newFmt Text
newRole Attr
newAttr
            Maybe (Text, Maybe Text, Attr)
Nothing -> -- undefined role
                Many Inline -> RSTParser m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> RSTParser m (Many Inline))
-> Many Inline -> RSTParser m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Attr -> Text -> Many Inline
B.codeWith (Text
"",[Text
"interpreted-text"],[(Text
"role",Text
role)])
                          Text
contents
 where
   titleRef :: Text -> m (Many Inline)
titleRef Text
ref = Many Inline -> m (Many Inline)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Many Inline -> m (Many Inline)) -> Many Inline -> m (Many Inline)
forall a b. (a -> b) -> a -> b
$ Attr -> Many Inline -> Many Inline
B.spanWith (Text
"",[Text
"title-ref"],[]) (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
treatAsText Text
ref
   rfcLink :: Text -> Many Inline
rfcLink Text
rfcNo = Text -> Text -> Many Inline -> Many Inline
B.link Text
rfcUrl (Text
"RFC " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rfcNo) (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
B.str (Text
"RFC " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rfcNo)
     where rfcUrl :: Text
rfcUrl = Text
"http://www.faqs.org/rfcs/rfc" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
rfcNo Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".html"
   pepLink :: Text -> Many Inline
pepLink Text
pepNo = Text -> Text -> Many Inline -> Many Inline
B.link Text
pepUrl (Text
"PEP " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pepNo) (Many Inline -> Many Inline) -> Many Inline -> Many Inline
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
B.str (Text
"PEP " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pepNo)
     where padNo :: Text
padNo = Int -> Text -> Text
T.replicate (Int
4 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Text -> Int
T.length Text
pepNo) Text
"0" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
pepNo
           pepUrl :: Text
pepUrl = Text
"http://www.python.org/dev/peps/pep-" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
padNo Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"/"
   treatAsText :: Text -> Many Inline
treatAsText = Text -> Many Inline
B.text (Text -> Many Inline) -> (Text -> Text) -> Text -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
handleEscapes
   handleEscapes :: Text -> Text
handleEscapes = [Text] -> Text
T.concat ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Text] -> [Text]
removeSpace ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HasCallStack => Text -> Text -> [Text]
Text -> Text -> [Text]
T.splitOn Text
"\\"
     where headSpace :: Text -> Text
headSpace Text
t = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
t (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Maybe Text
T.stripPrefix Text
" " Text
t
           removeSpace :: [Text] -> [Text]
removeSpace (Text
x:[Text]
xs) = Text
x Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Text
headSpace [Text]
xs
           removeSpace []     = []

cite :: PandocMonad m => Text -> Text -> RSTParser m Inlines
cite :: forall (m :: * -> *).
PandocMonad m =>
Text -> Text -> RSTParser m (Many Inline)
cite Text
citeType Text
rawcite = do
  let citations :: [Citation]
citations =
        case (Text -> Citation) -> [Text] -> [Citation]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Citation
parseCite (HasCallStack => Text -> Text -> [Text]
Text -> Text -> [Text]
T.splitOn Text
"," Text
rawcite) of
                (Citation
c:[Citation]
cs)
                  | Text
citeType Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
":t" Bool -> Bool -> Bool
|| Text
citeType Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
":ct"
                     -> Citation
c{ citationMode = AuthorInText } Citation -> [Citation] -> [Citation]
forall a. a -> [a] -> [a]
: [Citation]
cs
                  | Text
citeType Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
":year" Bool -> Bool -> Bool
|| Text
citeType Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
":yearpar"
                     -> Citation
c{ citationMode = SuppressAuthor } Citation -> [Citation] -> [Citation]
forall a. a -> [a] -> [a]
: [Citation]
cs
                [Citation]
cs -> [Citation]
cs
  Many Inline -> ParsecT Sources ParserState m (Many Inline)
forall a. a -> ParsecT Sources ParserState m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many Inline -> ParsecT Sources ParserState m (Many Inline))
-> Many Inline -> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ [Citation] -> Many Inline -> Many Inline
B.cite [Citation]
citations (Text -> Many Inline
B.str Text
rawcite)

parseCite :: Text -> Citation
parseCite :: Text -> Citation
parseCite Text
t =
  let (ParseCiteState
_, Text
pref, Text
suff, Text
ident) = ((ParseCiteState, Text, Text, Text)
 -> Char -> (ParseCiteState, Text, Text, Text))
-> (ParseCiteState, Text, Text, Text)
-> Text
-> (ParseCiteState, Text, Text, Text)
forall a. (a -> Char -> a) -> a -> Text -> a
T.foldl (ParseCiteState, Text, Text, Text)
-> Char -> (ParseCiteState, Text, Text, Text)
go (ParseCiteState
ParseStart, Text
"", Text
"", Text
"") Text
t
  in  Citation{citationId :: Text
citationId = Text
ident
              ,citationPrefix :: [Inline]
citationPrefix = Many Inline -> [Inline]
forall a. Many a -> [a]
B.toList (Many Inline -> [Inline]) -> Many Inline -> [Inline]
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
B.text Text
pref
              ,citationSuffix :: [Inline]
citationSuffix = Many Inline -> [Inline]
forall a. Many a -> [a]
B.toList (Many Inline -> [Inline]) -> Many Inline -> [Inline]
forall a b. (a -> b) -> a -> b
$ Text -> Many Inline
B.text Text
suff
              ,citationMode :: CitationMode
citationMode = CitationMode
NormalCitation
              ,citationNoteNum :: Int
citationNoteNum = Int
0
              ,citationHash :: Int
citationHash = Int
0}
 where
   go :: (ParseCiteState, Text, Text, Text)
-> Char -> (ParseCiteState, Text, Text, Text)
go (ParseCiteState
ParseStart, Text
p, Text
s, Text
i) Char
'{' = (ParseCiteState
ParsePrefix, Text
p, Text
s, Text
i)
   go (ParseCiteState
ParseStart, Text
p, Text
s, Text
i) Char
c = (ParseCiteState
ParseId, Text
p, Text
s, Text -> Char -> Text
T.snoc Text
i Char
c)
   go (ParseCiteState
ParsePrefix, Text
p, Text
s, Text
i) Char
'}' = (ParseCiteState
ParseId, Text
p, Text
s, Text
i)
   go (ParseCiteState
ParsePrefix, Text
p, Text
s, Text
i) Char
c = (ParseCiteState
ParsePrefix, Text -> Char -> Text
T.snoc Text
p Char
c, Text
s, Text
i)
   go (ParseCiteState
ParseId, Text
p, Text
s, Text
i) Char
'{' = (ParseCiteState
ParseSuffix, Text
p, Text
s, Text
i)
   go (ParseCiteState
ParseId, Text
p, Text
s, Text
i) Char
c = (ParseCiteState
ParseId, Text
p, Text
s, Text -> Char -> Text
T.snoc Text
i Char
c)
   go (ParseCiteState
ParseSuffix, Text
p, Text
s, Text
i) Char
'}' = (ParseCiteState
ParseSuffix, Text
p, Text
s, Text
i)
   go (ParseCiteState
ParseSuffix, Text
p, Text
s, Text
i) Char
c = (ParseCiteState
ParseSuffix, Text
p, Text -> Char -> Text
T.snoc Text
s Char
c, Text
i)

data ParseCiteState = ParseStart | ParsePrefix | ParseSuffix | ParseId
  deriving (Int -> ParseCiteState -> [Char] -> [Char]
[ParseCiteState] -> [Char] -> [Char]
ParseCiteState -> [Char]
(Int -> ParseCiteState -> [Char] -> [Char])
-> (ParseCiteState -> [Char])
-> ([ParseCiteState] -> [Char] -> [Char])
-> Show ParseCiteState
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ParseCiteState -> [Char] -> [Char]
showsPrec :: Int -> ParseCiteState -> [Char] -> [Char]
$cshow :: ParseCiteState -> [Char]
show :: ParseCiteState -> [Char]
$cshowList :: [ParseCiteState] -> [Char] -> [Char]
showList :: [ParseCiteState] -> [Char] -> [Char]
Show)

-- single words consisting of alphanumerics plus isolated (no two adjacent)
-- internal hyphens, underscores, periods, colons and plus signs;
-- no whitespace or other characters are allowed
roleName :: PandocMonad m => RSTParser m Text
roleName :: forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleName = ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
many1Char (ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
oneOf [Char]
"-_.:+" ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
alphaNum))

roleMarker :: PandocMonad m => RSTParser m Text
roleMarker :: forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleMarker = Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
':' ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Sources ParserState m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleName ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
':'

roleBefore :: PandocMonad m => RSTParser m (Text,Text)
roleBefore :: forall (m :: * -> *). PandocMonad m => RSTParser m (Text, Text)
roleBefore = ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Text, Text)
 -> ParsecT Sources ParserState m (Text, Text))
-> ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall a b. (a -> b) -> a -> b
$ do
  role <- RSTParser m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleMarker
  contents <- unmarkedInterpretedText
  return (role,contents)

roleAfter :: PandocMonad m => RSTParser m (Text,Text)
roleAfter :: forall (m :: * -> *). PandocMonad m => RSTParser m (Text, Text)
roleAfter = ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Text, Text)
 -> ParsecT Sources ParserState m (Text, Text))
-> ParsecT Sources ParserState m (Text, Text)
-> ParsecT Sources ParserState m (Text, Text)
forall a b. (a -> b) -> a -> b
$ do
  contents <- RSTParser m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
unmarkedInterpretedText
  role <- roleMarker <|> (stateRstDefaultRole <$> getState)
  return (role,contents)

unmarkedInterpretedText :: PandocMonad m => RSTParser m Text
unmarkedInterpretedText :: forall (m :: * -> *). PandocMonad m => RSTParser m Text
unmarkedInterpretedText = ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m Text
 -> ParsecT Sources ParserState m Text)
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m Text
forall a b. (a -> b) -> a -> b
$ do
  RSTParser m Char -> RSTParser m Char
forall (m :: * -> *) a. Monad m => RSTParser m a -> RSTParser m a
atStart (Char -> RSTParser m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`')
  contents <- [[Char]] -> [Char]
forall a. Monoid a => [a] -> a
mconcat ([[Char]] -> [Char])
-> ParsecT Sources ParserState m [[Char]]
-> ParsecT Sources ParserState m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [[Char]]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1
       (  RSTParser m Char -> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many1 ([Char] -> RSTParser m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
noneOf [Char]
"`\\\n")
      ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> RSTParser m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'\\' RSTParser m Char
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((\Char
c -> [Char
'\\',Char
c]) (Char -> [Char])
-> RSTParser m Char -> ParsecT Sources ParserState m [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Char] -> RSTParser m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
noneOf [Char]
"\n"))
      ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ([Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"\n" ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m [Char]
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* RSTParser m Char -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy RSTParser m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline)
      ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m [Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ([Char] -> ParsecT Sources ParserState m [Char]
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m [Char]
string [Char]
"`" ParsecT Sources ParserState m [Char]
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m [Char]
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
                ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (() ()
-> ParsecT Sources ParserState m Text
-> ParsecT Sources ParserState m ()
forall a b.
a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Sources ParserState m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
roleMarker) ParsecT Sources ParserState m [Char]
-> RSTParser m Char -> ParsecT Sources ParserState m [Char]
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<*
                RSTParser m Char -> RSTParser m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ((Char -> Bool) -> RSTParser m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isAlphaNum))
       )
  char '`'
  return $ T.pack contents

whitespace :: PandocMonad m => RSTParser m Inlines
whitespace :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
whitespace = Many Inline
B.space Many Inline
-> ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m (Many Inline)
forall a b.
a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
spaceChar ParsecT Sources ParserState m (Many Inline)
-> [Char] -> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"whitespace"

str :: Monad m => RSTParser m Inlines
str :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
str = do
  let strChar :: ParsecT Sources u m Char
strChar = [Char] -> ParsecT Sources u m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
[Char] -> ParsecT s u m Char
noneOf ([Char]
"\t\n " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
specialChars)
  result <- ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Text
forall s (m :: * -> *) t st.
Stream s m t =>
ParsecT s st m Char -> ParsecT s st m Text
many1Char ParsecT Sources ParserState m Char
forall {u}. ParsecT Sources u m Char
strChar
  updateLastStrPos
  return $ B.str result

-- an endline character that can be treated as a space, not a structural break
endline :: Monad m => RSTParser m Inlines
endline :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
endline = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s u m Char
newline
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy ParsecT Sources ParserState m Char
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m Char
blankline
  -- parse potential list-starts at beginning of line differently in a list:
  st <- ParsecT Sources ParserState m ParserState
forall (m :: * -> *) s u. Monad m => ParsecT s u m u
getState
  when (stateParserContext st == ListItemState) $ notFollowedBy (anyOrderedListMarker >> spaceChar) >>
          notFollowedBy' bulletListStart
  return B.softbreak

--
-- links
--

link :: PandocMonad m => RSTParser m Inlines
link :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
link = [ParsecT Sources ParserState m (Many Inline)]
-> ParsecT Sources ParserState m (Many Inline)
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice [ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
explicitLink, ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
referenceLink, ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
autoLink]  ParsecT Sources ParserState m (Many Inline)
-> [Char] -> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> [Char] -> ParsecT s u m a
<?> [Char]
"link"

explicitLink :: PandocMonad m => RSTParser m Inlines
explicitLink :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
explicitLink = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`'
  ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`') -- `` marks start of inline code
  label' <- Many Inline -> Many Inline
trimInlines (Many Inline -> Many Inline)
-> ([Many Inline] -> Many Inline) -> [Many Inline] -> Many Inline
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Many Inline] -> Many Inline
forall a. Monoid a => [a] -> a
mconcat ([Many Inline] -> Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m (Many Inline)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
              ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m [Many Inline]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill (ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t a u.
(Stream s m t, Show a) =>
ParsecT s u m a -> ParsecT s u m ()
notFollowedBy (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'`') ParsecT Sources ParserState m ()
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineContent) (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'<')
  src <- trim . T.pack . filter (/= '\n') <$> -- see #10279
           manyTill (noneOf ">\n" <|> (char '\n' <* notFollowedBy blankline))
                    (char '>')
  skipSpaces
  string "`_"
  optional $ char '_' -- anonymous form
  let src' | Text -> Bool
isURI Text
src = Text -> Text
escapeURI Text
src
           | Bool
otherwise =
              case Text -> Maybe (Text, Char)
T.unsnoc Text
src of
                 Just (Text
xs, Char
'_') -> Text
"##REF##" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
xs
                 Maybe (Text, Char)
_              -> Text
src
  let label'' = if Many Inline
label' Many Inline -> Many Inline -> Bool
forall a. Eq a => a -> a -> Bool
== Many Inline
forall a. Monoid a => a
mempty
                   then Text -> Many Inline
B.str Text
src
                   else Many Inline
label'
  let key = Text -> Key
toKey (Text -> Key) -> Text -> Key
forall a b. (a -> b) -> a -> b
$ Many Inline -> Text
forall a. Walkable Inline a => a -> Text
stringify Many Inline
label'
  unless (key == Key mempty) $ do
    updateState $ \ParserState
s -> ParserState
s{
      stateKeys = M.insert key ((src',""), nullAttr) $ stateKeys s }
  return $ B.linkWith nullAttr src' "" label''

citationName :: PandocMonad m => RSTParser m Text
citationName :: forall (m :: * -> *). PandocMonad m => RSTParser m Text
citationName = do
  raw <- RSTParser m Text
forall (m :: * -> *). Monad m => RSTParser m Text
citationMarker
  return $ "[" <> raw <> "]"

-- We store the reference link label as the link target,
-- preceded by '##REF##'. This is replaced after the AST
-- has been built by the resolved reference.
referenceLink :: PandocMonad m => RSTParser m Inlines
referenceLink :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
referenceLink = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  ref <- (RSTParser m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
referenceName RSTParser m Text -> RSTParser m Text -> RSTParser m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
citationName) RSTParser m Text
-> ParsecT Sources ParserState m Char -> RSTParser m Text
forall a b.
ParsecT Sources ParserState m a
-> ParsecT Sources ParserState m b
-> ParsecT Sources ParserState m a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'_'
  isAnonymous <- (True <$ char '_') <|> pure False
  eof <|> notFollowedBy alphaNum
  let ref' = if Bool
isAnonymous
                then Text
"_"
                else Text
ref
  pure $ B.linkWith nullAttr ("##REF##" <> ref') "" (B.text ref)

-- We keep a list of oldkeys so we can detect lookup loops.
lookupKey :: PandocMonad m
          => [Key] -> Key -> RSTParser m ((Text, Text), Attr)
lookupKey :: forall (m :: * -> *).
PandocMonad m =>
[Key] -> Key -> RSTParser m ((Text, Text), Attr)
lookupKey [Key]
oldkeys Key
key = do
  pos <- ParsecT Sources ParserState m SourcePos
forall (m :: * -> *) s u. Monad m => ParsecT s u m SourcePos
getPosition
  state <- getState
  let keyTable = ParserState -> KeyTable
stateKeys ParserState
state
  case M.lookup key keyTable of
       Maybe ((Text, Text), Attr)
Nothing  -> do
         let Key Text
key' = Key
key
         LogMessage -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasLogMessages st) =>
LogMessage -> ParsecT s st m ()
logMessage (LogMessage -> ParsecT Sources ParserState m ())
-> LogMessage -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
ReferenceNotFound Text
key' SourcePos
pos
         ((Text, Text), Attr)
-> ParsecT Sources ParserState m ((Text, Text), Attr)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Text
"",Text
""),Attr
nullAttr)
       -- check for keys of the form link_, which need to be resolved:
       Just ((Text
u, Text
""),Attr
_) | Text -> Int
T.length Text
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1, HasCallStack => Text -> Char
Text -> Char
T.last Text
u Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_', HasCallStack => Text -> Char
Text -> Char
T.head Text
u Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'#' -> do
         let rawkey :: Text
rawkey = HasCallStack => Text -> Text
Text -> Text
T.init Text
u
         let newkey :: Key
newkey = Text -> Key
toKey Text
rawkey
         if Key
newkey Key -> [Key] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Key]
oldkeys
            then do
              -- TODO the pos is not going to be accurate
              -- because we're calling this after the AST is
              -- constructed. Probably good to remove that
              -- parameter form CircularReference at some point.
              LogMessage -> ParsecT Sources ParserState m ()
forall s (m :: * -> *) a st.
(Stream s m a, HasLogMessages st) =>
LogMessage -> ParsecT s st m ()
logMessage (LogMessage -> ParsecT Sources ParserState m ())
-> LogMessage -> ParsecT Sources ParserState m ()
forall a b. (a -> b) -> a -> b
$ Text -> SourcePos -> LogMessage
CircularReference Text
rawkey SourcePos
pos
              ((Text, Text), Attr)
-> ParsecT Sources ParserState m ((Text, Text), Attr)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Text
"",Text
""),Attr
nullAttr)
            else [Key] -> Key -> ParsecT Sources ParserState m ((Text, Text), Attr)
forall (m :: * -> *).
PandocMonad m =>
[Key] -> Key -> RSTParser m ((Text, Text), Attr)
lookupKey (Key
keyKey -> [Key] -> [Key]
forall a. a -> [a] -> [a]
:[Key]
oldkeys) Key
newkey
       Just ((Text, Text), Attr)
val -> ((Text, Text), Attr)
-> ParsecT Sources ParserState m ((Text, Text), Attr)
forall a. a -> ParsecT Sources ParserState m a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Text, Text), Attr)
val

autoURI :: Monad m => RSTParser m Inlines
autoURI :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
autoURI = do
  (orig, src) <- ParsecT Sources ParserState m (Text, Text)
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m (Text, Text)
uri
  return $ B.link src "" $ B.str orig

autoEmail :: Monad m => RSTParser m Inlines
autoEmail :: forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
autoEmail = do
  (orig, src) <- ParsecT Sources ParserState m (Text, Text)
forall s (m :: * -> *) st.
(Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m (Text, Text)
emailAddress
  return $ B.link src "" $ B.str orig

autoLink :: PandocMonad m => RSTParser m Inlines
autoLink :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
autoLink = RSTParser m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
autoURI RSTParser m (Many Inline)
-> RSTParser m (Many Inline) -> RSTParser m (Many Inline)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m (Many Inline)
forall (m :: * -> *). Monad m => RSTParser m (Many Inline)
autoEmail

subst :: PandocMonad m => RSTParser m Inlines
subst :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
subst = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  (_,ref) <- ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m ([Many Inline], Text)
forall (m :: * -> *) st a.
Monad m =>
ParsecT Sources st m a -> ParsecT Sources st m (a, Text)
withRaw (ParsecT Sources ParserState m [Many Inline]
 -> ParsecT Sources ParserState m ([Many Inline], Text))
-> ParsecT Sources ParserState m [Many Inline]
-> ParsecT Sources ParserState m ([Many Inline], Text)
forall a b. (a -> b) -> a -> b
$ ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m Char
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m [Many Inline]
forall end s (m :: * -> *) st t a.
(Show end, Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m t
-> ParsecT s st m end -> ParsecT s st m a -> ParsecT s st m [a]
enclosed (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'|') (Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'|') ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline
  let substlink = Attr -> Text -> Text -> Many Inline -> Many Inline
B.linkWith Attr
nullAttr (Text
"##SUBST##" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ref) Text
"" (Text -> Many Inline
B.text Text
ref)
  reflink <- option False (True <$ char '_')
  if reflink
     then do
       let linkref = Int -> Text -> Text
T.drop Int
1 (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Text -> Text
T.dropEnd Int
1 Text
ref
       return $ B.linkWith nullAttr ("##REF##" <> linkref) "" substlink
     else return substlink

note :: PandocMonad m => RSTParser m Inlines
note :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
note = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
whitespace
  ref <- RSTParser m Text
forall (m :: * -> *). Monad m => RSTParser m Text
noteMarker
  char '_'
  pure $ B.linkWith nullAttr ("##NOTE##" <> ref) "" (B.text ref)

smart :: PandocMonad m => RSTParser m Inlines
smart :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
smart = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall st (m :: * -> *) s.
(HasReaderOptions st, HasLastStrPosition st, HasQuoteContext st m,
 Stream s m Char, UpdateSourcePos s Char) =>
ParsecT s st m (Many Inline) -> ParsecT s st m (Many Inline)
smartPunctuation ParsecT Sources ParserState m (Many Inline)
forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inline

inlineAnchor :: PandocMonad m => RSTParser m Inlines
inlineAnchor :: forall (m :: * -> *). PandocMonad m => RSTParser m (Many Inline)
inlineAnchor = ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT Sources ParserState m (Many Inline)
 -> ParsecT Sources ParserState m (Many Inline))
-> ParsecT Sources ParserState m (Many Inline)
-> ParsecT Sources ParserState m (Many Inline)
forall a b. (a -> b) -> a -> b
$ do
  Char -> ParsecT Sources ParserState m Char
forall (m :: * -> *) s u.
(Monad m, Stream s m Char, UpdateSourcePos s Char) =>
Char -> ParsecT s u m Char
char Char
'_'
  name <- RSTParser m Text
forall (m :: * -> *). PandocMonad m => RSTParser m Text
quotedReferenceName RSTParser m Text -> RSTParser m Text -> RSTParser m Text
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> RSTParser m Text
forall (m :: * -> *) st. Monad m => ParsecT Sources st m Text
simpleReferenceName
  let ident = Extensions -> Text -> Text
textToIdentifier Extensions
forall a. Monoid a => a
mempty Text
name
  updateState $ \ParserState
s ->
    ParserState
s{ stateKeys = M.insert (toKey name) (("#" <> ident, ""), nullAttr)
                    (stateKeys s) }
  pure $ B.spanWith (ident,[],[]) (B.text name)