summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn MacFarlane <jgm@berkeley.edu>2015-04-17 19:06:25 -0700
committerJohn MacFarlane <jgm@berkeley.edu>2015-04-17 19:06:25 -0700
commit44fcc5f96e3f412337a98a1791a79b059579f78e (patch)
tree72365d6fdd854139e2bbdf24618d0bbde7436f74 /src
parent96abd907bd1090b4dd5fdc6f9aa5a9fa845efbfe (diff)
parent4b7ddeb63fb754cbe3f4f6ea809532b2b92ca513 (diff)
Merge pull request #2079 from lierdakil/rst-normalize-headings
RST Writer: Normalize headings to sequential levels
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Writers/RST.hs43
1 files changed, 36 insertions, 7 deletions
diff --git a/src/Text/Pandoc/Writers/RST.hs b/src/Text/Pandoc/Writers/RST.hs
index 2f4c9575e..2dd899680 100644
--- a/src/Text/Pandoc/Writers/RST.hs
+++ b/src/Text/Pandoc/Writers/RST.hs
@@ -54,6 +54,7 @@ data WriterState =
, stHasMath :: Bool
, stHasRawTeX :: Bool
, stOptions :: WriterOptions
+ , stTopLevel :: Bool
}
-- | Convert Pandoc to RST.
@@ -61,7 +62,8 @@ writeRST :: WriterOptions -> Pandoc -> String
writeRST opts document =
let st = WriterState { stNotes = [], stLinks = [],
stImages = [], stHasMath = False,
- stHasRawTeX = False, stOptions = opts }
+ stHasRawTeX = False, stOptions = opts,
+ stTopLevel = True}
in evalState (pandocToRST document) st
-- | Return RST representation of document.
@@ -79,7 +81,7 @@ pandocToRST (Pandoc meta blocks) = do
(fmap (render colwidth) . blockListToRST)
(fmap (trimr . render colwidth) . inlineListToRST)
$ deleteMeta "title" $ deleteMeta "subtitle" meta
- body <- blockListToRST blocks
+ body <- blockListToRST' True $ normalizeHeadings 1 blocks
notes <- liftM (reverse . stNotes) get >>= notesToRST
-- note that the notes may contain refs, so we do them first
refs <- liftM (reverse . stLinks) get >>= refsToRST
@@ -98,6 +100,13 @@ pandocToRST (Pandoc meta blocks) = do
if writerStandalone opts
then return $ renderTemplate' (writerTemplate opts) context
else return main
+ where
+ normalizeHeadings lev (Header l a i:bs) = Header lev a i:normalizeHeadings (lev+1) cont ++ normalizeHeadings lev bs'
+ where (cont,bs') = break (headerLtEq l) bs
+ headerLtEq level (Header l' _ _) = l' <= level
+ headerLtEq _ _ = False
+ normalizeHeadings lev (b:bs) = b:normalizeHeadings lev bs
+ normalizeHeadings _ [] = []
-- | Return RST representation of reference key table.
refsToRST :: Refs -> State WriterState Doc
@@ -191,11 +200,21 @@ blockToRST (RawBlock f@(Format f') str)
(nest 3 $ text str) $$ blankline
blockToRST HorizontalRule =
return $ blankline $$ "--------------" $$ blankline
-blockToRST (Header level _ inlines) = do
+blockToRST (Header level (name,classes,_) inlines) = do
contents <- inlineListToRST inlines
- let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
- let border = text $ replicate (offset contents) headerChar
- return $ nowrap $ contents $$ border $$ blankline
+ isTopLevel <- gets stTopLevel
+ if isTopLevel
+ then do
+ let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
+ let border = text $ replicate (offset contents) headerChar
+ return $ nowrap $ contents $$ border $$ blankline
+ else do
+ let rub = "rubric:: " <> contents
+ let name' | null name = empty
+ | otherwise = ":name: " <> text name
+ let cls | null classes = empty
+ | otherwise = ":class: " <> text (unwords classes)
+ return $ nowrap $ hang 3 ".. " (rub $$ name' $$ cls) $$ blankline
blockToRST (CodeBlock (_,classes,kvs) str) = do
opts <- stOptions <$> get
let tabstop = writerTabStop opts
@@ -297,9 +316,19 @@ definitionListItemToRST (label, defs) = do
return $ label' $$ nest tabstop (nestle contents <> cr)
-- | Convert list of Pandoc block elements to RST.
+blockListToRST' :: Bool
+ -> [Block] -- ^ List of block elements
+ -> State WriterState Doc
+blockListToRST' topLevel blocks = do
+ tl <- gets stTopLevel
+ modify (\s->s{stTopLevel=topLevel})
+ res <- vcat `fmap` mapM blockToRST blocks
+ modify (\s->s{stTopLevel=tl})
+ return res
+
blockListToRST :: [Block] -- ^ List of block elements
-> State WriterState Doc
-blockListToRST blocks = mapM blockToRST blocks >>= return . vcat
+blockListToRST = blockListToRST' False
-- | Convert list of Pandoc inline elements to RST.
inlineListToRST :: [Inline] -> State WriterState Doc