diff --git a/src/Text/Pandoc/Lua/Module/Utils.hs b/src/Text/Pandoc/Lua/Module/Utils.hs
index 496fdbc0a..3a3727355 100644
--- a/src/Text/Pandoc/Lua/Module/Utils.hs
+++ b/src/Text/Pandoc/Lua/Module/Utils.hs
@@ -29,22 +29,51 @@ module Text.Pandoc.Lua.Module.Utils
   ( pushModule
   ) where
 
-import Data.Digest.Pure.SHA (sha1, showDigest)
-import Foreign.Lua (Lua, NumResults)
+import Control.Applicative ((<|>))
+import Foreign.Lua (FromLuaStack, Lua, NumResults)
+import Text.Pandoc.Definition (Pandoc, Meta, Block, Inline)
 import Text.Pandoc.Lua.StackInstances ()
 import Text.Pandoc.Lua.Util (addFunction)
 
+import qualified Data.Digest.Pure.SHA as SHA
 import qualified Data.ByteString.Lazy as BSL
 import qualified Foreign.Lua as Lua
+import qualified Text.Pandoc.Shared as Shared
 
 -- | Push the "pandoc.utils" module to the lua stack.
 pushModule :: Lua NumResults
 pushModule = do
   Lua.newtable
-  addFunction "sha1" sha1HashFn
+  addFunction "sha1" sha1
+  addFunction "stringify" stringify
   return 1
 
 -- | Calculate the hash of the given contents.
-sha1HashFn :: BSL.ByteString
-           -> Lua String
-sha1HashFn = return . showDigest . sha1
+sha1 :: BSL.ByteString
+     -> Lua String
+sha1 = return . SHA.showDigest . SHA.sha1
+
+stringify :: AstElement -> Lua String
+stringify el = return $ case el of
+  PandocElement pd -> Shared.stringify pd
+  InlineElement i  -> Shared.stringify i
+  BlockElement b   -> Shared.stringify b
+  MetaElement m    -> Shared.stringify m
+
+data AstElement
+  = PandocElement Pandoc
+  | MetaElement Meta
+  | BlockElement Block
+  | InlineElement Inline
+  deriving (Show)
+
+instance FromLuaStack AstElement where
+  peek idx  = do
+    res <- Lua.tryLua $  (PandocElement <$> Lua.peek idx)
+                     <|> (InlineElement <$> Lua.peek idx)
+                     <|> (BlockElement <$> Lua.peek idx)
+                     <|> (MetaElement <$> Lua.peek idx)
+    case res of
+      Right x -> return x
+      Left _ -> Lua.throwLuaError
+        "Expected an AST element, but could not parse value as such."
diff --git a/test/Tests/Lua.hs b/test/Tests/Lua.hs
index 0e76249fe..57e7c5f0c 100644
--- a/test/Tests/Lua.hs
+++ b/test/Tests/Lua.hs
@@ -101,6 +101,7 @@ tests = map (localOption (QuickCheckTests 20))
                      , plain (str "failing pipe: OK")
                      , plain (str "read: OK")
                      , plain (str "failing read: OK")
+                     , plain (str "stringify: OK")
                      ])
   ]
 
diff --git a/test/lua/test-pandoc-utils.lua b/test/lua/test-pandoc-utils.lua
index 7354496f9..ce3456d5d 100644
--- a/test/lua/test-pandoc-utils.lua
+++ b/test/lua/test-pandoc-utils.lua
@@ -1,4 +1,4 @@
-utils = require 'pandoc'
+utils = require 'pandoc.utils'
 
 -- SHA1
 ------------------------------------------------------------------------
@@ -22,7 +22,7 @@ function test_pipe ()
     warn 'Did not find /bin/sed, skipping test'
     return true
   end
-  local pipe_result = utils.pipe('/bin/sed', {'-e', 's/a/b/'}, 'abc')
+  local pipe_result = pandoc.pipe('/bin/sed', {'-e', 's/a/b/'}, 'abc')
   return pipe_result == 'bbc'
 end
 
@@ -31,7 +31,7 @@ function test_failing_pipe ()
     warn 'Did not find /bin/false, skipping test'
     return true
   end
-  local res, err = pcall(utils.pipe, '/bin/false', {}, 'abc')
+  local res, err = pcall(pandoc.pipe, '/bin/false', {}, 'abc')
   return not res and
     err.command == '/bin/false' and
     err.error_code == 1 and
@@ -51,6 +51,18 @@ function test_failing_read ()
   return not res and err:match 'Unknown reader: nosuchreader'
 end
 
+-- Stringify
+------------------------------------------------------------------------
+function test_stringify ()
+  local inline = pandoc.Emph{
+    pandoc.Str 'Cogito',
+    pandoc.Space(),
+    pandoc.Str 'ergo',
+    pandoc.Space(),
+    pandoc.Str 'sum.',
+  }
+  return utils.stringify(inline) == 'Cogito ergo sum.'
+end
 
 -- Return result
 ------------------------------------------------------------------------
@@ -65,5 +77,6 @@ function Para (el)
     pandoc.Plain{pandoc.Str("failing pipe: " .. run(test_failing_pipe))},
     pandoc.Plain{pandoc.Str("read: " .. run(test_read))},
     pandoc.Plain{pandoc.Str("failing read: " .. run(test_failing_read))},
+    pandoc.Plain{pandoc.Str("stringify: " .. run(test_stringify))},
   }
 end