git.iko.soy/typeable/pandoc
on master help sign in
Markdown reader efficiency improvements.
7229d06John MacFarlane
src/Text/Pandoc/Readers/Markdown.hs+208−182
@@ -247,51 +247,60 @@ titleBlock :: PandocMonad m => MarkdownParser m ()
247titleBlock = pandocTitleBlock <|> mmdTitleBlock
247titleBlock = pandocTitleBlock <|> mmdTitleBlock
248
248
249pandocTitleBlock :: PandocMonad m => MarkdownParser m ()
249pandocTitleBlock :: PandocMonad m => MarkdownParser m ()
250−pandocTitleBlock = try $ do
250+pandocTitleBlock = do
251 guardEnabled Ext_pandoc_title_block
251 guardEnabled Ext_pandoc_title_block
252 lookAhead (char '%')
252 lookAhead (char '%')
253+ try $ do
253− title <- option mempty titleLine
254+ title <- option mempty titleLine
254− author <- option (return []) authorsLine
255+ author <- option (return []) authorsLine
255− date <- option mempty dateLine
256+ date <- option mempty dateLine
256− optional blanklines
257+ optional blanklines
257− let meta' = do title' <- title
258+ let meta' = do title' <- title
258− author' <- author
259+ author' <- author
259− date' <- date
260+ date' <- date
260− return $
261+ return $
262+ (if null title'
263+ then id
261− (if null title' then id else B.setMeta "title" title')
264+ else B.setMeta "title" title')
265+ . (if null author'
266+ then id
262− . (if null author' then id else B.setMeta "author" author')
267+ else B.setMeta "author" author')
268+ . (if null date'
269+ then id
263− . (if null date' then id else B.setMeta "date" date')
270+ else B.setMeta "date" date')
264− $ nullMeta
271+ $ nullMeta
265− updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }
272+ updateState $ \st -> st{ stateMeta' = stateMeta' st <> meta' }
266
273
267yamlMetaBlock :: PandocMonad m => MarkdownParser m (F Blocks)
274yamlMetaBlock :: PandocMonad m => MarkdownParser m (F Blocks)
268−yamlMetaBlock = try $ do
275+yamlMetaBlock = do
269 guardEnabled Ext_yaml_metadata_block
276 guardEnabled Ext_yaml_metadata_block
277+ try $ do
270− string "---"
278+ string "---"
271− blankline
279+ blankline
272− notFollowedBy blankline -- if --- is followed by a blank it's an HRULE
280+ notFollowedBy blankline -- if --- is followed by a blank it's an HRULE
273− rawYamlLines <- manyTill anyLine stopLine
281+ rawYamlLines <- manyTill anyLine stopLine
274− -- by including --- and ..., we allow yaml blocks with just comments:
282+ -- by including --- and ..., we allow yaml blocks with just comments:
275− let rawYaml = T.unlines ("---" : (rawYamlLines ++ ["..."]))
283+ let rawYaml = T.unlines ("---" : (rawYamlLines ++ ["..."]))
276− optional blanklines
284+ optional blanklines
277− newMetaF <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks)
285+ newMetaF <- yamlBsToMeta (fmap B.toMetaValue <$> parseBlocks)
278− $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
286+ $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
279− -- Since `<>` is left-biased, existing values are not touched:
287+ -- Since `<>` is left-biased, existing values are not touched:
280− updateState $ \st -> st{ stateMeta' = stateMeta' st <> newMetaF }
288+ updateState $ \st -> st{ stateMeta' = stateMeta' st <> newMetaF }
281− return mempty
289+ return mempty
282
290
283stopLine :: PandocMonad m => MarkdownParser m ()
291stopLine :: PandocMonad m => MarkdownParser m ()
284stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()
292stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()
285
293
286mmdTitleBlock :: PandocMonad m => MarkdownParser m ()
294mmdTitleBlock :: PandocMonad m => MarkdownParser m ()
287−mmdTitleBlock = try $ do
295+mmdTitleBlock = do
288 guardEnabled Ext_mmd_title_block
296 guardEnabled Ext_mmd_title_block
297+ try $ do
289− firstPair <- kvPair False
298+ firstPair <- kvPair False
290− restPairs <- many (kvPair True)
299+ restPairs <- many (kvPair True)
291− let kvPairs = firstPair : restPairs
300+ let kvPairs = firstPair : restPairs
292− blanklines
301+ blanklines
293− updateState $ \st -> st{ stateMeta' = stateMeta' st <>
302+ updateState $ \st -> st{ stateMeta' = stateMeta' st <>
294− return (Meta $ M.fromList kvPairs) }
303+ return (Meta $ M.fromList kvPairs) }
295
304
296kvPair :: PandocMonad m => Bool -> MarkdownParser m (Text, MetaValue)
305kvPair :: PandocMonad m => Bool -> MarkdownParser m (Text, MetaValue)
297kvPair allowEmpty = try $ do
306kvPair allowEmpty = try $ do
@@ -661,15 +670,15 @@ codeBlockFenced :: PandocMonad m => MarkdownParser m (F Blocks)
661codeBlockFenced = try $ do
670codeBlockFenced = try $ do
662 indentchars <- nonindentSpaces
671 indentchars <- nonindentSpaces
663 let indentLevel = T.length indentchars
672 let indentLevel = T.length indentchars
664− c <- try (guardEnabled Ext_fenced_code_blocks >> lookAhead (char '~'))
673+ c <- (guardEnabled Ext_fenced_code_blocks >> lookAhead (char '~'))
665 <|> (guardEnabled Ext_backtick_code_blocks >> lookAhead (char '`'))
674 <|> (guardEnabled Ext_backtick_code_blocks >> lookAhead (char '`'))
666 size <- blockDelimiter (== c) Nothing
675 size <- blockDelimiter (== c) Nothing
667 skipMany spaceChar
676 skipMany spaceChar
668 rawattr <-
677 rawattr <-
669− (Left <$> try (guardEnabled Ext_raw_attribute >> rawAttribute))
678+ (Left <$> (guardEnabled Ext_raw_attribute >> try rawAttribute))
670 <|>
679 <|>
671 (Right <$> option ("",[],[])
680 (Right <$> option ("",[],[])
672− (try (guardEnabled Ext_fenced_code_attributes >> attributes)
681+ ((guardEnabled Ext_fenced_code_attributes >> try attributes)
673 <|> ((\x -> ("",[toLanguageId x],[])) <$> many1Char nonspaceChar)))
682 <|> ((\x -> ("",[toLanguageId x],[])) <$> many1Char nonspaceChar)))
674 blankline
683 blankline
675 contents <- T.intercalate "\n" <$>
684 contents <- T.intercalate "\n" <$>
@@ -1157,11 +1166,12 @@ stripMarkdownAttribute s = renderTags' $ map filterAttrib $ parseTags s
1157--
1166--
1158
1167
1159lineBlock :: PandocMonad m => MarkdownParser m (F Blocks)
1168lineBlock :: PandocMonad m => MarkdownParser m (F Blocks)
1160−lineBlock = try $ do
1169+lineBlock = do
1161 guardEnabled Ext_line_blocks
1170 guardEnabled Ext_line_blocks
1171+ try $ do
1162− lines' <- lineBlockLines >>=
1172+ lines' <- lineBlockLines >>=
1163− mapM (parseFromString' (trimInlinesF <$> inlines))
1173+ mapM (parseFromString' (trimInlinesF <$> inlines))
1164− return $ B.lineBlock <$> sequence lines'
1174+ return $ B.lineBlock <$> sequence lines'
1165
1175
1166--
1176--
1167-- Tables
1177-- Tables
@@ -1263,11 +1273,12 @@ multilineRow indices = do
1263-- Parses a table caption: inlines beginning with 'Table:'
1273-- Parses a table caption: inlines beginning with 'Table:'
1264-- and followed by blank lines.
1274-- and followed by blank lines.
1265tableCaption :: PandocMonad m => MarkdownParser m (F Inlines)
1275tableCaption :: PandocMonad m => MarkdownParser m (F Inlines)
1266−tableCaption = try $ do
1276+tableCaption = do
1267 guardEnabled Ext_table_captions
1277 guardEnabled Ext_table_captions
1278+ try $ do
1268− skipNonindentSpaces
1279+ skipNonindentSpaces
1269− (string ":" <* notFollowedBy (satisfy isPunctuation)) <|> string "Table:"
1280+ (string ":" <* notFollowedBy (satisfy isPunctuation)) <|> string "Table:"
1270− trimInlinesF <$> inlines1 <* blanklines
1281+ trimInlinesF <$> inlines1 <* blanklines
1271
1282
1272-- Parse a simple table with '---' header and one line per row.
1283-- Parse a simple table with '---' header and one line per row.
1273simpleTable :: PandocMonad m
1284simpleTable :: PandocMonad m
@@ -1436,15 +1447,14 @@ table :: PandocMonad m => MarkdownParser m (F Blocks)
1436table = try $ do
1447table = try $ do
1437 frontCaption <- option Nothing (Just <$> tableCaption)
1448 frontCaption <- option Nothing (Just <$> tableCaption)
1438 (aligns, widths, heads, lns) <-
1449 (aligns, widths, heads, lns) <-
1439− try (guardEnabled Ext_pipe_tables >> scanForPipe >> pipeTable) <|>
1450+ (guardEnabled Ext_pipe_tables >> try (scanForPipe >> pipeTable)) <|>
1440− try (guardEnabled Ext_multiline_tables >>
1451+ (guardEnabled Ext_multiline_tables >> try (multilineTable False)) <|>
1441− multilineTable False) <|>
1442− try (guardEnabled Ext_simple_tables >>
1452+ (guardEnabled Ext_simple_tables >>
1443− (simpleTable True <|> simpleTable False)) <|>
1453+ try (simpleTable True <|> simpleTable False)) <|>
1444− try (guardEnabled Ext_multiline_tables >>
1454+ (guardEnabled Ext_multiline_tables >>
1445− multilineTable True) <|>
1455+ try (multilineTable True)) <|>
1446− try (guardEnabled Ext_grid_tables >>
1456+ (guardEnabled Ext_grid_tables >>
1447− (gridTable False <|> gridTable True)) <?> "table"
1457+ try (gridTable False <|> gridTable True)) <?> "table"
1448 optional blanklines
1458 optional blanklines
1449 caption <- case frontCaption of
1459 caption <- case frontCaption of
1450 Nothing -> option (return mempty) tableCaption
1460 Nothing -> option (return mempty) tableCaption
@@ -1478,35 +1488,37 @@ inlines1 :: PandocMonad m => MarkdownParser m (F Inlines)
1478inlines1 = mconcat <$> many1 inline
1488inlines1 = mconcat <$> many1 inline
1479
1489
1480inline :: PandocMonad m => MarkdownParser m (F Inlines)
1490inline :: PandocMonad m => MarkdownParser m (F Inlines)
1481−inline = choice [ whitespace
1491+inline = do
1482− , bareURL
1492+ c <- lookAhead anyChar
1483− , str
1493+ ((case c of
1494+ ' ' -> whitespace
1495+ '\t' -> whitespace
1484− , endline
1496+ '\n' -> endline
1485− , code
1497+ '`' -> code
1486− , strongOrEmph
1498+ '_' -> strongOrEmph
1487− , note
1499+ '*' -> strongOrEmph
1488− , cite
1500+ '^' -> superscript <|> inlineNote -- in this order bc ^[link](/foo)^
1489− , bracketedSpan
1501+ '[' -> note <|> cite <|> bracketedSpan <|> link
1490− , link
1491− , image
1502+ '!' -> image
1492− , math
1503+ '$' -> math
1493− , strikeout
1504+ '~' -> strikeout <|> subscript
1494− , subscript
1495− , superscript
1496− , inlineNote -- after superscript because of ^[link](/foo)^
1497− , autoLink
1498− , spanHtml
1499− , rawHtmlInline
1505+ '<' -> autoLink <|> spanHtml <|> rawHtmlInline <|> ltSign
1500− , escapedNewline
1506+ '\\' -> escapedNewline <|> escapedChar <|> rawLaTeXInline'
1501− , escapedChar
1502− , rawLaTeXInline'
1503− , exampleRef
1507+ '@' -> exampleRef
1508+ '"' -> smart
1509+ '\'' -> smart
1510+ '\8216' -> smart
1511+ '\145' -> smart
1512+ '\8220' -> smart
1513+ '\147' -> smart
1504− , smart
1514+ '-' -> smart
1515+ '.' -> smart
1505− , return . B.singleton <$> charRef
1516+ '&' -> return . B.singleton <$> charRef
1506− , emoji
1517+ ':' -> emoji
1518+ _ -> mzero)
1519+ <|> bareURL
1520+ <|> str
1507− , symbol
1521+ <|> symbol) <?> "inline"
1508− , ltSign
1509− ] <?> "inline"
1510
1522
1511escapedChar' :: PandocMonad m => MarkdownParser m Char
1523escapedChar' :: PandocMonad m => MarkdownParser m Char
1512escapedChar' = try $ do
1524escapedChar' = try $ do
@@ -1517,11 +1529,12 @@ escapedChar' = try $ do
1517 <|> oneOf "\\`*_{}[]()>#+-.!~\""
1529 <|> oneOf "\\`*_{}[]()>#+-.!~\""
1518
1530
1519escapedNewline :: PandocMonad m => MarkdownParser m (F Inlines)
1531escapedNewline :: PandocMonad m => MarkdownParser m (F Inlines)
1520−escapedNewline = try $ do
1532+escapedNewline = do
1521 guardEnabled Ext_escaped_line_breaks
1533 guardEnabled Ext_escaped_line_breaks
1534+ try $ do
1522− char '\\'
1535+ char '\\'
1523− lookAhead (char '\n') -- don't consume the newline (see #3730)
1536+ lookAhead (char '\n') -- don't consume the newline (see #3730)
1524− return $ return B.linebreak
1537+ return $ return B.linebreak
1525
1538
1526escapedChar :: PandocMonad m => MarkdownParser m (F Inlines)
1539escapedChar :: PandocMonad m => MarkdownParser m (F Inlines)
1527escapedChar = do
1540escapedChar = do
@@ -1543,19 +1556,20 @@ ltSign = do
1543-- whole document has been parsed. But we need this parser
1556-- whole document has been parsed. But we need this parser
1544-- here in case citations is disabled.
1557-- here in case citations is disabled.
1545exampleRef :: PandocMonad m => MarkdownParser m (F Inlines)
1558exampleRef :: PandocMonad m => MarkdownParser m (F Inlines)
1546−exampleRef = try $ do
1559+exampleRef = do
1547 guardEnabled Ext_example_lists
1560 guardEnabled Ext_example_lists
1561+ try $ do
1548− char '@'
1562+ char '@'
1549− lab <- mconcat . map T.pack <$>
1563+ lab <- mconcat . map T.pack <$>
1550− many (many1 alphaNum <|>
1564+ many (many1 alphaNum <|>
1551− try (do c <- char '_' <|> char '-'
1565+ try (do c <- char '_' <|> char '-'
1552− cs <- many1 alphaNum
1566+ cs <- many1 alphaNum
1553− return (c:cs)))
1567+ return (c:cs)))
1554− return $ do
1568+ return $ do
1555− st <- askF
1569+ st <- askF
1556− return $ case M.lookup lab (stateExamples st) of
1570+ return $ case M.lookup lab (stateExamples st) of
1557− Just n -> B.str $ tshow n
1571+ Just n -> B.str $ tshow n
1558− Nothing -> B.str $ "@" <> lab
1572+ Nothing -> B.str $ "@" <> lab
1559
1573
1560symbol :: PandocMonad m => MarkdownParser m (F Inlines)
1574symbol :: PandocMonad m => MarkdownParser m (F Inlines)
1561symbol = do
1575symbol = do
@@ -1582,10 +1596,10 @@ code = try $ do
1582 >> count (length starts) (char '`')
1596 >> count (length starts) (char '`')
1583 >> notFollowedBy (char '`'))
1597 >> notFollowedBy (char '`'))
1584 rawattr <-
1598 rawattr <-
1585− (Left <$> try (guardEnabled Ext_raw_attribute >> rawAttribute))
1599+ (Left <$> (guardEnabled Ext_raw_attribute >> try rawAttribute))
1586 <|>
1600 <|>
1587 (Right <$> option ("",[],[])
1601 (Right <$> option ("",[],[])
1588− (try (guardEnabled Ext_inline_code_attributes >> attributes)))
1602+ (guardEnabled Ext_inline_code_attributes >> try attributes))
1589 return $ return $
1603 return $ return $
1590 case rawattr of
1604 case rawattr of
1591 Left syn -> B.rawInline syn result
1605 Left syn -> B.rawInline syn result
@@ -1678,20 +1692,22 @@ strikeout = fmap B.strikeout <$>
1678 strikeEnd = try $ string "~~"
1692 strikeEnd = try $ string "~~"
1679
1693
1680superscript :: PandocMonad m => MarkdownParser m (F Inlines)
1694superscript :: PandocMonad m => MarkdownParser m (F Inlines)
1681−superscript = fmap B.superscript <$> try (do
1695+superscript = do
1682 guardEnabled Ext_superscript
1696 guardEnabled Ext_superscript
1697+ fmap B.superscript <$> try (do
1683− char '^'
1698+ char '^'
1684− mconcat <$> many1Till (do notFollowedBy spaceChar
1699+ mconcat <$> many1Till (do notFollowedBy spaceChar
1685− notFollowedBy newline
1700+ notFollowedBy newline
1686− inline) (char '^'))
1701+ inline) (char '^'))
1687
1702
1688subscript :: PandocMonad m => MarkdownParser m (F Inlines)
1703subscript :: PandocMonad m => MarkdownParser m (F Inlines)
1689−subscript = fmap B.subscript <$> try (do
1704+subscript = do
1690 guardEnabled Ext_subscript
1705 guardEnabled Ext_subscript
1706+ fmap B.subscript <$> try (do
1691− char '~'
1707+ char '~'
1692− mconcat <$> many1Till (do notFollowedBy spaceChar
1708+ mconcat <$> many1Till (do notFollowedBy spaceChar
1693− notFollowedBy newline
1709+ notFollowedBy newline
1694− inline) (char '~'))
1710+ inline) (char '~'))
1695
1711
1696whitespace :: PandocMonad m => MarkdownParser m (F Inlines)
1712whitespace :: PandocMonad m => MarkdownParser m (F Inlines)
1697whitespace = spaceChar >> return <$> (lb <|> regsp) <?> "whitespace"
1713whitespace = spaceChar >> return <$> (lb <|> regsp) <?> "whitespace"
@@ -1792,15 +1808,16 @@ link = try $ do
1792 regLink B.linkWith lab <|> referenceLink B.linkWith (lab,raw)
1808 regLink B.linkWith lab <|> referenceLink B.linkWith (lab,raw)
1793
1809
1794bracketedSpan :: PandocMonad m => MarkdownParser m (F Inlines)
1810bracketedSpan :: PandocMonad m => MarkdownParser m (F Inlines)
1795−bracketedSpan = try $ do
1811+bracketedSpan = do
1796 guardEnabled Ext_bracketed_spans
1812 guardEnabled Ext_bracketed_spans
1813+ try $ do
1797− (lab,_) <- reference
1814+ (lab,_) <- reference
1798− attr <- attributes
1815+ attr <- attributes
1799− return $ if isSmallCaps attr
1816+ return $ if isSmallCaps attr
1800− then B.smallcaps <$> lab
1817+ then B.smallcaps <$> lab
1801− else if isUnderline attr
1818+ else if isUnderline attr
1802− then B.underline <$> lab
1819+ then B.underline <$> lab
1803− else B.spanWith attr <$> lab
1820+ else B.spanWith attr <$> lab
1804
1821
1805-- | We treat a span as SmallCaps if class is "smallcaps" (and
1822-- | We treat a span as SmallCaps if class is "smallcaps" (and
1806-- no other attributes are set or if style is "font-variant:small-caps"
1823-- no other attributes are set or if style is "font-variant:small-caps"
@@ -1879,12 +1896,13 @@ dropBrackets = dropRB . dropLB
1879 dropLB xs = xs
1896 dropLB xs = xs
1880
1897
1881bareURL :: PandocMonad m => MarkdownParser m (F Inlines)
1898bareURL :: PandocMonad m => MarkdownParser m (F Inlines)
1882−bareURL = try $ do
1899+bareURL = do
1883 guardEnabled Ext_autolink_bare_uris
1900 guardEnabled Ext_autolink_bare_uris
1884 getState >>= guard . stateAllowLinks
1901 getState >>= guard . stateAllowLinks
1902+ try $ do
1885− (cls, (orig, src)) <- (("uri",) <$> uri) <|> (("email",) <$> emailAddress)
1903+ (cls, (orig, src)) <- (("uri",) <$> uri) <|> (("email",) <$> emailAddress)
1886− notFollowedBy $ try $ spaces >> htmlTag (~== TagClose ("a" :: Text))
1904+ notFollowedBy $ try $ spaces >> htmlTag (~== TagClose ("a" :: Text))
1887− return $ return $ B.linkWith ("",[cls],[]) src "" (B.str orig)
1905+ return $ return $ B.linkWith ("",[cls],[]) src "" (B.str orig)
1888
1906
1889autoLink :: PandocMonad m => MarkdownParser m (F Inlines)
1907autoLink :: PandocMonad m => MarkdownParser m (F Inlines)
1890autoLink = try $ do
1908autoLink = try $ do
@@ -1937,21 +1955,23 @@ note = try $ do
1937 return $ B.note $ walk adjustCite contents'
1955 return $ B.note $ walk adjustCite contents'
1938
1956
1939inlineNote :: PandocMonad m => MarkdownParser m (F Inlines)
1957inlineNote :: PandocMonad m => MarkdownParser m (F Inlines)
1940−inlineNote = try $ do
1958+inlineNote = do
1941 guardEnabled Ext_inline_notes
1959 guardEnabled Ext_inline_notes
1960+ try $ do
1942− char '^'
1961+ char '^'
1943− updateState $ \st -> st{ stateInNote = True
1962+ updateState $ \st -> st{ stateInNote = True
1944− , stateNoteNumber = stateNoteNumber st + 1 }
1963+ , stateNoteNumber = stateNoteNumber st + 1 }
1945− contents <- inlinesInBalancedBrackets
1964+ contents <- inlinesInBalancedBrackets
1946− updateState $ \st -> st{ stateInNote = False }
1965+ updateState $ \st -> st{ stateInNote = False }
1947− return $ B.note . B.para <$> contents
1966+ return $ B.note . B.para <$> contents
1948
1967
1949rawLaTeXInline' :: PandocMonad m => MarkdownParser m (F Inlines)
1968rawLaTeXInline' :: PandocMonad m => MarkdownParser m (F Inlines)
1950−rawLaTeXInline' = try $ do
1969+rawLaTeXInline' = do
1951 guardEnabled Ext_raw_tex
1970 guardEnabled Ext_raw_tex
1952 notFollowedBy' rawConTeXtEnvironment
1971 notFollowedBy' rawConTeXtEnvironment
1972+ try $ do
1953− s <- rawLaTeXInline
1973+ s <- rawLaTeXInline
1954− return $ return $ B.rawInline "tex" s -- "tex" because it might be context
1974+ return $ return $ B.rawInline "tex" s -- "tex" because it might be context
1955
1975
1956rawConTeXtEnvironment :: PandocMonad m => ParserT Text st m Text
1976rawConTeXtEnvironment :: PandocMonad m => ParserT Text st m Text
1957rawConTeXtEnvironment = try $ do
1977rawConTeXtEnvironment = try $ do
@@ -1970,55 +1990,60 @@ inBrackets parser = do
1970 return $ "[" <> contents <> "]"
1990 return $ "[" <> contents <> "]"
1971
1991
1972spanHtml :: PandocMonad m => MarkdownParser m (F Inlines)
1992spanHtml :: PandocMonad m => MarkdownParser m (F Inlines)
1973−spanHtml = try $ do
1993+spanHtml = do
1974 guardEnabled Ext_native_spans
1994 guardEnabled Ext_native_spans
1995+ try $ do
1975− (TagOpen _ attrs, _) <- htmlTag (~== TagOpen ("span" :: Text) [])
1996+ (TagOpen _ attrs, _) <- htmlTag (~== TagOpen ("span" :: Text) [])
1976− contents <- mconcat <$> manyTill inline (htmlTag (~== TagClose ("span" :: Text)))
1997+ contents <- mconcat <$> manyTill inline (htmlTag (~== TagClose ("span" :: Text)))
1977− let ident = fromMaybe "" $ lookup "id" attrs
1998+ let ident = fromMaybe "" $ lookup "id" attrs
1978− let classes = maybe [] T.words $ lookup "class" attrs
1999+ let classes = maybe [] T.words $ lookup "class" attrs
1979− let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]
2000+ let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]
1980− return $ if isSmallCaps (ident, classes, keyvals)
2001+ return $ if isSmallCaps (ident, classes, keyvals)
1981− then B.smallcaps <$> contents
2002+ then B.smallcaps <$> contents
1982− else if isUnderline (ident, classes, keyvals)
2003+ else if isUnderline (ident, classes, keyvals)
1983− then B.underline <$> contents
2004+ then B.underline <$> contents
1984− else B.spanWith (ident, classes, keyvals) <$> contents
2005+ else B.spanWith (ident, classes, keyvals) <$> contents
1985
2006
1986divHtml :: PandocMonad m => MarkdownParser m (F Blocks)
2007divHtml :: PandocMonad m => MarkdownParser m (F Blocks)
1987−divHtml = try $ do
2008+divHtml = do
1988 guardEnabled Ext_native_divs
2009 guardEnabled Ext_native_divs
2010+ try $ do
1989− (TagOpen _ attrs, rawtag) <- htmlTag (~== TagOpen ("div" :: Text) [])
2011+ (TagOpen _ attrs, rawtag) <- htmlTag (~== TagOpen ("div" :: Text) [])
1990− -- we set stateInHtmlBlock so that closing tags that can be either block or
2012+ -- we set stateInHtmlBlock so that closing tags that can be either block
1991− -- inline will not be parsed as inline tags
2013+ -- or inline will not be parsed as inline tags
1992− oldInHtmlBlock <- stateInHtmlBlock <$> getState
2014+ oldInHtmlBlock <- stateInHtmlBlock <$> getState
1993− updateState $ \st -> st{ stateInHtmlBlock = Just "div" }
2015+ updateState $ \st -> st{ stateInHtmlBlock = Just "div" }
1994− bls <- option "" (blankline >> option "" blanklines)
2016+ bls <- option "" (blankline >> option "" blanklines)
1995− contents <- mconcat <$>
2017+ contents <- mconcat <$>
1996− many (notFollowedBy' (htmlTag (~== TagClose ("div" :: Text))) >> block)
2018+ many (notFollowedBy' (htmlTag (~== TagClose ("div" :: Text))) >> block)
1997− closed <- option False (True <$ htmlTag (~== TagClose ("div" :: Text)))
2019+ closed <- option False (True <$ htmlTag (~== TagClose ("div" :: Text)))
1998− if closed
2020+ if closed
1999− then do
2021+ then do
2000− updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }
2022+ updateState $ \st -> st{ stateInHtmlBlock = oldInHtmlBlock }
2001− let ident = fromMaybe "" $ lookup "id" attrs
2023+ let ident = fromMaybe "" $ lookup "id" attrs
2002− let classes = maybe [] T.words $ lookup "class" attrs
2024+ let classes = maybe [] T.words $ lookup "class" attrs
2003− let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]
2025+ let keyvals = [(k,v) | (k,v) <- attrs, k /= "id" && k /= "class"]
2004− return $ B.divWith (ident, classes, keyvals) <$> contents
2026+ return $ B.divWith (ident, classes, keyvals) <$> contents
2005− else -- avoid backtracing
2027+ else -- avoid backtracing
2006− return $ return (B.rawBlock "html" (rawtag <> bls)) <> contents
2028+ return $ return (B.rawBlock "html" (rawtag <> bls)) <> contents
2007
2029
2008divFenced :: PandocMonad m => MarkdownParser m (F Blocks)
2030divFenced :: PandocMonad m => MarkdownParser m (F Blocks)
2009−divFenced = try $ do
2031+divFenced = do
2010 guardEnabled Ext_fenced_divs
2032 guardEnabled Ext_fenced_divs
2033+ try $ do
2011− string ":::"
2034+ string ":::"
2012− skipMany (char ':')
2035+ skipMany (char ':')
2013− skipMany spaceChar
2036+ skipMany spaceChar
2014− attribs <- attributes <|> ((\x -> ("",[x],[])) <$> many1Char nonspaceChar)
2037+ attribs <- attributes <|> ((\x -> ("",[x],[])) <$> many1Char nonspaceChar)
2015− skipMany spaceChar
2038+ skipMany spaceChar
2016− skipMany (char ':')
2039+ skipMany (char ':')
2017− blankline
2040+ blankline
2041+ updateState $ \st ->
2018− updateState $ \st -> st{ stateFencedDivLevel = stateFencedDivLevel st + 1 }
2042+ st{ stateFencedDivLevel = stateFencedDivLevel st + 1 }
2019− bs <- mconcat <$> manyTill block divFenceEnd
2043+ bs <- mconcat <$> manyTill block divFenceEnd
2044+ updateState $ \st ->
2020− updateState $ \st -> st{ stateFencedDivLevel = stateFencedDivLevel st - 1 }
2045+ st{ stateFencedDivLevel = stateFencedDivLevel st - 1 }
2021− return $ B.divWith attribs <$> bs
2046+ return $ B.divWith attribs <$> bs
2022
2047
2023divFenceEnd :: PandocMonad m => MarkdownParser m ()
2048divFenceEnd :: PandocMonad m => MarkdownParser m ()
2024divFenceEnd = try $ do
2049divFenceEnd = try $ do
@@ -2050,14 +2075,15 @@ emojiChars :: [Char]
2050emojiChars = ['a'..'z'] ++ ['0'..'9'] ++ ['_','+','-']
2075emojiChars = ['a'..'z'] ++ ['0'..'9'] ++ ['_','+','-']
2051
2076
2052emoji :: PandocMonad m => MarkdownParser m (F Inlines)
2077emoji :: PandocMonad m => MarkdownParser m (F Inlines)
2053−emoji = try $ do
2078+emoji = do
2054 guardEnabled Ext_emoji
2079 guardEnabled Ext_emoji
2080+ try $ do
2055− char ':'
2081+ char ':'
2056− emojikey <- many1Char (oneOf emojiChars)
2082+ emojikey <- many1Char (oneOf emojiChars)
2057− char ':'
2083+ char ':'
2058− case emojiToInline emojikey of
2084+ case emojiToInline emojikey of
2059− Just i -> return (return $ B.singleton i)
2085+ Just i -> return (return $ B.singleton i)
2060− Nothing -> mzero
2086+ Nothing -> mzero
2061
2087
2062-- Citations
2088-- Citations
2063
2089