diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Change log
+
+pandoc-pyplot uses [Semantic Versioning][].
+The change log is available through the [releases on GitHub][].
+
+[Semantic Versioning]: http://semver.org/spec/v2.0.0.html
+[releases on GitHub]: https://github.com/githubuser/pandoc-pyplot/releases
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,23 @@
+[The MIT License (MIT)][]
+
+Copyright (c) 2018 Author name here
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+[The MIT License (MIT)]: https://opensource.org/licenses/MIT
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,133 @@
+# pandoc-pyplot
+
+[![Build status](https://ci.appveyor.com/api/projects/status/qbmq9cyks5jup48e?svg=true)](https://ci.appveyor.com/project/LaurentRDC/pandoc-pyplot)
+
+_A Pandoc filter for generating figures with Matplotlib from code directly in documents_
+
+Inspired by [sphinx](https://sphinxdoc.org)'s `plot_directive`, `pandoc-pyplot` helps turn Python code present in your documents to embedded Matplotlib figures. 
+
+## Usage
+
+The filter recognizes code blocks with the `plot_target` attribute present. It will run the script in the associated code block in a Python interpreter and capture the generated Matplotlib figure. This captured figure will be saved in the located specific by `plot_target`.
+
+### Basic example
+
+Here is a basic example using the scripting `matplotlib.pyplot` API:
+
+```markdown
+    ```{plot_target=my_figure.jpg}
+    import matplotlib.pyplot as plt
+
+    plt.figure()
+    plt.plot([0,1,2,3,4], [1,2,3,4,5])
+    plt.title('This is an example figure')
+    ```
+```
+
+`pandoc-pyplot` will determine whether the `plot_target` is a relative or absolute path. In case of a relative path (like above), all paths will be considered relative to the current working directory.
+
+We can control the format of the output file by changing the `plot_target` file extension. All formats supported by Matplotlib on your machine are available.
+
+Putting the above in `input.md`, we can then generate the plot and embed it:
+
+```bash
+pandoc --filter pandoc-pyplot input.md --output output.html
+```
+
+or
+
+```bash
+pandoc --filter pandoc-pyplot input.md output.pdf
+```
+
+or any other output format you want. There are more examples in the source repository, in the `\examples` directory.
+
+### Link to source code
+
+In case of an output format that supports links (e.g. HTML), the embedded image generated by `pandoc-pyplot` will be a link to the source code which was used to generate the file. Therefore, other people can see what Python code was used to create your figures.
+
+### Alternate text
+
+You can also specify some alternate text for your image. This is done using the optional `plot_alt` parameter:
+
+```markdown
+    ```{plot_target=my_figure.jpg, plot_alt="This is a simple figure"}
+    import matplotlib.pyplot as plt
+
+    plt.figure()
+    plt.plot([0,1,2,3,4], [1,2,3,4,5])
+    plt.title('This is an example figure')
+    ```
+```
+
+## Requirements
+
+This filter only works with the Matplotlib plotting library. Therefore, you need [Matplotlib](matplotlib.org) and a Python interpreter. The python interpreter is expected to be discoverable using the name `"python"` (as opposed to `"python3"`, for example)
+
+## Running the filter
+
+The filter program must be in your `PATH`. In case it is, you can use the filter with Pandoc as follows:
+
+```bash
+pandoc --filter pandoc-pyplot input.md output.html
+```
+
+Another example with PDF output:
+
+```bash
+pandoc --filter pandoc-pyplot input.md output.pdf
+```
+
+Python exceptions will be printed to screen in case of a problem.
+
+`pandoc-pyplot` has a very limited command-line interface. Take a look at the help available using the `-h` or `--help` argument:
+
+```bash
+pandoc-pyplot --help
+```
+
+## Usage as a Haskell library
+
+To include the functionality of `pandoc-pyplot` in a Haskell package, you can use the `makePlot` function:
+
+```haskell
+-- From pandoc-types
+import Text.Pandoc.Walk         (walkM)
+import Text.Pandoc.Definition   (Pandoc)
+-- From pandoc-pyplot
+import Text.Pandoc.Filter.Pyplot (makePlot)
+
+transformDocument :: Pandoc -> IO Pandoc
+transformDocument = walkM makePlot
+```
+
+## Usage with Hakyll
+
+This filter was originally designed to be used with [Hakyll](https://jaspervdj.be/hakyll/). In case you want to use the filter with your own Hakyll setup, you must create a transform function first:
+
+```haskell
+-- From pandoc-types
+import Text.Pandoc          (Pandoc)
+import Text.Pandoc.Walk     (walkM)
+
+-- from pandoc-pyplot
+import Text.Pandoc.Filter.Pyplot (makePlot)
+
+import Hakyll
+
+plotTransform :: Pandoc -> IO Pandoc
+plotTransform = walkM . makePlot
+
+-- Unsafe compiler is required because of the interaction
+-- in IO (i.e. running an external Python script).
+makePlotPandocCompiler :: Compiler (Item String)
+makePlotPandocCompiler =
+  pandocCompilerWithTransformM
+    defaultHakyllReaderOptions
+    defaultHakyllWriterOptions
+    (unsafeCompiler . plotTransform)
+```
+
+## Aknowledgements
+
+This package is inspired from [`pandoc-include-code`](https://github.com/owickstrom/pandoc-include-code).
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,7 @@
+-- This script is used to build and install your package. Typically you don't
+-- need to change it. The Cabal documentation has more information about this
+-- file: <https://www.haskell.org/cabal/users-guide/installing-packages.html>.
+import qualified Distribution.Simple
+
+main :: IO ()
+main = Distribution.Simple.defaultMain
diff --git a/executable/Main.hs b/executable/Main.hs
new file mode 100644
--- /dev/null
+++ b/executable/Main.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE LambdaCase #-}
+module Main where
+
+import System.Environment        (getArgs)
+
+import Text.Pandoc.JSON          (toJSONFilter)
+import Text.Pandoc.Filter.Pyplot (makePlot)
+
+import qualified Data.Version as V
+import Paths_pandoc_pyplot       (version)
+
+-- The formatting is borrowed from Python's argparse library
+help :: String
+help = "\n\
+    \\n\
+    \   usage: pandoc-pyplot [-h, --help] [-v, --version] \n\
+    \\n\
+    \   This pandoc filter generates plots from Python code blocks using Matplotlib. \n\
+    \   This allows to keep documentation and figures up-to-date.\n\
+    \\n\
+    \   Optional arguments:\n\
+    \       -h, --help     Show this help message and exit\n\
+    \       -v, --version  Show version number and exit \n\
+    \\n\
+    \   To use with pandoc: \n\
+    \       pandoc --filter pandoc-pyplot input.md --output output.html\n\
+    \\n\
+    \   More information can be found in the repository README, located at \n\
+    \       https://github.com/LaurentRDC/pandoc-pyplot\n"
+
+main :: IO ()
+main = do
+    getArgs >>=
+        \case
+            (arg:_) 
+                | arg `elem` ["-h", "--help"]    -> showHelp
+                | arg `elem` ["-v", "--version"] -> showVersion
+            _ -> toJSONFilter makePlot 
+    where
+        showHelp    = putStrLn help
+        showVersion = putStrLn (V.showVersion version)
diff --git a/package.yaml b/package.yaml
new file mode 100644
--- /dev/null
+++ b/package.yaml
@@ -0,0 +1,50 @@
+name: pandoc-pyplot
+version: '1.0.0.0'
+github: "LaurentRDC/pandoc-pyplot"
+license: MIT
+author: "Laurent P. René de Cotret"
+maintainer: "Laurent P. René de Cotret"
+synopsis: A Pandoc filter for including figures generated from Matplotlib
+description: 
+  A pandoc filter for including figures generated from Matplotlib.
+  Keep the document and Python code in the same location. Output from Matplotlib
+  is captured and included as a figure.
+category: Documentation
+
+license-file: LICENSE.md
+
+extra-source-files:
+- CHANGELOG.md
+- LICENSE.md
+- package.yaml
+- README.md
+- stack.yaml
+
+ghc-options: -Wall -Wcompat
+
+library:
+  dependencies:
+  - base            > 4.8 && < 5
+  - directory
+  - filepath
+  - pandoc-types    > 1.12 && < 2
+  - temporary
+  - typed-process
+  - containers
+  source-dirs: src
+  exposed-modules:
+  - Text.Pandoc.Filter.Pyplot
+  - Text.Pandoc.Filter.Scripting
+
+executables:
+  pandoc-pyplot:
+    source-dirs: executable
+    main: Main.hs
+    dependencies:
+    - base                > 4.8  && < 5
+    - pandoc-pyplot
+    - pandoc-types        > 1.12 && < 2
+    ghc-options:
+    - -rtsopts
+    - -threaded
+    - -with-rtsopts=-N
diff --git a/pandoc-pyplot.cabal b/pandoc-pyplot.cabal
new file mode 100644
--- /dev/null
+++ b/pandoc-pyplot.cabal
@@ -0,0 +1,62 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.30.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 057cfdb19c595e350f99205195ae2e446cc16a377c1fd0633b87ad68ae4bdc98
+
+name:           pandoc-pyplot
+version:        1.0.0.0
+synopsis:       A Pandoc filter for including figures generated from Matplotlib
+description:    A pandoc filter for including figures generated from Matplotlib. Keep the document and Python code in the same location. Output from Matplotlib is captured and included as a figure.
+category:       Documentation
+homepage:       https://github.com/LaurentRDC/pandoc-pyplot#readme
+bug-reports:    https://github.com/LaurentRDC/pandoc-pyplot/issues
+author:         Laurent P. René de Cotret
+maintainer:     Laurent P. René de Cotret
+license:        MIT
+license-file:   LICENSE.md
+build-type:     Simple
+extra-source-files:
+    CHANGELOG.md
+    LICENSE.md
+    package.yaml
+    README.md
+    stack.yaml
+
+source-repository head
+  type: git
+  location: https://github.com/LaurentRDC/pandoc-pyplot
+
+library
+  exposed-modules:
+      Text.Pandoc.Filter.Pyplot
+      Text.Pandoc.Filter.Scripting
+  other-modules:
+      Paths_pandoc_pyplot
+  hs-source-dirs:
+      src
+  ghc-options: -Wall -Wcompat
+  build-depends:
+      base >4.8 && <5
+    , containers
+    , directory
+    , filepath
+    , pandoc-types >1.12 && <2
+    , temporary
+    , typed-process
+  default-language: Haskell2010
+
+executable pandoc-pyplot
+  main-is: Main.hs
+  other-modules:
+      Paths_pandoc_pyplot
+  hs-source-dirs:
+      executable
+  ghc-options: -Wall -Wcompat -rtsopts -threaded -with-rtsopts=-N
+  build-depends:
+      base >4.8 && <5
+    , pandoc-pyplot
+    , pandoc-types >1.12 && <2
+  default-language: Haskell2010
diff --git a/src/Text/Pandoc/Filter/Pyplot.hs b/src/Text/Pandoc/Filter/Pyplot.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/Filter/Pyplot.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE MultiWayIf #-}
+
+module Text.Pandoc.Filter.Pyplot (
+        makePlot
+      , makePlot'
+      , PandocPyplotError(..)
+      , showError
+    ) where
+
+import           Control.Monad   ((>=>))
+import qualified Data.Map.Strict as M
+import           System.FilePath (replaceExtension, isValid)
+
+import           Text.Pandoc.Definition
+
+import           Text.Pandoc.Filter.Scripting
+
+data PandocPyplotError = ScriptError Int                -- ^ Running Python script has yielded an error
+                       | InvalidTargetError FilePath    -- ^ Invalid figure path
+                       | BlockingCallError              -- ^ Python script contains a block call to 'show()'
+
+-- | Datatype containing all parameters required
+-- to run pandoc-pyplot
+data FigureSpec = FigureSpec 
+    { target :: FilePath    -- ^ filepath where generated figure will be saved
+    , alt :: String         -- ^ Alternate text for the figure (optional)
+    , caption :: String     -- ^ Figure caption (optional)
+    }
+
+-- Keys that pandoc-pyplot will look for in code blocks
+targetKey, altTextKey, captionKey :: String
+targetKey  = "plot_target"
+altTextKey = "plot_alt"
+captionKey = "plot_caption"
+
+-- | Determine inclusion specifications from Block attributes.
+-- Note that the target key is required, but all other parameters are optional
+parseFigureSpec :: M.Map String String -> Maybe FigureSpec
+parseFigureSpec attrs = createInclusion <$> M.lookup targetKey attrs
+    where
+        defaultAltText = "Figure generated by pandoc-pyplot"
+        defaultCaption = mempty
+        createInclusion fname = FigureSpec
+            { target  = fname
+            , alt     = M.findWithDefault defaultAltText altTextKey attrs
+            , caption = M.findWithDefault defaultCaption captionKey attrs
+            }
+
+-- | Format the script source based on figure spec.
+formatScriptSource :: FigureSpec -> PythonScript -> PythonScript
+formatScriptSource spec script = mconcat [ "# Source code for " <> target spec
+                                         , "\n"
+                                         , script 
+                                         ]
+
+-- | Main routine to include Matplotlib plots.
+-- Code blocks containing the attributes @plot_target@ are considered
+-- Python plotting scripts. All other possible blocks are ignored.
+-- The source code is also saved in another file, which can be access by 
+-- clicking the image
+makePlot' :: Block -> IO (Either PandocPyplotError Block)
+makePlot' cb @ (CodeBlock (id', cls, attrs) scriptSource) = 
+    case parseFigureSpec (M.fromList attrs) of
+        -- Could not parse - leave code block unchanged
+        Nothing -> return $ Right cb
+        -- Could parse : run the script and capture output
+        Just spec -> do
+            let figurePath = target spec
+            
+            if | not (isValid figurePath)         -> return $ Left $ InvalidTargetError figurePath
+               | hasBlockingShowCall scriptSource -> return $ Left $ BlockingCallError
+               | otherwise -> do 
+                    
+                script <- addPlotCapture figurePath scriptSource
+                result <- runTempPythonScript script
+                
+                case result of
+                    ScriptFailure code -> return $ Left $ ScriptError code
+                    ScriptSuccess -> do 
+                        -- Save the original script into a separate file
+                        -- so it can be inspected
+                        -- Note : using a .txt file allows to view source directly
+                        --        in the browser, in the case of HTML output
+                        let sourcePath = replaceExtension figurePath ".txt"
+                        writeFile sourcePath $ formatScriptSource spec scriptSource
+                        
+                        -- Propagate attributes that are not related to pandoc-pyplot
+                        let inclusionKeys = [ targetKey, altTextKey, captionKey ]
+                            filteredAttrs = filter (\(k,_) -> k `notElem` inclusionKeys) attrs
+                            image         = Image (id', cls, filteredAttrs) [Str $ alt spec] (figurePath, "")
+                            srcTarget     = (sourcePath, "Click on this figure to see the source code")
+
+                        -- TODO: use FigureSpec caption
+                        -- We make the figure be a link to the source code
+                        return $ Right $ Para [
+                            Link nullAttr [image] srcTarget
+                            ]
+            
+makePlot' x = return $ Right x
+
+-- | Translate filter error to an error message
+showError :: PandocPyplotError -> String
+showError (ScriptError exitcode)     = "Script error: plot could not be generated. Exit code " <> (show exitcode)
+showError (InvalidTargetError fname) = "Target filename " <> fname <> " is not valid."
+showError BlockingCallError          = "Script contains a blocking call to show, like 'plt.show()'"
+
+-- | Highest-level function that can be walked over a Pandoc tree.
+-- All code blocks that have the 'plot_target' parameter will be considered
+-- figures.
+makePlot :: Block -> IO Block
+makePlot = makePlot' >=> either (fail . showError) return
diff --git a/src/Text/Pandoc/Filter/Scripting.hs b/src/Text/Pandoc/Filter/Scripting.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/Filter/Scripting.hs
@@ -0,0 +1,58 @@
+
+module Text.Pandoc.Filter.Scripting (
+      runTempPythonScript
+    , addPlotCapture
+    , hasBlockingShowCall
+    , PythonScript
+    , ScriptResult(..)
+) where
+
+import System.Directory     (getCurrentDirectory)
+import System.Exit          (ExitCode(..))
+import System.FilePath      ((</>), isAbsolute)
+import System.IO.Temp       (getCanonicalTemporaryDirectory)
+import System.Process.Typed (runProcess, shell)
+
+import Data.Monoid          (Any(..))
+
+type PythonScript = String
+
+data ScriptResult = ScriptSuccess 
+                  | ScriptFailure Int
+
+-- | Take a python script in string form, write it in a temporary directory,
+-- then execute it. 
+runTempPythonScript :: PythonScript    -- ^ Content of the script
+                    -> IO ScriptResult -- ^ Result with exit code.
+runTempPythonScript script = do
+            -- Write script to temporary directory
+            scriptPath <- (</> "pandoc-pyplot.py") <$>  getCanonicalTemporaryDirectory
+            writeFile scriptPath script
+            -- Execute script
+            ec <- runProcess $ shell $ "python " <> (show scriptPath)
+            case ec of
+                ExitSuccess -> return ScriptSuccess
+                ExitFailure code -> return $ ScriptFailure code
+
+-- | Modify a Python plotting script to save the figure to a filename.
+addPlotCapture :: FilePath          -- ^ Path where to save the figure
+               -> PythonScript      -- ^ Raw code block
+               -> IO PythonScript   -- ^ Code block with added capture
+addPlotCapture fname content = do
+    absFname <- if isAbsolute fname
+                then (return fname)
+                else (</> fname) <$> getCurrentDirectory
+    return $ mconcat [ content
+                     , "\nimport matplotlib.pyplot as plt"  -- Just in case
+                     , "\nplt.savefig(" <> show absFname <> ")\n\n"
+                     ]
+
+-- | Detect the presence of a blocking show call, for example "plt.show()"
+hasBlockingShowCall :: PythonScript -> Bool
+hasBlockingShowCall script = anyOf
+        [ "plt.show()" `elem` scriptLines
+        , "matplotlib.pyplot.show()" `elem` scriptLines
+        ]
+    where
+        scriptLines = lines script
+        anyOf xs = getAny $ mconcat $ Any <$> xs
diff --git a/stack.yaml b/stack.yaml
new file mode 100644
--- /dev/null
+++ b/stack.yaml
@@ -0,0 +1,64 @@
+# This file was automatically generated by 'stack init'
+#
+# Some commonly used options have been documented as comments in this file.
+# For advanced use and comprehensive documentation of the format, please see:
+# https://docs.haskellstack.org/en/stable/yaml_configuration/
+
+# Resolver to choose a 'specific' stackage snapshot or a compiler version.
+# A snapshot resolver dictates the compiler version and the set of packages
+# to be used for project dependencies. For example:
+#
+# resolver: lts-3.5
+# resolver: nightly-2015-09-21
+# resolver: ghc-7.10.2
+#
+# The location of a snapshot can be provided as a file or url. Stack assumes
+# a snapshot provided as a file might change, whereas a url resource does not.
+#
+# resolver: ./custom-snapshot.yaml
+# resolver: https://example.com/snapshots/2018-01-01.yaml
+resolver: lts-12.10
+
+# User packages to be built.
+# Various formats can be used as shown in the example below.
+#
+# packages:
+# - some-directory
+# - https://example.com/foo/bar/baz-0.0.2.tar.gz
+# - location:
+#    git: https://github.com/commercialhaskell/stack.git
+#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
+#  subdirs:
+#  - auto-update
+#  - wai
+packages:
+- .
+# Dependency packages to be pulled from upstream that are not in the resolver
+# using the same syntax as the packages field.
+# (e.g., acme-missiles-0.3)
+# extra-deps: []
+
+# Override default flag values for local packages and extra-deps
+# flags: {}
+
+# Extra package databases containing global packages
+# extra-package-dbs: []
+
+# Control whether we use the GHC we find on the path
+# system-ghc: true
+#
+# Require a specific version of stack, using version ranges
+# require-stack-version: -any # Default
+# require-stack-version: ">=1.10"
+#
+# Override the architecture used by stack, especially useful on Windows
+# arch: i386
+# arch: x86_64
+#
+# Extra directories used by stack for building
+# extra-include-dirs: [/path/to/dir]
+# extra-lib-dirs: [/path/to/dir]
+#
+# Allow a newer minor version of GHC than the snapshot specifies
+# compiler-check: newer-minor
