git.iko.soy/typeable/pandoc
on master help sign in
Implemented Ext_header_attributes.

This allows explicit attributes to be put on headers, using a syntax like that for code blocks: {#id .class .class k=v k=v}

commit23ab5ffcb0b708e4f07cafd7a877926ce0dc532b authorJohn MacFarlane <fiddlosopher@gmail.com> dateThu 10 Jan 2013, 20:22 (14 years ago) parent1a7686a
3 files changed+46−15
README+24−3 src/Text/Pandoc/Options.hs+2 src/Text/Pandoc/Readers/Markdown.hs+20−12
README+24−3
@@ -872,10 +872,31 @@ wrapping). Consider, for example:
872872
873873### Header identifiers in HTML, LaTeX, and ConTeXt ###
874874
875−**Extension: `header_identifiers`**
875+**Extension: `header_attributes`**
876876
877−Each header element in pandoc's HTML and ConTeXt output is given a
878−unique identifier. This identifier is based on the text of the header.
877+Headers can be assigned attributes using this syntax at the end
878+of the line containing the header text:
879+
880+ {#identifier .class .class key=value key=value}
881+
882+Although this syntax allows assignment of classes and key/value attributes,
883+only identifiers currently have any affect in the writers (and only in some
884+writers: HTML, LaTeX, ConTeXt, Textile, AsciiDoc). Thus, for example,
885+the following headers will all be assigned the identifier `foo`:
886+
887+ # My header {#foo}
888+
889+ ## My header ## {#foo}
890+
891+ My other header {#foo}
892+ ---------------
893+
894+(This syntax is compatible with [PHP Markdown Extra].)
895+
896+**Extension: `auto_identifiers`**
897+
898+A header without an explicitly specified identifier will be
899+automatically assigned a unique identifier based on the header text.
879900To derive the identifier from the header text,
880901
881902 - Remove all formatting, links, etc.
src/Text/Pandoc/Options.hs+2
@@ -91,6 +91,7 @@ data Extension =
9191 | Ext_literate_haskell -- ^ Enable literate Haskell conventions
9292 | Ext_abbreviations -- ^ PHP markdown extra abbreviation definitions
9393 | Ext_auto_identifiers -- ^ Automatic identifiers for headers
94+ | Ext_header_attributes -- ^ Explicit header attributes {#id .class k=v}
9495 | Ext_implicit_header_references -- ^ Implicit reference links for headers
9596 deriving (Show, Read, Enum, Eq, Ord, Bounded)
9697
@@ -129,6 +130,7 @@ pandocExtensions = Set.fromList
129130 , Ext_superscript
130131 , Ext_subscript
131132 , Ext_auto_identifiers
133+ , Ext_header_attributes
132134 , Ext_implicit_header_references
133135 ]
134136
src/Text/Pandoc/Readers/Markdown.hs+20−12
@@ -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