@@ -33,15 +33,23 @@ module Text.Pandoc.Readers.CommonMark (readCommonMark)
35import CMarkGFM
35import CMarkGFM
36+import Control.Monad.State
37+import Data.Char (isLetter, isAlphaNum, isSpace, toLower)
36import Data.List (groupBy)
38import Data.List (groupBy)
37import Data.Text (Text, unpack)
39import Data.Text (Text, unpack)
40+import qualified Data.Map as Map
38import Text.Pandoc.Class (PandocMonad)
41import Text.Pandoc.Class (PandocMonad)
39import Text.Pandoc.Definition
42import Text.Pandoc.Definition
40import Text.Pandoc.Options
43import Text.Pandoc.Options
44+import Text.Pandoc.Shared (stringify)
45+import Text.Pandoc.Walk (walkM)
42-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
47-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
43readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
48readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
44readCommonMark opts s = return $
49readCommonMark opts s = return $
50+ (if enabled Ext_gfm_auto_identifiers
51+ then addHeaderIdentifiers
45 nodeToPandoc $ commonmarkToNode opts' exts s
53 nodeToPandoc $ commonmarkToNode opts' exts s
46 where opts' = [ optSmart | enabled Ext_smart ]
54 where opts' = [ optSmart | enabled Ext_smart ]
47 exts = [ extStrikethrough | enabled Ext_strikeout ] ++
55 exts = [ extStrikethrough | enabled Ext_strikeout ] ++
@@ -49,6 +57,29 @@ readCommonMark opts s = return $
49 [ extAutolink | enabled Ext_autolink_bare_uris ]
57 [ extAutolink | enabled Ext_autolink_bare_uris ]
50 enabled x = extensionEnabled x (readerExtensions opts)
58 enabled x = extensionEnabled x (readerExtensions opts)
60+addHeaderIdentifiers :: Pandoc -> Pandoc
61+addHeaderIdentifiers doc = evalState (walkM addHeaderId doc) mempty
63+addHeaderId :: Block -> State (Map.Map String Int) Block
64+addHeaderId (Header lev (_,classes,kvs) ils) = do
66+ let ident = toIdent ils
67+ ident' <- case Map.lookup ident idmap of
69+ put (Map.insert ident 1 idmap)
72+ put (Map.adjust (+ 1) ident idmap)
73+ return (ident ++ "-" ++ show i)
74+ return $ Header lev (ident',classes,kvs) ils
75+addHeaderId x = return x
77+toIdent :: [Inline] -> String
78+toIdent = map (\c -> if isSpace c then '-' else c)
79+ . filter (\c -> isLetter c || isAlphaNum c || isSpace c ||
80+ c == '_' || c == '-')
81+ . map toLower . stringify
52nodeToPandoc :: Node -> Pandoc
83nodeToPandoc :: Node -> Pandoc
53nodeToPandoc (Node _ DOCUMENT nodes) =
84nodeToPandoc (Node _ DOCUMENT nodes) =
54 Pandoc nullMeta $ foldr addBlock [] nodes
85 Pandoc nullMeta $ foldr addBlock [] nodes