git.iko.soy/typeable/pandoc
on master help sign in
Implemented Ext_backtick_code_blocks.
dc8e597John MacFarlane
src/Text/Pandoc/Options.hs+2
@@ -66,6 +66,7 @@ data Extension =
66 | Ext_latex_macros -- ^ Parse LaTeX macro definitions (for math only)
66 | Ext_latex_macros -- ^ Parse LaTeX macro definitions (for math only)
67 | Ext_fenced_code_blocks -- ^ Parse fenced code blocks
67 | Ext_fenced_code_blocks -- ^ Parse fenced code blocks
68 | Ext_fenced_code_attributes -- ^ Allow attributes on fenced code blocks
68 | Ext_fenced_code_attributes -- ^ Allow attributes on fenced code blocks
69+ | Ext_backtick_code_blocks -- ^ Github style ``` code blocks
69 | Ext_inline_code_attributes -- ^ Allow attributes on inline code
70 | Ext_inline_code_attributes -- ^ Allow attributes on inline code
70 | Ext_markdown_in_html_blocks -- ^ Interpret as markdown inside HTML blocks
71 | Ext_markdown_in_html_blocks -- ^ Interpret as markdown inside HTML blocks
71 | Ext_markdown_attribute -- ^ Interpret text inside HTML as markdown
72 | Ext_markdown_attribute -- ^ Interpret text inside HTML as markdown
@@ -107,6 +108,7 @@ pandocExtensions = Set.fromList
107 , Ext_latex_macros
108 , Ext_latex_macros
108 , Ext_fenced_code_blocks
109 , Ext_fenced_code_blocks
109 , Ext_fenced_code_attributes
110 , Ext_fenced_code_attributes
111+ , Ext_backtick_code_blocks
110 , Ext_inline_code_attributes
112 , Ext_inline_code_attributes
111 , Ext_markdown_in_html_blocks
113 , Ext_markdown_in_html_blocks
112 , Ext_escaped_line_breaks
114 , Ext_escaped_line_breaks
src/Text/Pandoc/Readers/Markdown.hs+23−15
@@ -307,6 +307,7 @@ parseBlocks = mconcat <$> manyTill block eof
307
307
308block :: Parser [Char] ParserState (F Blocks)
308block :: Parser [Char] ParserState (F Blocks)
309block = choice [ codeBlockFenced
309block = choice [ codeBlockFenced
310+ , codeBlockBackticks
310 , guardEnabled Ext_latex_macros *> (mempty <$ macro)
311 , guardEnabled Ext_latex_macros *> (mempty <$ macro)
311 , header
312 , header
312 , rawTeXBlock
313 , rawTeXBlock
@@ -379,21 +380,13 @@ indentedLine = indentSpaces >> manyTill anyChar newline >>= return . (++ "\n")
379
380
380blockDelimiter :: (Char -> Bool)
381blockDelimiter :: (Char -> Bool)
381 -> Maybe Int
382 -> Maybe Int
382− -> Parser [Char] ParserState (Int, (String, [String], [(String, String)]), Char)
383+ -> Parser [Char] st Int
383blockDelimiter f len = try $ do
384blockDelimiter f len = try $ do
384 c <- lookAhead (satisfy f)
385 c <- lookAhead (satisfy f)
385− size <- case len of
386+ case len of
386− Just l -> count l (char c) >> many (char c) >> return l
387+ Just l -> count l (char c) >> many (char c) >> return l
387− Nothing -> count 3 (char c) >> many (char c) >>=
388+ Nothing -> count 3 (char c) >> many (char c) >>=
388− return . (+ 3) . length
389+ return . (+ 3) . length
389− many spaceChar
390− attr <- option ([],[],[]) $ do
391− guardEnabled Ext_fenced_code_attributes
392− attributes -- ~~~ {.ruby}
393− <|> (many1 alphaNum >>= \x ->
394− return ([],[x],[])) -- github variant ```ruby
395− blankline
396− return (size, attr, c)
397
390
398attributes :: Parser [Char] st (String, [String], [(String, String)])
391attributes :: Parser [Char] st (String, [String], [(String, String)])
399attributes = try $ do
392attributes = try $ do
@@ -440,11 +433,26 @@ keyValAttr = try $ do
440codeBlockFenced :: Parser [Char] ParserState (F Blocks)
433codeBlockFenced :: Parser [Char] ParserState (F Blocks)
441codeBlockFenced = try $ do
434codeBlockFenced = try $ do
442 guardEnabled Ext_fenced_code_blocks
435 guardEnabled Ext_fenced_code_blocks
443− (size, attr, c) <- blockDelimiter (\c -> c == '~' || c == '`') Nothing
436+ size <- blockDelimiter (=='~') Nothing
437+ skipMany spaceChar
438+ attr <- option ([],[],[]) $
439+ guardEnabled Ext_fenced_code_attributes >> attributes
440+ blankline
444− contents <- manyTill anyLine (blockDelimiter (== c) (Just size))
441+ contents <- manyTill anyLine (blockDelimiter (=='~') (Just size))
445 blanklines
442 blanklines
446 return $ return $ B.codeBlockWith attr $ intercalate "\n" contents
443 return $ return $ B.codeBlockWith attr $ intercalate "\n" contents
447
444
445+codeBlockBackticks :: Parser [Char] ParserState (F Blocks)
446+codeBlockBackticks = try $ do
447+ guardEnabled Ext_backtick_code_blocks
448+ blockDelimiter (=='`') (Just 3)
449+ skipMany spaceChar
450+ cls <- many1 alphaNum
451+ blankline
452+ contents <- manyTill anyLine $ blockDelimiter (=='`') (Just 3)
453+ blanklines
454+ return $ return $ B.codeBlockWith ("",[cls],[]) $ intercalate "\n" contents
455+
448codeBlockIndented :: Parser [Char] ParserState (F Blocks)
456codeBlockIndented :: Parser [Char] ParserState (F Blocks)
449codeBlockIndented = do
457codeBlockIndented = do
450 contents <- many1 (indentedLine <|>
458 contents <- many1 (indentedLine <|>
src/Text/Pandoc/Writers/Markdown.hs+14−6
@@ -292,12 +292,20 @@ blockToMarkdown opts (CodeBlock (_,classes,_) str)
292 isEnabled Ext_literate_haskell opts =
292 isEnabled Ext_literate_haskell opts =
293 return $ prefixed "> " (text str) <> blankline
293 return $ prefixed "> " (text str) <> blankline
294blockToMarkdown opts (CodeBlock attribs str) = return $
294blockToMarkdown opts (CodeBlock attribs str) = return $
295− if isEnabled Ext_fenced_code_blocks opts && attribs /= nullAttr
295+ case attribs of
296− then -- use fenced code block
296+ x | x /= nullAttr && isEnabled Ext_fenced_code_blocks opts ->
297− (tildes <> space <> attrs <> cr <> text str <>
297+ tildes <> space <> attrs <> cr <> text str <>
298+ cr <> tildes <> blankline
299+ (_,(cls:_),_) | isEnabled Ext_backtick_code_blocks opts ->
300+ backticks <> space <> text cls <> cr <> text str <>
298− cr <> tildes) <> blankline
301+ cr <> backticks <> blankline
299− else nest (writerTabStop opts) (text str) <> blankline
302+ _ -> nest (writerTabStop opts) (text str) <> blankline
300− where tildes = text "~~~~"
303+ where tildes = text $ case [ln | ln <- lines str, all (=='~') ln] of
304+ [] -> "~~~~"
305+ xs -> case maximum $ map length xs of
306+ n | n < 3 -> "~~~~"
307+ | otherwise -> replicate (n+1) '~'
308+ backticks = text "```"
301 attrs = if isEnabled Ext_fenced_code_attributes opts
309 attrs = if isEnabled Ext_fenced_code_attributes opts
302 then attrsToMarkdown attribs
310 then attrsToMarkdown attribs
303 else empty
311 else empty