git.iko.soy/typeable/pandoc
on master help sign in
CommonMark reader: support `gfm_auto_identifiers`.

Added `Ext_gfm_auto_identifiers`: new constructor for `Extension` in `Text.Pandoc.Extensions` [API change]. Use this in githubExtensions. Closes #2821.

commit73caf92871a2fb40b6f092e90a86d366eca630cb authorJohn MacFarlane <jgm@berkeley.edu> dateTue 8 Aug 2017, 11:33 (9 years ago) parent312349b
2 files changed+34−1
src/Text/Pandoc/Extensions.hs+3−1 src/Text/Pandoc/Readers/CommonMark.hs+31
src/Text/Pandoc/Extensions.hs+3−1
@@ -133,6 +133,8 @@ data Extension =
133133 | Ext_abbreviations -- ^ PHP markdown extra abbreviation definitions
134134 | Ext_emoji -- ^ Support emoji like :smile:
135135 | Ext_auto_identifiers -- ^ Automatic identifiers for headers
136+ | Ext_gfm_auto_identifiers -- ^ Automatic identifiers for headers,
137+ -- using GitHub's method for generating identifiers
136138 | Ext_ascii_identifiers -- ^ ascii-only identifiers for headers
137139 | Ext_header_attributes -- ^ Explicit header attributes {#id .class k=v}
138140 | Ext_mmd_header_identifiers -- ^ Multimarkdown style header identifiers [myid]
@@ -237,7 +239,7 @@ githubMarkdownExtensions = extensionsFromList
237239 , Ext_pipe_tables
238240 , Ext_raw_html
239241 , Ext_fenced_code_blocks
240− , Ext_auto_identifiers
242+ , Ext_gfm_auto_identifiers
241243 , Ext_ascii_identifiers
242244 , Ext_backtick_code_blocks
243245 , Ext_autolink_bare_uris
src/Text/Pandoc/Readers/CommonMark.hs+31
@@ -33,15 +33,23 @@ module Text.Pandoc.Readers.CommonMark (readCommonMark)
3333where
3434
3535import CMarkGFM
36+import Control.Monad.State
37+import Data.Char (isLetter, isAlphaNum, isSpace, toLower)
3638import Data.List (groupBy)
3739import Data.Text (Text, unpack)
40+import qualified Data.Map as Map
3841import Text.Pandoc.Class (PandocMonad)
3942import Text.Pandoc.Definition
4043import Text.Pandoc.Options
44+import Text.Pandoc.Shared (stringify)
45+import Text.Pandoc.Walk (walkM)
4146
4247-- | Parse a CommonMark formatted string into a 'Pandoc' structure.
4348readCommonMark :: PandocMonad m => ReaderOptions -> Text -> m Pandoc
4449readCommonMark opts s = return $
50+ (if enabled Ext_gfm_auto_identifiers
51+ then addHeaderIdentifiers
52+ else id) $
4553 nodeToPandoc $ commonmarkToNode opts' exts s
4654 where opts' = [ optSmart | enabled Ext_smart ]
4755 exts = [ extStrikethrough | enabled Ext_strikeout ] ++
@@ -49,6 +57,29 @@ readCommonMark opts s = return $
4957 [ extAutolink | enabled Ext_autolink_bare_uris ]
5058 enabled x = extensionEnabled x (readerExtensions opts)
5159
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+
5283nodeToPandoc :: Node -> Pandoc
5384nodeToPandoc (Node _ DOCUMENT nodes) =
5485 Pandoc nullMeta $ foldr addBlock [] nodes