@@ -54,6 +54,7 @@ data WriterState =
5454 , stHasMath :: Bool
5555 , stHasRawTeX :: Bool
5656 , stOptions :: WriterOptions
57+ , stTopLevel :: Bool
5758 }
5859
5960-- | Convert Pandoc to RST.
@@ -61,7 +62,8 @@ writeRST :: WriterOptions -> Pandoc -> String
6162writeRST opts document =
6263 let st = WriterState { stNotes = [], stLinks = [],
6364 stImages = [], stHasMath = False,
64− stHasRawTeX = False, stOptions = opts }
65+ stHasRawTeX = False, stOptions = opts,
66+ stTopLevel = True}
6567 in evalState (pandocToRST document) st
6668
6769-- | Return RST representation of document.
@@ -79,7 +81,7 @@ pandocToRST (Pandoc meta blocks) = do
7981 (fmap (render colwidth) . blockListToRST)
8082 (fmap (trimr . render colwidth) . inlineListToRST)
8183 $ deleteMeta "title" $ deleteMeta "subtitle" meta
82− body <- blockListToRST blocks
84+ body <- blockListToRST' True $ normalizeHeadings 1 blocks
8385 notes <- liftM (reverse . stNotes) get >>= notesToRST
8486 -- note that the notes may contain refs, so we do them first
8587 refs <- liftM (reverse . stLinks) get >>= refsToRST
@@ -98,6 +100,13 @@ pandocToRST (Pandoc meta blocks) = do
98100 if writerStandalone opts
99101 then return $ renderTemplate' (writerTemplate opts) context
100102 else return main
103+ where
104+ normalizeHeadings lev (Header l a i:bs) = Header lev a i:normalizeHeadings (lev+1) cont ++ normalizeHeadings lev bs'
105+ where (cont,bs') = break (headerLtEq l) bs
106+ headerLtEq level (Header l' _ _) = l' <= level
107+ headerLtEq _ _ = False
108+ normalizeHeadings lev (b:bs) = b:normalizeHeadings lev bs
109+ normalizeHeadings _ [] = []
101110
102111-- | Return RST representation of reference key table.
103112refsToRST :: Refs -> State WriterState Doc
@@ -191,11 +200,21 @@ blockToRST (RawBlock f@(Format f') str)
191200 (nest 3 $ text str) $$ blankline
192201blockToRST HorizontalRule =
193202 return $ blankline $$ "--------------" $$ blankline
194−blockToRST (Header level _ inlines) = do
203+blockToRST (Header level (name,classes,_) inlines) = do
195204 contents <- inlineListToRST inlines
196− let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
197− let border = text $ replicate (offset contents) headerChar
198− return $ nowrap $ contents $$ border $$ blankline
205+ isTopLevel <- gets stTopLevel
206+ if isTopLevel
207+ then do
208+ let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
209+ let border = text $ replicate (offset contents) headerChar
210+ return $ nowrap $ contents $$ border $$ blankline
211+ else do
212+ let rub = "rubric:: " <> contents
213+ let name' | null name = empty
214+ | otherwise = ":name: " <> text name
215+ let cls | null classes = empty
216+ | otherwise = ":class: " <> text (unwords classes)
217+ return $ nowrap $ hang 3 ".. " (rub $$ name' $$ cls) $$ blankline
199218blockToRST (CodeBlock (_,classes,kvs) str) = do
200219 opts <- stOptions <$> get
201220 let tabstop = writerTabStop opts
@@ -297,9 +316,19 @@ definitionListItemToRST (label, defs) = do
297316 return $ label' $$ nest tabstop (nestle contents <> cr)
298317
299318-- | Convert list of Pandoc block elements to RST.
319+blockListToRST' :: Bool
320+ -> [Block] -- ^ List of block elements
321+ -> State WriterState Doc
322+blockListToRST' topLevel blocks = do
323+ tl <- gets stTopLevel
324+ modify (\s->s{stTopLevel=topLevel})
325+ res <- vcat `fmap` mapM blockToRST blocks
326+ modify (\s->s{stTopLevel=tl})
327+ return res
328+
300329blockListToRST :: [Block] -- ^ List of block elements
301330 -> State WriterState Doc
302−blockListToRST blocks = mapM blockToRST blocks >>= return . vcat
331+blockListToRST = blockListToRST' False
303332
304333-- | Convert list of Pandoc inline elements to RST.
305334inlineListToRST :: [Inline] -> State WriterState Doc