git.iko.soy/typeable/pandoc
on master help sign in
CommonMark reader: support `gfm_auto_identifiers`.
73caf92John MacFarlane
src/Text/Pandoc/Extensions.hs+3−1
@@ -133,6 +133,8 @@ data Extension =
133 | Ext_abbreviations -- ^ PHP markdown extra abbreviation definitions
133 | Ext_abbreviations -- ^ PHP markdown extra abbreviation definitions
134 | Ext_emoji -- ^ Support emoji like :smile:
134 | Ext_emoji -- ^ Support emoji like :smile:
135 | Ext_auto_identifiers -- ^ Automatic identifiers for headers
135 | Ext_auto_identifiers -- ^ Automatic identifiers for headers
136+ | Ext_gfm_auto_identifiers -- ^ Automatic identifiers for headers,
137+ -- using GitHub's method for generating identifiers
136 | Ext_ascii_identifiers -- ^ ascii-only identifiers for headers
138 | Ext_ascii_identifiers -- ^ ascii-only identifiers for headers
137 | Ext_header_attributes -- ^ Explicit header attributes {#id .class k=v}
139 | Ext_header_attributes -- ^ Explicit header attributes {#id .class k=v}
138 | Ext_mmd_header_identifiers -- ^ Multimarkdown style header identifiers [myid]
140 | Ext_mmd_header_identifiers -- ^ Multimarkdown style header identifiers [myid]
@@ -237,7 +239,7 @@ githubMarkdownExtensions = extensionsFromList
237 , Ext_pipe_tables
239 , Ext_pipe_tables
238 , Ext_raw_html
240 , Ext_raw_html
239 , Ext_fenced_code_blocks
241 , Ext_fenced_code_blocks
240− , Ext_auto_identifiers
242+ , Ext_gfm_auto_identifiers
241 , Ext_ascii_identifiers
243 , Ext_ascii_identifiers
242 , Ext_backtick_code_blocks
244 , Ext_backtick_code_blocks
243 , Ext_autolink_bare_uris
245 , Ext_autolink_bare_uris
src/Text/Pandoc/Readers/CommonMark.hs+31
@@ -33,15 +33,23 @@ module Text.Pandoc.Readers.CommonMark (readCommonMark)
33where
33where
34
34
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)
41
46
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
52+ else id) $
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)
51
59
60+addHeaderIdentifiers :: Pandoc -> Pandoc
61+addHeaderIdentifiers doc = evalState (walkM addHeaderId doc) mempty
62+
63+addHeaderId :: Block -> State (Map.Map String Int) Block
64+addHeaderId (Header lev (_,classes,kvs) ils) = do
65+ idmap <- get
66+ let ident = toIdent ils
67+ ident' <- case Map.lookup ident idmap of
68+ Nothing -> do
69+ put (Map.insert ident 1 idmap)
70+ return ident
71+ Just i -> do
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
76+
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
82+
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