git.iko.soy/typeable/pandoc
on master help sign in
Added literate haskell support for markdown reader.
42ba781fiddlosopher
Main.hs+24−9
@@ -146,6 +146,7 @@ data Opt = Opt
146 , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst
146 , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst
147 , optWrapText :: Bool -- ^ Wrap text
147 , optWrapText :: Bool -- ^ Wrap text
148 , optSanitizeHTML :: Bool -- ^ Sanitize HTML
148 , optSanitizeHTML :: Bool -- ^ Sanitize HTML
149+ , optLHSIn :: Bool -- ^ Treat input as literate haskell
149#ifdef _CITEPROC
150#ifdef _CITEPROC
150 , optModsFile :: String
151 , optModsFile :: String
151 , optCslFile :: String
152 , optCslFile :: String
@@ -179,6 +180,7 @@ defaultOpts = Opt
179 , optReferenceLinks = False
180 , optReferenceLinks = False
180 , optWrapText = True
181 , optWrapText = True
181 , optSanitizeHTML = False
182 , optSanitizeHTML = False
183+ , optLHSIn = False
182#ifdef _CITEPROC
184#ifdef _CITEPROC
183 , optModsFile = []
185 , optModsFile = []
184 , optCslFile = []
186 , optCslFile = []
@@ -288,6 +290,11 @@ options =
288 (\opt -> return opt { optSanitizeHTML = True }))
290 (\opt -> return opt { optSanitizeHTML = True }))
289 "" -- "Sanitize HTML"
291 "" -- "Sanitize HTML"
290
292
293+ , Option "" ["lhs-in"]
294+ (NoArg
295+ (\opt -> return opt { optLHSIn = True }))
296+ "" -- "Treat input as literate haskell"
297+
291 , Option "" ["toc", "table-of-contents"]
298 , Option "" ["toc", "table-of-contents"]
292 (NoArg
299 (NoArg
293 (\opt -> return opt { optTableOfContents = True }))
300 (\opt -> return opt { optTableOfContents = True }))
@@ -419,6 +426,11 @@ defaultReaderName (x:xs) =
419 ".native" -> "native"
426 ".native" -> "native"
420 _ -> defaultReaderName xs
427 _ -> defaultReaderName xs
421
428
429+-- Returns True if extension of first source is .lhs
430+lhsExtension :: [FilePath] -> Bool
431+lhsExtension (x:_) = takeExtension x == ".lhs"
432+lhsExtension _ = False
433+
422-- Determine default writer based on output file extension
434-- Determine default writer based on output file extension
423defaultWriterName :: FilePath -> String
435defaultWriterName :: FilePath -> String
424defaultWriterName "-" = "html" -- no output file
436defaultWriterName "-" = "html" -- no output file
@@ -498,6 +510,7 @@ main = do
498 , optReferenceLinks = referenceLinks
510 , optReferenceLinks = referenceLinks
499 , optWrapText = wrap
511 , optWrapText = wrap
500 , optSanitizeHTML = sanitize
512 , optSanitizeHTML = sanitize
513+ , optLHSIn = lhsIn
501#ifdef _CITEPROC
514#ifdef _CITEPROC
502 , optModsFile = modsFile
515 , optModsFile = modsFile
503 , optCslFile = cslFile
516 , optCslFile = cslFile
@@ -556,17 +569,19 @@ main = do
556#endif
569#endif
557
570
558 let startParserState =
571 let startParserState =
559− defaultParserState { stateParseRaw = parseRaw,
572+ defaultParserState { stateParseRaw = parseRaw,
560− stateTabStop = tabStop,
573+ stateTabStop = tabStop,
561− stateSanitizeHTML = sanitize,
574+ stateSanitizeHTML = sanitize,
575+ stateLiterateHaskell = lhsIn ||
576+ lhsExtension sources,
562− stateStandalone = standalone',
577+ stateStandalone = standalone',
563#ifdef _CITEPROC
578#ifdef _CITEPROC
564− stateCitations = map citeKey refs,
579+ stateCitations = map citeKey refs,
565#endif
580#endif
566− stateSmart = smart || writerName' `elem`
581+ stateSmart = smart || writerName' `elem`
567− ["latex", "context"],
582+ ["latex", "context"],
568− stateColumns = columns,
583+ stateColumns = columns,
569− stateStrict = strict }
584+ stateStrict = strict }
570 let csslink = if null css
585 let csslink = if null css
571 then ""
586 then ""
572 else concatMap
587 else concatMap
Text/Pandoc/Readers/Markdown.hs+27
@@ -45,6 +45,7 @@ import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag,
45 htmlBlockElement, unsanitaryURI )
45 htmlBlockElement, unsanitaryURI )
46import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
46import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
47import Text.ParserCombinators.Parsec
47import Text.ParserCombinators.Parsec
48+import Control.Monad (when)
48
49
49-- | Read markdown from an input string and return a Pandoc document.
50-- | Read markdown from an input string and return a Pandoc document.
50readMarkdown :: ParserState -> String -> Pandoc
51readMarkdown :: ParserState -> String -> Pandoc
@@ -102,6 +103,12 @@ failUnlessSmart = do
102 state <- getState
103 state <- getState
103 if stateSmart state then return () else fail "Smart typography feature"
104 if stateSmart state then return () else fail "Smart typography feature"
104
105
106+-- | Fail unless we're in literate haskell mode.
107+failUnlessLHS :: GenParser tok ParserState ()
108+failUnlessLHS = do
109+ state <- getState
110+ if stateLiterateHaskell state then return () else fail "Literate haskell feature"
111+
105-- | Parse a sequence of inline elements between square brackets,
112-- | Parse a sequence of inline elements between square brackets,
106-- including inlines between balanced pairs of square brackets.
113-- including inlines between balanced pairs of square brackets.
107inlinesInBalancedBrackets :: GenParser Char ParserState Inline
114inlinesInBalancedBrackets :: GenParser Char ParserState Inline
@@ -268,6 +275,7 @@ block = do
268 , header
275 , header
269 , table
276 , table
270 , codeBlockIndented
277 , codeBlockIndented
278+ , lhsCodeBlock
271 , blockQuote
279 , blockQuote
272 , hrule
280 , hrule
273 , bulletList
281 , bulletList
@@ -393,6 +401,25 @@ codeBlockIndented = do
393 optional blanklines
401 optional blanklines
394 return $ CodeBlock ("",[],[]) $ stripTrailingNewlines $ concat contents
402 return $ CodeBlock ("",[],[]) $ stripTrailingNewlines $ concat contents
395
403
404+lhsCodeBlock :: GenParser Char ParserState Block
405+lhsCodeBlock = do
406+ failUnlessLHS
407+ pos <- getPosition
408+ when (sourceColumn pos /= 1) $ fail "Not in first column"
409+ lns <- many1 birdTrackLine
410+ -- if (as is normal) there is always a space after >, drop it
411+ let lns' = if all (\ln -> null ln || take 1 ln == " ") lns
412+ then map (drop 1) lns
413+ else lns
414+ blanklines
415+ return $ CodeBlock ("",["haskell"],[]) $ intercalate "\n" lns'
416+
417+birdTrackLine :: GenParser Char st [Char]
418+birdTrackLine = do
419+ char '>'
420+ manyTill anyChar newline
421+
422+
396--
423--
397-- block quotes
424-- block quotes
398--
425--
Text/Pandoc/Shared.hs+2
@@ -635,6 +635,7 @@ data ParserState = ParserState
635 stateDate :: String, -- ^ Date of document
635 stateDate :: String, -- ^ Date of document
636 stateStrict :: Bool, -- ^ Use strict markdown syntax?
636 stateStrict :: Bool, -- ^ Use strict markdown syntax?
637 stateSmart :: Bool, -- ^ Use smart typography?
637 stateSmart :: Bool, -- ^ Use smart typography?
638+ stateLiterateHaskell :: Bool, -- ^ Treat input as literate haskell
638 stateColumns :: Int, -- ^ Number of columns in terminal
639 stateColumns :: Int, -- ^ Number of columns in terminal
639 stateHeaderTable :: [HeaderType] -- ^ Ordered list of header types used
640 stateHeaderTable :: [HeaderType] -- ^ Ordered list of header types used
640 }
641 }
@@ -658,6 +659,7 @@ defaultParserState =
658 stateDate = [],
659 stateDate = [],
659 stateStrict = False,
660 stateStrict = False,
660 stateSmart = False,
661 stateSmart = False,
662+ stateLiterateHaskell = False,
661 stateColumns = 80,
663 stateColumns = 80,
662 stateHeaderTable = [] }
664 stateHeaderTable = [] }
663
665