@@ -373,40 +373,48 @@ header :: MarkdownParser (F Blocks)
373373header = setextHeader <|> atxHeader <?> "header"
374374
375375-- returns unique identifier
376−addToHeaderList :: F Inlines -> MarkdownParser String
377−addToHeaderList text = do
376+addToHeaderList :: Attr -> F Inlines -> MarkdownParser Attr
377+addToHeaderList (ident,classes,kvs) text = do
378378 let headerList = B.toList $ runF text defaultParserState
379379 updateState $ \st -> st{ stateHeaders = headerList : stateHeaders st }
380380 (do guardEnabled Ext_auto_identifiers
381381 ids <- stateIdentifiers `fmap` getState
382− let id' = uniqueIdent headerList ids
382+ let id' = if null ident
383+ then uniqueIdent headerList ids
384+ else ident
383385 updateState $ \st -> st{ stateIdentifiers = id' : ids }
384− return id') <|> return ""
386+ return (id',classes,kvs)) <|> return ("",classes,kvs)
385387
386388atxHeader :: MarkdownParser (F Blocks)
387389atxHeader = try $ do
388390 level <- many1 (char '#') >>= return . length
389391 notFollowedBy (char '.' <|> char ')') -- this would be a list
390392 skipSpaces
391− text <- trimInlinesF . mconcat <$> manyTill inline atxClosing
392− id' <- addToHeaderList text
393− return $ B.headerWith (id',[],[]) level <$> text
393+ text <- trimInlinesF . mconcat <$> many (notFollowedBy atxClosing >> inline)
394+ attr <- atxClosing
395+ attr' <- addToHeaderList attr text
396+ return $ B.headerWith attr' level <$> text
394397
395−atxClosing :: Parser [Char] st String
396−atxClosing = try $ skipMany (char '#') >> blanklines
398+atxClosing :: Parser [Char] st Attr
399+atxClosing =
400+ try $ skipMany (char '#') >> skipSpaces >> option nullAttr attributes <* blanklines
401+
402+setextHeaderEnd :: MarkdownParser Attr
403+setextHeaderEnd = try $ option nullAttr attributes <* blankline
397404
398405setextHeader :: MarkdownParser (F Blocks)
399406setextHeader = try $ do
400407 -- This lookahead prevents us from wasting time parsing Inlines
401408 -- unless necessary -- it gives a significant performance boost.
402409 lookAhead $ anyLine >> many1 (oneOf setextHChars) >> blankline
403− text <- trimInlinesF . mconcat <$> many1Till inline newline
410+ text <- trimInlinesF . mconcat <$> many1 (notFollowedBy setextHeaderEnd >> inline)
411+ attr <- setextHeaderEnd
404412 underlineChar <- oneOf setextHChars
405413 many (char underlineChar)
406414 blanklines
407415 let level = (fromMaybe 0 $ findIndex (== underlineChar) setextHChars) + 1
408− id' <- addToHeaderList text
409− return $ B.headerWith (id',[],[]) level <$> text
416+ attr' <- addToHeaderList attr text
417+ return $ B.headerWith attr' level <$> text
410418
411419--
412420-- hrule block