pandoc-include-code 0.2.0 → 0.3.0
raw patch · 2 files changed
+54/−39 lines, 2 files
Files
- pandoc-include-code.cabal +1/−1
- src/Main.hs +53/−38
pandoc-include-code.cabal view
@@ -8,7 +8,7 @@ author: Oskar Wickström maintainer: Oskar Wickström homepage: https://github.com/owickstrom/pandoc-include-code-version: 0.2.0+version: 0.3.0 cabal-version: >= 1.8 build-type: Simple category: Documentation
src/Main.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE QuasiQuotes #-}+ module Main where import qualified Data.Map as Map@@ -19,46 +20,51 @@ escapeForLatex :: IsEscaped -> String -> String escapeForLatex isEscaped = concatMap escape where- escape '$' = if isEscaped then "\\$" else "$"- escape c = [c]+ escape '$' =+ if isEscaped+ then "\\$"+ else "$"+ escape c = [c] replaceDashWithLatex :: IsEscaped -> String -> String replaceDashWithLatex isEscaped = gsub ([re|(\--)|]) toLatex where- toLatex ("--":_) = encloseInListingEscape isEscaped "-{}-"- toLatex _ = ""+ toLatex ("--":_) = encloseInListingEscape isEscaped "-{}-"+ toLatex _ = "" replaceTagWithLatex :: IsEscaped -> String -> String replaceTagWithLatex isEscaped s = foldl replaceWith s replacements where- replacements = [ ([re|<strong>(.*?)</strong>|], "\\texttt{\\textbf{", "}}")- , ([re|<em>(.*?)</em>|], "\\texttt{\\textit{", "}}")- , ([re|<sub>(.*?)</sub>|], "\\textsubscript{", "}")- ]- replaceWith s' (r, pre, post) = gsub r (toLatex pre post) s'- toLatex pre post (contents:_) =- let replacedContents = replaceWithLatex True contents- command = pre ++ replacedContents ++ post- in encloseInListingEscape isEscaped command- toLatex _ _ [] = ""+ replacements =+ [ ([re|<strong>(.*?)</strong>|], "\\texttt{\\textbf{", "}}")+ , ([re|<em>(.*?)</em>|], "\\texttt{\\textit{", "}}")+ , ([re|<sub>(.*?)</sub>|], "\\textsubscript{", "}")+ ]+ replaceWith s' (r, pre, post) = gsub r (toLatex pre post) s'+ toLatex pre post (contents:_) =+ let replacedContents = replaceWithLatex True contents+ command = pre ++ replacedContents ++ post+ in encloseInListingEscape isEscaped command+ toLatex _ _ [] = "" replaceWithLatex :: Bool -> String -> String replaceWithLatex isEscaped =- replaceDashWithLatex isEscaped . replaceTagWithLatex isEscaped . escapeForLatex isEscaped+ replaceDashWithLatex isEscaped .+ replaceTagWithLatex isEscaped . escapeForLatex isEscaped postProcess :: Format -> String -> String postProcess fmt contents- | fmt == Format "latex" = unlines $ map (replaceWithLatex False) $ lines contents+ | fmt == Format "latex" =+ unlines $ map (replaceWithLatex False) $ lines contents | otherwise = contents -getRange :: Map.Map String String- -> Maybe (Int, Int)+getRange :: Map.Map String String -> Maybe (Int, Int) getRange attrs = do start <- Map.lookup "startLine" attrs >>= readMaybe end <- Map.lookup "endLine" attrs >>= readMaybe if start <= end- then return (start, end)- else Nothing+ then return (start, end)+ else Nothing withinLines :: Maybe (Int, Int) -> String -> String withinLines range =@@ -66,38 +72,47 @@ Just (start, end) -> unlines . take (end - startIndex) . drop startIndex . lines where startIndex = pred start- Nothing ->- id+ Nothing -> id onlySnippet :: Map.Map String String -> String -> String onlySnippet attrs = case Map.lookup "snippet" attrs of Just name ->- unlines . takeWhile (not . isSnippetEnd) . drop 1 . dropWhile (not . isSnippetStart) . lines- where- isSnippetTag tag line = (tag ++ " snippet " ++ name) `isInfixOf` line- isSnippetStart = isSnippetTag "start"- isSnippetEnd = isSnippetTag "end"- Nothing ->- id+ unlines .+ takeWhile (not . isSnippetEnd) .+ drop 1 . dropWhile (not . isSnippetStart) . lines+ where isSnippetTag tag line =+ (tag ++ " snippet " ++ name) `isInfixOf` line+ isSnippetStart = isSnippetTag "start"+ isSnippetEnd = isSnippetTag "end"+ Nothing -> id includeCode :: Maybe Format -> Block -> IO Block includeCode (Just fmt) cb@(CodeBlock (id', classes, attrs) _) = do let attrs' = Map.fromList attrs case Map.lookup "include" attrs' of Just f -> do- fileContents <- if "formatted" `Map.member` attrs'- then postProcess fmt <$> readFile f- else readFile f- let filteredLines = fileContents- & withinLines (getRange attrs')- & onlySnippet attrs'- paramNames = ["include", "formatted", "startLine", "endLine", "snippet"]+ let isFormatted = "formatted" `Map.member` attrs'+ fileContents <-+ if isFormatted+ then postProcess fmt <$> readFile f+ else readFile f+ let filteredLines =+ fileContents & withinLines (getRange attrs') & onlySnippet attrs'+ paramNames =+ ["include", "formatted", "startLine", "endLine", "snippet"] filteredAttrs = foldl (flip Map.delete) attrs' paramNames classes' = unwords classes case fmt of- (Format "html5") -> return (RawBlock (Format "html") ("<pre class=" ++ classes' ++ "><code>" ++ filteredLines ++ "</code></pre>"))- _ -> return (CodeBlock (id', classes, Map.toList filteredAttrs) filteredLines)+ Format "html5" | isFormatted ->+ return+ (RawBlock+ (Format "html")+ ("<pre class=" +++ classes' ++ "><code>" ++ filteredLines ++ "</code></pre>"))+ _ ->+ return+ (CodeBlock (id', classes, Map.toList filteredAttrs) filteredLines) Nothing -> return cb includeCode _ x = return x