@@ -59,13 +59,17 @@ pandocToMarkdown opts (Pandoc meta blocks) = do
5959 let head = if (writerStandalone opts)
6060 then metaBlock $$ text (writerHeader opts)
6161 else empty
62+ let headerBlocks = filter isHeaderBlock blocks
63+ let toc = if writerTableOfContents opts
64+ then tableOfContents opts headerBlocks
65+ else empty
6266 body <- blockListToMarkdown opts blocks
6367 (notes, _) <- get
6468 notes' <- notesToMarkdown opts (reverse notes)
6569 (_, refs) <- get -- note that the notes may contain refs
6670 refs' <- keyTableToMarkdown opts (reverse refs)
67− return $ head <> (before' $$ body <> text "\n" $$
68− notes' <> text "\n" $$ refs' $$ after')
71+ return $ head $$ before' $$ toc $$ body $$ text "" $$
72+ notes' $$ text "" $$ refs' $$ after'
6973
7074-- | Return markdown representation of reference key table.
7175keyTableToMarkdown :: WriterOptions -> KeyTable -> State WriterState Doc
@@ -118,22 +122,38 @@ metaToMarkdown opts (Meta title authors date) = do
118122 title' <- titleToMarkdown opts title
119123 authors' <- authorsToMarkdown authors
120124 date' <- dateToMarkdown date
121− return $ title' <> authors' <> date'
125+ return $ title' $$ authors' $$ date'
122126
123127titleToMarkdown :: WriterOptions -> [Inline] -> State WriterState Doc
124128titleToMarkdown opts [] = return empty
125129titleToMarkdown opts lst = do
126130 contents <- inlineListToMarkdown opts lst
127− return $ text "% " <> contents <> text "\n"
131+ return $ text "% " <> contents
128132
129133authorsToMarkdown :: [String] -> State WriterState Doc
130134authorsToMarkdown [] = return empty
131135authorsToMarkdown lst = return $
132− text "% " <> text (joinWithSep ", " (map escapeString lst)) <> text "\n"
136+ text "% " <> text (joinWithSep ", " (map escapeString lst))
133137
134138dateToMarkdown :: String -> State WriterState Doc
135139dateToMarkdown [] = return empty
136−dateToMarkdown str = return $ text "% " <> text (escapeString str) <> text "\n"
140+dateToMarkdown str = return $ text "% " <> text (escapeString str)
141+
142+-- | Construct table of contents from list of header blocks.
143+tableOfContents :: WriterOptions -> [Block] -> Doc
144+tableOfContents opts headers =
145+ let opts' = opts { writerIgnoreNotes = True }
146+ contents = BulletList $ map elementToListItem $ hierarchicalize headers
147+ in evalState (blockToMarkdown opts' contents) ([],[])
148+
149+-- | Converts an Element to a list item for a table of contents,
150+elementToListItem :: Element -> [Block]
151+elementToListItem (Blk _) = []
152+elementToListItem (Sec headerText subsecs) =
153+ [Plain headerText] ++
154+ if null subsecs
155+ then []
156+ else [BulletList $ map elementToListItem subsecs]
137157
138158-- | Convert Pandoc block element to markdown.
139159blockToMarkdown :: WriterOptions -- ^ Options