module PanPipe where import Control.Applicative import Data.List import System.Exit import System.IO import System.IO.Temp (withSystemTempDirectory) import System.Posix import System.Process import Text.Pandoc import Text.Pandoc.JSON (toJSONFilter) import Text.Pandoc.Shared (inDirectory) import Text.Pandoc.Walk (walkM) pipeBWith :: (Functor m, Monad m) => (String -> String -> m String) -> Block -> m Block pipeBWith f (CodeBlock as s) | Just (as', p) <- partPipes as = CodeBlock as' <$> f p s pipeBWith f x = walkM (pipeIWith f) x pipeB = pipeBWith readShell pipeIWith :: (Functor m, Monad m) => (String -> String -> m String) -> Inline -> m Inline pipeIWith f (Code as s) | Just (as', p) <- partPipes as = Code as' <$> f p s pipeIWith f x = return x pipeI = pipeIWith readShell readShell :: FilePath -> String -> IO String readShell p = readProcess "sh" ["-c", p] partPipes :: Attr -> Maybe (Attr, String) partPipes (x, y, zs) = case partition (("pipe" ==) . fst) zs of ((_, p):_, zs') -> Just ((x, y, zs'), p) _ -> Nothing transform :: Pandoc -> IO Pandoc transform doc = do cwd <-getWorkingDirectory withSystemTempDirectory "panpipe" (\dir -> do createSymbolicLink cwd (dir ++ "/root") inDirectory dir (transformDoc doc)) transformDoc :: Pandoc -> IO Pandoc transformDoc = walkM pipeB panpipeMain = toJSONFilter transform