@@ -54,6 +54,7 @@ data WriterState =
54 , stHasMath :: Bool
54 , stHasMath :: Bool
55 , stHasRawTeX :: Bool
55 , stHasRawTeX :: Bool
56 , stOptions :: WriterOptions
56 , stOptions :: WriterOptions
59-- | Convert Pandoc to RST.
60-- | Convert Pandoc to RST.
@@ -61,7 +62,8 @@ writeRST :: WriterOptions -> Pandoc -> String
61writeRST opts document =
62writeRST opts document =
62 let st = WriterState { stNotes = [], stLinks = [],
63 let st = WriterState { stNotes = [], stLinks = [],
63 stImages = [], stHasMath = False,
64 stImages = [], stHasMath = False,
64− stHasRawTeX = False, stOptions = opts }
65+ stHasRawTeX = False, stOptions = opts,
65 in evalState (pandocToRST document) st
67 in evalState (pandocToRST document) st
67-- | Return RST representation of document.
69-- | Return RST representation of document.
@@ -79,7 +81,7 @@ pandocToRST (Pandoc meta blocks) = do
79 (fmap (render colwidth) . blockListToRST)
81 (fmap (render colwidth) . blockListToRST)
80 (fmap (trimr . render colwidth) . inlineListToRST)
82 (fmap (trimr . render colwidth) . inlineListToRST)
81 $ deleteMeta "title" $ deleteMeta "subtitle" meta
83 $ deleteMeta "title" $ deleteMeta "subtitle" meta
82− body <- blockListToRST blocks
84+ body <- blockListToRST' True $ normalizeHeadings 1 blocks
83 notes <- liftM (reverse . stNotes) get >>= notesToRST
85 notes <- liftM (reverse . stNotes) get >>= notesToRST
84 -- note that the notes may contain refs, so we do them first
86 -- note that the notes may contain refs, so we do them first
85 refs <- liftM (reverse . stLinks) get >>= refsToRST
87 refs <- liftM (reverse . stLinks) get >>= refsToRST
@@ -98,6 +100,13 @@ pandocToRST (Pandoc meta blocks) = do
98 if writerStandalone opts
100 if writerStandalone opts
99 then return $ renderTemplate' (writerTemplate opts) context
101 then return $ renderTemplate' (writerTemplate opts) context
100 else return main
102 else return main
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 _ [] = []
102-- | Return RST representation of reference key table.
111-- | Return RST representation of reference key table.
103refsToRST :: Refs -> State WriterState Doc
112refsToRST :: Refs -> State WriterState Doc
@@ -191,11 +200,21 @@ blockToRST (RawBlock f@(Format f') str)
191 (nest 3 $ text str) $$ blankline
200 (nest 3 $ text str) $$ blankline
192blockToRST HorizontalRule =
201blockToRST HorizontalRule =
193 return $ blankline $$ "--------------" $$ blankline
202 return $ blankline $$ "--------------" $$ blankline
194−blockToRST (Header level _ inlines) = do
203+blockToRST (Header level (name,classes,_) inlines) = do
195 contents <- inlineListToRST inlines
204 contents <- inlineListToRST inlines
205+ isTopLevel <- gets stTopLevel
196− let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
208+ let headerChar = if level > 5 then ' ' else "=-~^'" !! (level - 1)
197− let border = text $ replicate (offset contents) headerChar
209+ let border = text $ replicate (offset contents) headerChar
198− return $ nowrap $ contents $$ border $$ blankline
210+ return $ nowrap $ contents $$ border $$ blankline
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
199blockToRST (CodeBlock (_,classes,kvs) str) = do
218blockToRST (CodeBlock (_,classes,kvs) str) = do
200 opts <- stOptions <$> get
219 opts <- stOptions <$> get
201 let tabstop = writerTabStop opts
220 let tabstop = writerTabStop opts
@@ -297,9 +316,19 @@ definitionListItemToRST (label, defs) = do
297 return $ label' $$ nest tabstop (nestle contents <> cr)
316 return $ label' $$ nest tabstop (nestle contents <> cr)
299-- | Convert list of Pandoc block elements to RST.
318-- | 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})
300blockListToRST :: [Block] -- ^ List of block elements
329blockListToRST :: [Block] -- ^ List of block elements
301 -> State WriterState Doc
330 -> State WriterState Doc
302−blockListToRST blocks = mapM blockToRST blocks >>= return . vcat
331+blockListToRST = blockListToRST' False
304-- | Convert list of Pandoc inline elements to RST.
333-- | Convert list of Pandoc inline elements to RST.
305inlineListToRST :: [Inline] -> State WriterState Doc
334inlineListToRST :: [Inline] -> State WriterState Doc