diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+## 0.3.1.0
+
+-   Update documentation
+-   Tweak default secHeaderDelim
+-   Test for secHeaderTemplate and indexed template variables
+-   New template syntax: indexed variables
+-   secHeaderTemplate
+-   Escape underscores in codeblock captions when necessary
+-   Travis set sudo: true
+-   Allow newer in stack.yaml
+-   Set license to GPL-2 (because hackage refuses to accept GPL now)
+
 ## 0.3.0.3
 
 -   Fix for Pandoc's Monoid\/Semigroup change
diff --git a/docs/index.md b/docs/index.md
--- a/docs/index.md
+++ b/docs/index.md
@@ -239,6 +239,15 @@
 Otherwise, only header levels up to and including `sectionsDepth` will
 be numbered.
 
+You can also supply a custom section header template via `secHeaderTemplate`
+metadata option. The following variables are supported:
+
+-   `$$i$$` -- formatted section number, according to `sectionsDepth`
+-   `$$t$$` -- original section header text
+-   `$$n$$` -- 0-indexed section level (0 is the topmost)
+
+See [section on templates](#templates) for more information
+
 ## Section reference labels
 
 ***Not currently supported with LaTeX output***
@@ -481,6 +490,8 @@
     titles, e.g. `Listing 1: Description`
 -   `titleDelim`, default `:`: What to put between object number and
     caption text.
+-   `secHeaderDelim`, default ` ` (i.e. space): What to put between section
+    number and title when `numberSections` is `true`.
 
 #### Subfigure-specific
 
@@ -585,6 +596,9 @@
 -   `listingTemplate`, default
     `$$listingTitle$$ $$i$$$$titleDelim$$ $$t$$`: template for listing
     captions
+-   `secHeaderTemplate`, default `$$i$$$$secHeaderDelim$$$$t$$`: template for
+    section header
+    text when `numberSections` is `true`
 
 #### Subfigure templates
 
@@ -680,6 +694,28 @@
 markdown, but instead have `p` variable, that binds to relevant
 `xPrefix`. This is done this way, since actual prefix vaule can depend
 on `i`.
+
+Additionally, a special syntax is provided for indexed access to array metadata variables: `arrayVariable[indexVariable]`, where `arrayVariable` is an array-like metadata variable, and `indexVariable` is an integer-typed template variable.
+If `indexVariable` is larger than length of `arrayVariable`, then the last
+element in `arrayVariable` is used.
+
+Indexed access can be useful with `secHeaderTemplate` for example, where you
+might want to add a custom prefix depending on the header level.
+
+For example, with this YAML metadata:
+
+``` yaml
+secHeaderTemplate: $$secHeaderPrefix[n]$$$$i$$. $$t$$
+secHeaderPrefix:
+  - "Chapter&#32;"
+  - "Section&#32;"
+  - ""
+sectionsDepth: -1
+numberSections: true
+```
+
+top-level sections will be prefixed with `Chapter `, second-level sections will
+be prefixed with `Section ` and the rest won't be prefixed with anything.
 
 Please note that at the moment, templates are not supported with
 LaTeX/PDF output.
diff --git a/lib/Text/Pandoc/CrossRef/References/Blocks.hs b/lib/Text/Pandoc/CrossRef/References/Blocks.hs
--- a/lib/Text/Pandoc/CrossRef/References/Blocks.hs
+++ b/lib/Text/Pandoc/CrossRef/References/Blocks.hs
@@ -77,9 +77,14 @@
         }
     cc <- get curChap
     let textCC | numberSections opts
-               , sectionsDepth opts < 0 || n <= if sectionsDepth opts == 0 then chaptersDepth opts else sectionsDepth opts
+               , sectionsDepth opts < 0
+               || n <= if sectionsDepth opts == 0 then chaptersDepth opts else sectionsDepth opts
                , "unnumbered" `notElem` cls
-               = Str (intercalate "." $ map show' cc) : Space : text'
+               = applyTemplate' (M.fromDistinctAscList [
+                    ("i", [Str (intercalate "." $ map show' cc)])
+                  , ("n", [Str $ show $ n - 1])
+                  , ("t", text')
+                  ]) $ secHeaderTemplate opts
                | otherwise = text'
         show' (_, Just s) = s
         show' (i, Nothing) = show i
@@ -185,8 +190,12 @@
         --if not using listings, however, wrap it in a codelisting environment
         | isLatexFormat f ->
           replaceNoRecurse $ Div nullAttr [
-              RawBlock (Format "latex")
-                $ "\\begin{codelisting}\n\\caption{"++caption++"}"
+              RawBlock (Format "latex") "\\begin{codelisting}"
+            , Plain [
+                RawInline (Format "latex") "\\caption{"
+              , Str caption
+              , RawInline (Format "latex") "}"
+              ]
             , cb
             , RawBlock (Format "latex") "\\end{codelisting}"
             ]
diff --git a/lib/Text/Pandoc/CrossRef/Util/Options.hs b/lib/Text/Pandoc/CrossRef/Util/Options.hs
--- a/lib/Text/Pandoc/CrossRef/Util/Options.hs
+++ b/lib/Text/Pandoc/CrossRef/Util/Options.hs
@@ -41,6 +41,7 @@
                        , secPrefixTemplate :: Template
                        , refIndexTemplate :: Template
                        , subfigureRefIndexTemplate :: Template
+                       , secHeaderTemplate :: Template
                        , chapDelim   :: [Inline]
                        , rangeDelim  :: [Inline]
                        , pairDelim  :: [Inline]
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings.hs b/lib/Text/Pandoc/CrossRef/Util/Settings.hs
--- a/lib/Text/Pandoc/CrossRef/Util/Settings.hs
+++ b/lib/Text/Pandoc/CrossRef/Util/Settings.hs
@@ -91,6 +91,8 @@
   <> secPrefixTemplate (var "p" <> str "\160" <> var "i")
   <> refIndexTemplate (var "i" <> var "suf")
   <> subfigureRefIndexTemplate (var "i" <> var "suf" <> space <> str "(" <> var "s" <> str ")")
+  <> secHeaderTemplate (var "i" <> var "secHeaderDelim" <> var "t")
+  <> secHeaderDelim space
   <> lofTitle (header 1 $ text "List of Figures")
   <> lotTitle (header 1 $ text "List of Tables")
   <> lolTitle (header 1 $ text "List of Listings")
diff --git a/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs b/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
--- a/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
+++ b/lib/Text/Pandoc/CrossRef/Util/Settings/Gen.hs
@@ -43,6 +43,7 @@
   , "tblLabels"
   , "lstLabels"
   , "secLabels"
+  , "secHeaderDelim"
   ]
 
 getOptions :: Meta -> Maybe Format -> Options
diff --git a/lib/Text/Pandoc/CrossRef/Util/Template.hs b/lib/Text/Pandoc/CrossRef/Util/Template.hs
--- a/lib/Text/Pandoc/CrossRef/Util/Template.hs
+++ b/lib/Text/Pandoc/CrossRef/Util/Template.hs
@@ -28,9 +28,10 @@
 import Text.Pandoc.Definition
 import Text.Pandoc.Builder
 import Text.Pandoc.Generic
-import Data.Map as M hiding (toList, fromList, singleton)
+import qualified Data.Map as M hiding (toList, fromList, singleton)
 import Text.Pandoc.CrossRef.Util.Meta
 import Control.Applicative
+import Text.Read
 
 type VarFunc = String -> Maybe MetaValue
 newtype Template = Template (VarFunc -> [Inline])
@@ -39,12 +40,22 @@
 makeTemplate dtv xs' = Template $ \vf -> scan (\var -> vf var <|> lookupMeta var dtv) xs'
   where
   scan = bottomUp . go
-  go vf (x@(Math DisplayMath var):xs) = toList $ fromList (replaceVar var (vf var) [x]) <> fromList xs
+  go vf (x@(Math DisplayMath var):xs)
+    | '[' `elem` var  && ']' == last var =
+      let (vn, idxBr) = span (/='[') var
+          idxVar = drop 1 $ takeWhile (/=']') idxBr
+          idx = readMaybe . toString ("index variable " ++ idxVar) =<< (vf idxVar)
+          arr = do
+            i <- idx
+            v <- lookupMeta vn dtv
+            getList i v
+      in toList $ fromList (replaceVar var arr [x]) <> fromList xs
+    | otherwise = toList $ fromList (replaceVar var (vf var) [x]) <> fromList xs
   go _ (x:xs) = toList $ singleton x <> fromList xs
   go _ [] = []
   replaceVar var val def' = maybe def' (toInlines ("variable " ++ var)) val
 
-applyTemplate' :: Map String [Inline] -> Template -> [Inline]
+applyTemplate' :: M.Map String [Inline] -> Template -> [Inline]
 applyTemplate' vars (Template g) = g internalVars
   where
   internalVars x | Just v <- M.lookup x vars = Just $ MetaInlines v
@@ -52,4 +63,4 @@
 
 applyTemplate :: [Inline] -> [Inline] -> Template -> [Inline]
 applyTemplate i t =
-  applyTemplate' (fromDistinctAscList [("i", i), ("t", t)])
+  applyTemplate' (M.fromDistinctAscList [("i", i), ("t", t)])
diff --git a/pandoc-crossref.cabal b/pandoc-crossref.cabal
--- a/pandoc-crossref.cabal
+++ b/pandoc-crossref.cabal
@@ -2,10 +2,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 6dc64b43875892f6af97cfecf66ae1f17064bb4d70c7c6011b856228f2e4e81e
+-- hash: 1134f5ed99f27ba306513fcd6aecbd132e1238e315eade16a2155173959174b8
 
 name:           pandoc-crossref
-version:        0.3.0.3
+version:        0.3.1.0
 synopsis:       Pandoc filter for cross-references
 description:    pandoc-crossref is a pandoc filter for numbering figures, equations, tables and cross-references to them.
 category:       Text
@@ -50,6 +50,9 @@
     test/m2m/listing-captions-ids/expect.md
     test/m2m/listing-captions-ids/expect.tex
     test/m2m/listing-captions-ids/input.md
+    test/m2m/section-template/expect.md
+    test/m2m/section-template/expect.tex
+    test/m2m/section-template/input.md
     test/m2m/subfigures-ccsDelim/expect.md
     test/m2m/subfigures-ccsDelim/expect.tex
     test/m2m/subfigures-ccsDelim/input.md
diff --git a/test/m2m/section-template/expect.md b/test/m2m/section-template/expect.md
new file mode 100644
--- /dev/null
+++ b/test/m2m/section-template/expect.md
@@ -0,0 +1,13 @@
+Chapter 1. First Level Section {#first-level-section}
+==============================
+
+Section 1.1. Second Level Section {#second-level-section}
+---------------------------------
+
+### Paragraph 1.1.1. Thrid Level Section {#thrid-level-section}
+
+#### 1.1.1.1. Fourth Level Section
+
+##### 1.1.1.1.1. Fifth Level Section
+
+###### 1.1.1.1.1.1. Sixth Level Section
diff --git a/test/m2m/section-template/expect.tex b/test/m2m/section-template/expect.tex
new file mode 100644
--- /dev/null
+++ b/test/m2m/section-template/expect.tex
@@ -0,0 +1,19 @@
+\hypertarget{first-level-section}{%
+\section{Chapter 1. First Level Section}\label{first-level-section}}
+
+\hypertarget{second-level-section}{%
+\subsection{Section 1.1. Second Level
+Section}\label{second-level-section}}
+
+\hypertarget{thrid-level-section}{%
+\subsubsection{Paragraph 1.1.1. Thrid Level
+Section}\label{thrid-level-section}}
+
+\hypertarget{fourth-level-section}{%
+\paragraph{1.1.1.1. Fourth Level Section}\label{fourth-level-section}}
+
+\hypertarget{fifth-level-section}{%
+\subparagraph{1.1.1.1.1. Fifth Level
+Section}\label{fifth-level-section}}
+
+1.1.1.1.1.1. Sixth Level Section
diff --git a/test/m2m/section-template/input.md b/test/m2m/section-template/input.md
new file mode 100644
--- /dev/null
+++ b/test/m2m/section-template/input.md
@@ -0,0 +1,22 @@
+---
+secHeaderTemplate: $$secHeaderPrefix[n]$$$$i$$. $$t$$
+secHeaderPrefix:
+  - "Chapter&#32;"
+  - "Section&#32;"
+  - "Paragraph&#32;"
+  - ""
+sectionsDepth: -1
+numberSections: true
+---
+
+# First Level Section
+
+## Second Level Section
+
+### Thrid Level Section
+
+#### Fourth Level Section
+
+##### Fifth Level Section
+
+###### Sixth Level Section
diff --git a/test/test-pandoc-crossref.hs b/test/test-pandoc-crossref.hs
--- a/test/test-pandoc-crossref.hs
+++ b/test/test-pandoc-crossref.hs
@@ -315,7 +315,10 @@
         it "Code block labels" $ do
           codeBlock' "A code block" "some_codeblock1"
             <> para (citeGen "lst:some_codeblock" [1])
-            `test` "\\begin{codelisting}\n\\caption{A code block}\n\n\\hypertarget{lst:some_codeblock1}{%\n\\label{lst:some_codeblock1}}%\n\\begin{Shaded}\n\\begin{Highlighting}[]\n\\OtherTok{main ::} \\DataTypeTok{IO}\\NormalTok{ ()}\n\\end{Highlighting}\n\\end{Shaded}\n\n\\end{codelisting}\n\nlst.~\\ref{lst:some_codeblock1}"
+            `test` "\\begin{codelisting}\n\n\\caption{A code block}\n\n\\hypertarget{lst:some_codeblock1}{%\n\\label{lst:some_codeblock1}}%\n\\begin{Shaded}\n\\begin{Highlighting}[]\n\\OtherTok{main ::} \\DataTypeTok{IO}\\NormalTok{ ()}\n\\end{Highlighting}\n\\end{Shaded}\n\n\\end{codelisting}\n\nlst.~\\ref{lst:some_codeblock1}"
+          codeBlock' "A code block with under_score" "some_codeblock1"
+            <> para (citeGen "lst:some_codeblock" [1])
+            `test` "\\begin{codelisting}\n\n\\caption{A code block with under\\_score}\n\n\\hypertarget{lst:some_codeblock1}{%\n\\label{lst:some_codeblock1}}%\n\\begin{Shaded}\n\\begin{Highlighting}[]\n\\OtherTok{main ::} \\DataTypeTok{IO}\\NormalTok{ ()}\n\\end{Highlighting}\n\\end{Shaded}\n\n\\end{codelisting}\n\nlst.~\\ref{lst:some_codeblock1}"
           let test1 = test' $ setMeta "codeBlockCaptions" True nullMeta
               infixr 5 `test1`
           codeBlockForTable "some_codeblock1" <> paraText ": A code block"
