diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2015 Jonas Weber
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,11 @@
+
+import Text.Pandoc.PlantUML.Filter
+import Text.Pandoc.PlantUML.Filter.IORender
+import Text.Pandoc.JSON
+
+processBlocksInRealWorld :: Maybe Format -> Block -> IO Block
+processBlocksInRealWorld = processBlocks
+
+main :: IO ()
+main = toJSONFilter processBlocksInRealWorld
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/pandoc-plantuml-diagrams.cabal b/pandoc-plantuml-diagrams.cabal
new file mode 100644
--- /dev/null
+++ b/pandoc-plantuml-diagrams.cabal
@@ -0,0 +1,60 @@
+name:                pandoc-plantuml-diagrams
+version:             0.1.0.3
+synopsis:            Render and insert PlantUML diagrams with Pandoc
+description:         PlantUML renders different types of UML diagrams.
+                     This filter invokes plantuml.jar (which must be present
+                     in the current directory) for any yet unrendered diagrams.
+                     .
+                     Diagrams are recognized in CodeBlocks that have the
+                     class "uml". It is advisable to also include an attribute
+                     "caption", which is rendered as alternate text for the image.
+                     If an ID is present, it is additionally appended compatible
+                     with pandoc-crossref.
+license:             MIT
+license-file:        LICENSE
+author:              Jonas Weber
+maintainer:          contact@jonasw.de
+category:            Text
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  Exposed-modules:     Text.Pandoc.PlantUML.Filter
+                     , Text.Pandoc.PlantUML.Filter.IORender
+                     , Text.Pandoc.PlantUML.Filter.Types
+                     , Text.Pandoc.PlantUML.Filter.FileNameGenerator
+                     , Text.Pandoc.PlantUML.Filter.Formats
+                     , Text.Pandoc.PlantUML.Filter.OutputBlock
+  build-depends:       base >= 4 && < 5
+                     , pandoc-types
+                     , SHA
+                     , process
+                     , directory
+                     , utf8-string
+                     , bytestring
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+
+Executable pandoc-plantuml-diagrams
+  Main-Is:             Main.hs
+  build-depends:       base >= 4 && < 5
+                     , pandoc-plantuml-diagrams
+                     , pandoc-types
+  default-language:    Haskell2010
+
+Test-Suite test-pandoc-crossref
+  Type:                exitcode-stdio-1.0
+  Main-Is:             Spec.hs
+  hs-source-dirs:      test, src
+  default-language:    Haskell2010
+  Build-depends:       hspec
+                     , hspec-discover
+                     , base >= 4 && < 5
+                     , mtl
+                     , pandoc-types
+                     , SHA
+                     , utf8-string
+
+source-repository head
+  type:                git
+  location:            git://github.com/thriqon/pandoc-plantuml-diagrams
diff --git a/src/Text/Pandoc/PlantUML/Filter.hs b/src/Text/Pandoc/PlantUML/Filter.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/PlantUML/Filter.hs
@@ -0,0 +1,34 @@
+
+-- |
+-- Module    : Text.Pandoc.PlantUML.Filter
+--
+-- pandoc-plantuml-diagrams is a filter for Pandoc that automatically
+-- renders UML diagrams with PlantUML.
+module Text.Pandoc.PlantUML.Filter (processBlocks) where
+
+import Text.Pandoc.JSON
+import Control.Monad
+
+import Text.Pandoc.PlantUML.Filter.Types
+import Text.Pandoc.PlantUML.Filter.FileNameGenerator
+import Text.Pandoc.PlantUML.Filter.Formats
+import Text.Pandoc.PlantUML.Filter.OutputBlock
+
+-- | Processes a block in the context of the give format.
+-- The call syntax is compatible with the json filter provided
+-- by Pandoc.
+--
+processBlocks :: ImageIO m => Maybe Format -> Block -> m Block
+processBlocks (Just format) block@(CodeBlock attr@(_, classes, _) contents)
+  | "uml" `elem` classes       = do
+    ensureRendered imageFileName (DiagramSource contents)
+    return $ resultBlock imageFileName attr
+  | otherwise                  = return block
+  where imageFileName = ImageFileName (fileNameForSource (DiagramSource contents)) (imageFormatTypeFor format)
+processBlocks _ x              = return x
+
+ensureRendered :: ImageIO m => ImageFileName -> DiagramSource -> m ()
+ensureRendered imageFileName source = inCaseNotExists imageFileName $ renderImage imageFileName source
+
+inCaseNotExists :: ImageIO m => ImageFileName -> m () -> m ()
+inCaseNotExists fileName action = doesImageExist fileName >>= flip unless action
diff --git a/src/Text/Pandoc/PlantUML/Filter/FileNameGenerator.hs b/src/Text/Pandoc/PlantUML/Filter/FileNameGenerator.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/PlantUML/Filter/FileNameGenerator.hs
@@ -0,0 +1,27 @@
+
+-- |
+-- Module          : Text.Pandoc.PlantUML.Filter.FileNameGenerator
+-- Description     : Generate a filename only depending on the contents of it.
+-- Copyright       : (c) Jonas Weber, 2015
+-- License         : ISC
+--
+-- This package does its best to avoid rerendering the same diagrams (as in, with
+-- the same source) if not neccessary. It uses a cryptographic hash (namely SHA1)
+-- to get a stable identifier for the contents.
+--
+--
+module Text.Pandoc.PlantUML.Filter.FileNameGenerator(fileNameForSource) where
+
+import Data.Digest.Pure.SHA (sha1, showDigest)
+import Data.ByteString.Lazy.UTF8 (fromString)
+
+import Text.Pandoc.PlantUML.Filter.Types
+
+-- | Generates the Hash of a diagram source, and prefixes that.
+fileNameForSource :: DiagramSource -> ImageName
+fileNameForSource (DiagramSource source) = prefix ++ (hash source)
+  where hash = showDigest . sha1 . fromString
+
+-- | The prefix to put before rendered images
+prefix :: String
+prefix = ".rendered."
diff --git a/src/Text/Pandoc/PlantUML/Filter/Formats.hs b/src/Text/Pandoc/PlantUML/Filter/Formats.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/PlantUML/Filter/Formats.hs
@@ -0,0 +1,19 @@
+
+-- | Module : Text.Pandoc.PlantUML.Filter.Formats
+-- Determines the image type to be used for one particular
+-- pandoc output format.
+--
+-- Currently uses EPS for latex-based outputs (including PDF),
+-- and PNG for anything else.
+--
+module Text.Pandoc.PlantUML.Filter.Formats(imageFormatTypeFor) where
+
+import Text.Pandoc.Definition
+import Text.Pandoc.PlantUML.Filter.Types
+
+-- | The image file type to be used for the given output format.
+-- EPS is used for latex outputs, as it provides lossless scalability
+-- All other output formats use PNG for now.
+imageFormatTypeFor :: Format -> ImageFormat
+imageFormatTypeFor (Format "latex") =  "eps"
+imageFormatTypeFor _                =  "png"
diff --git a/src/Text/Pandoc/PlantUML/Filter/IORender.hs b/src/Text/Pandoc/PlantUML/Filter/IORender.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/PlantUML/Filter/IORender.hs
@@ -0,0 +1,31 @@
+
+-- | Module: Text.Pandoc.PlantUML.Filter.Render
+-- Defines the actual rendering done with PlantUML
+module Text.Pandoc.PlantUML.Filter.IORender() where
+
+import System.IO (hClose, hPutStr, IOMode(..), withBinaryFile, Handle)
+import Data.ByteString.Lazy (hGetContents, hPut)
+import System.Process
+import System.Directory
+
+import Text.Pandoc.PlantUML.Filter.Types
+
+instance ImageIO IO where
+  renderImage imageFileName (DiagramSource source) = do
+    (Just hIn, Just hOut, _, _) <- createProcess $ plantUmlProcess imageFileName
+    hPutStr hIn source
+    hClose hIn
+    withImageFile $ pipe hOut
+    hClose hOut
+      where withImageFile = withBinaryFile (show imageFileName) WriteMode
+  doesImageExist imageFileName = doesFileExist $ show imageFileName
+
+plantUmlProcess :: ImageFileName -> CreateProcess
+plantUmlProcess (ImageFileName _ fileType) = (proc "java" ["-jar", "plantuml.jar", "-pipe", "-t" ++ fileType])
+  { std_in = CreatePipe, std_out = CreatePipe }
+
+pipe :: Handle -> Handle -> IO ()
+pipe hIn hOut = do
+  input <- hGetContents hIn
+  hPut hOut input
+
diff --git a/src/Text/Pandoc/PlantUML/Filter/OutputBlock.hs b/src/Text/Pandoc/PlantUML/Filter/OutputBlock.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/PlantUML/Filter/OutputBlock.hs
@@ -0,0 +1,31 @@
+
+-- | Module : Text.Pandoc.PlantUML.Filter.OutputBlock
+-- Renders an image file name and some attributes into a Pandoc
+-- block, like so:
+--
+-- @
+-- Para
+--   Image src=picture.jpg
+--   "{#fig:id}"
+-- @
+module Text.Pandoc.PlantUML.Filter.OutputBlock(resultBlock) where
+
+import Text.Pandoc.JSON
+import Text.Pandoc.PlantUML.Filter.Types
+import Data.Maybe
+
+-- | The result block, as specified in the module header.
+resultBlock :: ImageFileName -> Attr -> Block
+resultBlock imageFileName attr = Para $ map (\p -> p imageFileName attr) [imageTag, idTag]
+
+imageTag :: ImageFileName -> Attr -> Inline
+imageTag imageFileName attr    = Image (altTagInline attr) ((show imageFileName), "fig:")
+
+idTag :: ImageFileName -> Attr -> Inline
+idTag _ (id, _, _)             = Str ("{#" ++ id ++ "}")
+
+altTagInline :: Attr -> [Inline]
+altTagInline (_, _, keyValues)
+  | isJust altText             = [Str (fromJust altText)]
+  | otherwise                  = []
+  where altText = lookup "caption" keyValues
diff --git a/src/Text/Pandoc/PlantUML/Filter/Types.hs b/src/Text/Pandoc/PlantUML/Filter/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/PlantUML/Filter/Types.hs
@@ -0,0 +1,36 @@
+
+-- |
+-- Module          : Text.Pandoc.PlantUML.Filter.Types
+-- Description     : Defines the common types used in this package
+-- Copyright       : (c) Jonas Weber, 2015
+-- License         : ISC
+--
+module Text.Pandoc.PlantUML.Filter.Types where
+
+-- | The name of an image, without extension, usually a hash
+type ImageName = String
+
+-- | The source of a diagram
+newtype DiagramSource = DiagramSource String deriving (Eq, Show)
+
+-- | An image format, e.g. "eps"
+type ImageFormat = String
+
+-- | A filename of an image. It contains the basename (myawesomepicture) and
+-- the extension (jpg). It can be shown, which is basically
+-- "myawesomepicture.jpg"
+data ImageFileName = ImageFileName ImageName ImageFormat deriving Eq
+
+-- | Show the image file name by joining basename and extension with
+-- a dot, yielding picture.jpg
+instance Show ImageFileName where
+  show (ImageFileName name format) = name ++ "." ++ format
+
+-- | External impure actions are encapsulated in this monad.
+class Monad m => ImageIO m where
+  -- | Tells whether an image with the given file name
+  -- is already present in the store (e.g., the filesystem).
+  doesImageExist     :: ImageFileName -> m Bool
+  -- | Calls out to an external diagram processor (PlantUML)
+  -- to render the source to the given image file name.
+  renderImage        :: ImageFileName -> DiagramSource -> m ()
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
