R-pandoc (empty) → 0.1
raw patch · 6 files changed
+214/−0 lines, 6 filesdep +R-pandocdep +basedep +directorysetup-changed
Dependencies added: R-pandoc, base, directory, filepath, pandoc-types, process, split
Files
- LICENSE +30/−0
- R-pandoc.cabal +40/−0
- README.md +59/−0
- Setup.hs +2/−0
- src/Main.hs +5/−0
- src/Text/Pandoc/R.hs +78/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2015 Corentin Dupont++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Brent Yorgey nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ R-pandoc.cabal view
@@ -0,0 +1,40 @@+name: R-pandoc+version: 0.1+cabal-version: >=1.10+build-type: Simple+license: BSD3+license-file: LICENSE+maintainer: corentin.dupont@gmail.com+bug-reports: http://github.com/cdupont/R-pandoc/issues+synopsis: A pandoc filter to express R plots inside markdown+category: Text+author: Corentin Dupont+extra-source-files: README.md++source-repository head+ type: git+ location: http://github.com/cdupont/R-pandoc.git++library+ build-depends:+ base >=4.6 && <4.9,+ pandoc-types >=1.12 && <1.13,+ directory >=1.2 && <1.3,+ filepath >=1.3 && <1.5,+ process >=1.2 && <1.3,+ split >=0.2 && <0.3+ exposed-modules: Text.Pandoc.R+ exposed: True+ buildable: True+ default-language: Haskell2010+ hs-source-dirs: src+ ghc-options: -Wall++executable R-pandoc+ build-depends:+ base >=4.6 && <4.9,+ pandoc-types >=1.12 && <1.13,+ R-pandoc ==0.1+ main-is: src/Main.hs+ buildable: True+ default-language: Haskell2010
+ README.md view
@@ -0,0 +1,59 @@++Please note that this repo is work in progress.++[](https://travis-ci.org/cdupont/R-pandoc)++A [pandoc](http://johnmacfarlane.net/pandoc/) filter to embbed R plots inside markdown documents.++## Usage++Install R:++ sudo apt-get install r-base+++Create a file called `demo.md` with the following text:++``` markdown+Here is a nice plot:+ ~~~ {.Rplot}+ require(stats)+ D = 150+ T = 10+ t = seq(0, 80, 0.01)+ x = -D*exp(-(t/T))+D+ v = (D/T)*exp(-(t/T))+ plot(t, x, type="l", main="position through time", xlab="time (s)", ylab="position (m)", xlim=c(0,80), ylim=c(0, D+10), xaxs = "i", yaxs = "i")+ ~~~+```++Now run:+``` shell+ pandoc -t html demo.md --filter R-pandoc -o demo.html -s+```++The file demo.html should now have a nice plot included:+++++## Details++`R-pandoc` compiles code blocks containing R plots+and includes the resulting images in the pandoc markup. It is meant+to be run as a+[pandoc filter](http://johnmacfarlane.net/pandoc/scripting.html) as+shown above.++`R-pandoc` is aware of two code block classes. A block with+the `Rplot` class will be replaced by the resulting plot---the code+will not appear in the output. ++## Installing+++``` shell+ git clone https://github.com/cdupont/R-pandoc.git+ cd R-pandoc+ cabal install+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Main.hs view
@@ -0,0 +1,5 @@+import Text.Pandoc.JSON+import Text.Pandoc.R++main :: IO ()+main = toJSONFilter (insertRplots "plots")
+ src/Text/Pandoc/R.hs view
@@ -0,0 +1,78 @@+++module Text.Pandoc.R where++import Control.Applicative+import Control.Monad+import Data.List (delete)+import Data.List.Split+import Data.Maybe+import System.Directory (createDirectoryIfMissing, doesFileExist, removeFile, renameFile)+import System.Exit (ExitCode (..))+import System.FilePath ((<.>), (</>), pathSeparator)+import System.IO (hPutStrLn, stderr)+import System.Process+import Text.Pandoc.Generic+import Text.Pandoc.JSON++rClass, fileAttr, defFile, defRplot, tmpRFile :: String+rClass = "Rplot"+fileAttr = "files"+defFile = "Rplot.png"+defRplot = "Rplots.pdf"+tmpRFile = "plot.R"++renderRPandoc :: FilePath -> Pandoc -> IO Pandoc+renderRPandoc f p = bottomUpM (insertRplots f) p++insertRplots :: FilePath -> Block -> IO Block+insertRplots outDir block@(CodeBlock (ident, classes, attrs) code) = do+ --hPutStrLn stderr $ "insertRplots classes: " ++ (show classes) ++ " attrs: " ++ (show attrs) ++ " ident: " ++ (show ident)+ if rClass `elem` classes then do+ let imgFiles = case lookup fileAttr attrs of+ Just is -> splitOn "," is+ Nothing -> [defFile]+ d <- renderRPlot code+ when (imgFiles == [defFile]) $ void $ convertDefault+ imgFiles' <- moveFiles imgFiles outDir+ return $ if d then Plain (map insertImage imgFiles') else block+ else return block+insertRplots _ block = return block++insertImage :: FilePath -> Inline+insertImage file = Image [] (file,"")++--plot the R graph+--the files created will be the one specified in the R code with commands such as:+--png(filename="fig1.png")+--if no filename is specified, a file "Rplots.pdf" is generated.+renderRPlot :: String -> IO Bool+renderRPlot rcode = do+ writeFile tmpRFile rcode+ (code,stdout,stderr) <- readProcessWithExitCode "R" ["CMD", "BATCH", "--no-save", "--quiet", tmpRFile] ""+ when (code /= ExitSuccess) $ do+ putStrLnErr $ "R exited with: " ++ (show code)+ putStrLnErr stdout+ putStrLnErr stderr+ whenM (doesFileExist tmpRFile) $ removeFile tmpRFile+ whenM (doesFileExist "plot.Rout") $ removeFile "plot.Rout"+ return $ (code==ExitSuccess)++moveFiles :: [FilePath] -> FilePath -> IO [FilePath]+moveFiles files outDir = do+ createDirectoryIfMissing False outDir+ mapM_ (\a -> whenM (doesFileExist a) $ renameFile a (outDir </> a)) files+ return $ map ((pathSeparator : outDir) </>) files++convertDefault :: IO Bool+convertDefault = do+ (code,_,_) <- readProcessWithExitCode "convert" [defRplot, defFile] ""+ whenM (doesFileExist defRplot) $ void $ removeFile defRplot+ return $ (code==ExitSuccess)++putStrLnErr = hPutStrLn stderr++whenM :: Monad m => m Bool -> m () -> m ()+whenM cond a = do+ c <- cond+ if c then a else (return ())