diff --git a/example/euclidean.hs b/example/euclidean.hs
--- a/example/euclidean.hs
+++ b/example/euclidean.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE Rank2Types, CPP #-}
+{-# LANGUAGE Rank2Types, OverloadedStrings, CPP #-}
 {-- The ProvenienceT monad transformer in action 
     in form of the Euclidean Algorithm --}
 import Control.Provenience
@@ -7,8 +7,13 @@
 import System.IO (readLn)
 import Text.Pandoc
 import qualified Data.Text.IO as T
-import Data.Text (pack)
+import Data.Text (Text,pack)
 import Data.Default
+import Data.Functor.Identity (runIdentity)
+#if MIN_VERSION_pandoc(2,8,0)
+import qualified Data.Map.Strict
+import Text.DocTemplates (Context,ToContext(..))
+#endif
 
 main = do 
     (store,_) <- execProvenienceT workflow 0
@@ -67,7 +72,7 @@
 
 #if MIN_VERSION_pandoc(2,8,0)
 -- pandoc-types >= 1.20 has Str Text instead of Str String 
-str = Str.pack
+str = Str . pack
 #else
 str = Str
 #endif
@@ -84,11 +89,21 @@
 makeDocument :: Block -> Pandoc
 makeDocument body = Pandoc nullMeta [Header 1 nullAttr [str "The Euclidean algorithm"],body]
 
+#if MIN_VERSION_pandoc(2,8,0)
 myWriterOpts :: WriterOptions
 myWriterOpts = def {
+    writerTemplate = either error Just $ runIdentity (compileTemplate "" (pack provenienceTemplate)),
+    writerVariables = toContext (Data.Map.Strict.fromList [
+        ("title" :: Text,"The Euclidean algorithm" :: Text),
+        ("copyright" :: Text,"Lackmann Phymetric")]) :: Context Text
+}
+#else
+myWriterOpts :: WriterOptions
+myWriterOpts = def {
     writerTemplate = Just provenienceTemplate,
-    writerVariables = [("title","The Euclidean algorithm"),("copyright","Lackmann Phymetric")]
+    writerVariables = [("title","The Euclidean algorithm" :: Text),("copyright","Lackmann Phymetric" :: Text)]
     }
+#endif
 
 -- | Pandoc Template for Html output
 provenienceTemplate :: String
diff --git a/provenience.cabal b/provenience.cabal
--- a/provenience.cabal
+++ b/provenience.cabal
@@ -1,5 +1,5 @@
 name:                provenience
-version:             0.1.2.0
+version:             0.1.2.1
 synopsis:            Computations that automatically track data dependencies
 description:         see README.md
 license:             GPL-3
@@ -12,7 +12,7 @@
 build-type:          Simple
 extra-source-files:  README.md
 cabal-version:       >=1.10
-tested-with:         GHC == 7.10.3, GHC == 8.4.4, GHC == 8.6.5
+tested-with:         GHC == 7.10.3, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.10.4
 
 library
   hs-source-dirs:      src
@@ -22,14 +22,14 @@
 -- tested against stackage lts-6.35 up to lts-14.22
   build-depends:       base >= 4.7 && < 5
                      , mtl >= 2.2.1 && <= 2.2.2
-                     , fgl >= 5.5.3.1 && <= 5.7.0.2
-                     , pandoc >= 1.16 && <= 2.7.3
-                     , blaze-markup >= 0.7.1.1 && <= 0.8.2.3
-                     , aeson >= 0.11.3.0 && <= 1.4.6.0
+                     , fgl >= 5.5.3.1 && < 5.8
+                     , pandoc >= 1.16 && < 3.0
+                     , blaze-markup >= 0.7.1.1 && < 0.8.3
+                     , aeson >= 0.11.3.0 && < 1.6
                      , data-default >= 0.5.3 && < 0.8
-                     , containers >= 0.5.6.2 && <= 0.6.0.1
-                     , time >= 1.5.0.1 && <= 1.8.0.2
-                     , text >= 1.2.2.2 && <= 1.2.3.1
+                     , containers >= 0.5.6.2 && < 0.7
+                     , time >= 1.5.0.1 && < 2.0
+                     , text >= 1.2.2.2 && < 1.3
   default-language:    Haskell2010
   other-extensions:  CPP
 
@@ -45,6 +45,9 @@
   build-depends:   base >= 4.7 && < 5
                  , provenience
                  , mtl >= 2.2.1 && <= 2.2.2
-                 , pandoc >= 1.16 && <= 2.7.3
-                 , text >= 1.2.2.2 && <= 1.2.3.1
+                 , pandoc >= 1.16 && < 3.0
+                 , text >= 1.2.2.2 && < 2.0
                  , data-default >= 0.5.3 && < 0.8
+                 , containers  
+                 , doctemplates
+-- containers, doctemplates only needed when using pandoc >= 2.8
diff --git a/src/Control/Provenience.hs b/src/Control/Provenience.hs
--- a/src/Control/Provenience.hs
+++ b/src/Control/Provenience.hs
@@ -189,14 +189,8 @@
 class DefaultRender a where
     renderDefault :: a -> Block
 -- | 'render' 'String's as plain text. 
-#if MIN_VERSION_pandoc(2,8,0)
--- pandoc.types >= 1.20 has Str Text so the instances for Text and String must be swapped
 instance DefaultRender String where
-    renderDefault = Para . pure . Str . pack 
-#else
-instance DefaultRender String where
-    renderDefault = Para . pure . Str 
-#endif
+    renderDefault = Para . inlinesString 
 instance DefaultRender Block where
     renderDefault = id
 #if MIN_VERSION_pandoc(2,8,0)
@@ -228,9 +222,42 @@
 renderWith :: (Representation a alt, Monad m) => (a -> Block) -> Variable a -> StateT (VariableStore alt) m ()
 renderWith method v = modify' (\vs -> changeLabel (identifier v) (\desc -> desc {valueRendering = method (value v), altRep = representation (value v)}) vs)
 
+-- pandoc.types >= 1.20 has Str Text
+#if MIN_VERSION_pandoc(2,8,0)
+inlinesString :: String -> [Inline]
+inlinesString = pure . Str . pack
+#else
+inlinesString :: String -> [Inline]
+inlinesString = pure . Str
+#endif
+
+-- pandoc.types >= 1.20 uses Text in Link
+#if MIN_VERSION_pandoc(2,8,0)
+localLink :: VariableStore alt -> Node -> (Text,Text)
+localLink variables i = let txt = maybe (show i) id (getShortname i variables)
+    in (pack ('#':linknode i), pack txt)
+#else
+localLink :: VariableStore alt -> Node -> (String,String)
+localLink variables i = let txt = maybe (show i) id (getShortname i variables)
+    in ('#':linknode i,txt)
+#endif
+
+-- pandoc.types >= 1.20 uses Text in Attr 
+#if MIN_VERSION_pandoc(2,8,0)
+divVar :: Node -> [Block] -> Block
+divVar i = Div (pack (linknode i),[pack "variable"],[])
+divVars :: (Node,Node) -> [Block] -> Block
+divVars (n0,n1) = Div (pack $ "variables"++(showHex n0 ("To"++(showHex n1 ""))),["provenienceVariables"],[])
+#else
+divVar :: [Block] -> Block
+divVar i = Div (linknode i,["variable"],[])
+divVars :: (Node,Node) -> [Block] -> Block
+divVars (n0,n1) = Div ("variables"++(showHex n0 ("To"++(showHex n1 ""))),["provenienceVariables"],[])
+#endif
+
 -- | Use the 'show' method to render a 'value' as 'Plain' text. 
 renderShow :: Show a => a -> Block
-renderShow = Plain . pure . Str . show
+renderShow = Plain . inlinesString . show
 
 -- | @'render' = 'renderWith' 'renderDefault'@. 
 -- You can use this function without providing a 'DefaultRender' instance 
@@ -280,29 +307,29 @@
 renderStore :: Proveniencei18n -> VariableStore alt -> Block
 renderStore i18n variables = let
     nodelist = topsort (dependencyGraph variables) :: [Node]
-    renderIncoming i = let txt = maybe (show i) id (getShortname i variables) 
-        in Link ("",["incoming"],[]) [Str txt] ('#':linknode i,txt)
-    renderOutgoing i = let txt = maybe (show i) id (getShortname i variables) 
-        in Link ("",["outgoing"],[]) [Str txt] ('#':linknode i,txt)
+    renderIncoming i = let l@(_,txt) = localLink variables i
+        in Link ("",["incoming"],[]) [Str txt] l
+    renderOutgoing i = let l@(_,txt) = localLink variables i
+        in Link ("",["outgoing"],[]) [Str txt] l
     renderVariable i = let 
         Just desc = getDescription i variables
         how = foldMap (\(_,_,f) -> Set.singleton f) (inn (dependencyGraph variables) i)
         sayhow = if Set.null how then [] else [Div ("",["edges"],[]) $ (Div ("",["provenienceKeyword"],[]) [Para [i18n_construction i18n]]):(Set.toList how)]
         short = case shortname desc of
             Nothing -> []
-            Just name -> [Header 3 ("",["shortname"],[]) [Str name]]
+            Just name -> [Header 3 ("",["shortname"],[]) (inlinesString name)]
         sources = case pre (dependencyGraph variables) i of
             [] -> []
             js@(_:_) -> [Div ("",["provenienceKeyword"],[]) [Para [i18n_incoming i18n]],BulletList $ map (pure . Plain . pure . renderIncoming) js]
         sinks = case suc (dependencyGraph variables) i of
             [] -> []
             js@(_:_) -> [Div ("",["provenienceKeyword"],[]) [Para [i18n_outgoing i18n]],BulletList $ map (pure . Plain . pure . renderOutgoing) js]
-        in Div (linknode i,["variable"],[]) $ short++sources++sayhow++sinks++[
+        in divVar i $ short++sources++sayhow++sinks++[
             HorizontalRule,
             Div ("",["description"],[]) [description desc],
             Div ("",["valueRendering"],[]) [valueRendering desc]]
     (n0,n1) = nodeRange (dependencyGraph variables) 
-    in Div ("variables"++(showHex n0 ("To"++(showHex n1 ""))),["provenienceVariables"],[]) (map renderVariable nodelist)
+    in divVars (nodeRange (dependencyGraph variables)) (map renderVariable nodelist)
 
 -- | When the alternative representation is in terms of spreadsheet rows, 
 -- we can assemble the 'VariableStore' into a spreadheet. 
@@ -457,8 +484,8 @@
 linkto :: Monad m => Variable a -> StateT (VariableStore alt) m Inline
 linkto v = do
     store <- get
-    let linktext = maybe (linkname v) id (getShortname (identifier v) store)
-    return $ Link nullAttr [Str linktext] ('#':linkname v,linktext)
+    let l@(_,linktext) = localLink store (identifier v)
+    return $ Link nullAttr [Str linktext] l
 
 -- | Run the Provenience monad and return the value of the result variable 
 -- together with the 'VariableStore' and its next unused 'Node'. 
