diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Stache 0.1.8
+
+* Rename `specs` directory to `specification` as the previous name somehow
+  caused conflicts when deploying an application on Heroku with Stache as a
+  dependency.
+
 ## Stache 0.1.7
 
 * Added `mustache` quasi-quoter.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@
 render them.
 
 The implementation uses the Megaparsec parsing library to parse the
-templates which is results in superior quality of error messages.
+templates which results in superior quality of error messages.
 
 For rendering you only need to create Aeson's `Value` where you put the data
 to interpolate. Since the library re-uses Aeson's instances and most data
diff --git a/Text/Mustache.hs b/Text/Mustache.hs
--- a/Text/Mustache.hs
+++ b/Text/Mustache.hs
@@ -15,7 +15,7 @@
 -- text) and one to render them.
 --
 -- The implementation uses the Megaparsec parsing library to parse the
--- templates which is results in superior quality of error messages.
+-- templates which results in superior quality of error messages.
 --
 -- For rendering you only need to create Aeson's 'Data.Aeson.Value' where
 -- you put the data to interpolate. Since the library re-uses Aeson's
diff --git a/mustache-spec/Spec.hs b/mustache-spec/Spec.hs
--- a/mustache-spec/Spec.hs
+++ b/mustache-spec/Spec.hs
@@ -58,12 +58,12 @@
 
 spec :: Spec
 spec = do
-  specData "Comments"      $(embedFile "specs/comments.yml")
-  specData "Delimiters"    $(embedFile "specs/delimiters.yml")
-  specData "Interpolation" $(embedFile "specs/interpolation.yml")
-  specData "Inverted"      $(embedFile "specs/inverted.yml")
-  specData "Partials"      $(embedFile "specs/partials.yml")
-  specData "Sections"      $(embedFile "specs/sections.yml")
+  specData "Comments"      $(embedFile "specification/comments.yml")
+  specData "Delimiters"    $(embedFile "specification/delimiters.yml")
+  specData "Interpolation" $(embedFile "specification/interpolation.yml")
+  specData "Inverted"      $(embedFile "specification/inverted.yml")
+  specData "Partials"      $(embedFile "specification/partials.yml")
+  specData "Sections"      $(embedFile "specification/sections.yml")
 
 specData :: String -> ByteString -> Spec
 specData aspect bytes = describe aspect $ do
diff --git a/specification/comments.yml b/specification/comments.yml
new file mode 100644
--- /dev/null
+++ b/specification/comments.yml
@@ -0,0 +1,103 @@
+overview: |
+  Comment tags represent content that should never appear in the resulting
+  output.
+
+  The tag's content may contain any substring (including newlines) EXCEPT the
+  closing delimiter.
+
+  Comment tags SHOULD be treated as standalone when appropriate.
+tests:
+  - name: Inline
+    desc: Comment blocks should be removed from the template.
+    data: { }
+    template: '12345{{! Comment Block! }}67890'
+    expected: '1234567890'
+
+  - name: Multiline
+    desc: Multiline comments should be permitted.
+    data: { }
+    template: |
+      12345{{!
+        This is a
+        multi-line comment...
+      }}67890
+    expected: |
+      1234567890
+
+  - name: Standalone
+    desc: All standalone comment lines should be removed.
+    data: { }
+    template: |
+      Begin.
+      {{! Comment Block! }}
+      End.
+    expected: |
+      Begin.
+      End.
+
+  - name: Indented Standalone
+    desc: All standalone comment lines should be removed.
+    data: { }
+    template: |
+      Begin.
+        {{! Indented Comment Block! }}
+      End.
+    expected: |
+      Begin.
+      End.
+
+  - name: Standalone Line Endings
+    desc: '"\r\n" should be considered a newline for standalone tags.'
+    data: { }
+    template: "|\r\n{{! Standalone Comment }}\r\n|"
+    expected: "|\r\n|"
+
+  - name: Standalone Without Previous Line
+    desc: Standalone tags should not require a newline to precede them.
+    data: { }
+    template: "  {{! I'm Still Standalone }}\n!"
+    expected: "!"
+
+  - name: Standalone Without Newline
+    desc: Standalone tags should not require a newline to follow them.
+    data: { }
+    template: "!\n  {{! I'm Still Standalone }}"
+    expected: "!\n"
+
+  - name: Multiline Standalone
+    desc: All standalone comment lines should be removed.
+    data: { }
+    template: |
+      Begin.
+      {{!
+      Something's going on here...
+      }}
+      End.
+    expected: |
+      Begin.
+      End.
+
+  - name: Indented Multiline Standalone
+    desc: All standalone comment lines should be removed.
+    data: { }
+    template: |
+      Begin.
+        {{!
+          Something's going on here...
+        }}
+      End.
+    expected: |
+      Begin.
+      End.
+
+  - name: Indented Inline
+    desc: Inline comments should not strip whitespace
+    data: { }
+    template: "  12 {{! 34 }}\n"
+    expected: "  12 \n"
+
+  - name: Surrounding Whitespace
+    desc: Comment removal should preserve surrounding whitespace.
+    data: { }
+    template: '12345 {{! Comment Block! }} 67890'
+    expected: '12345  67890'
diff --git a/specification/delimiters.yml b/specification/delimiters.yml
new file mode 100644
--- /dev/null
+++ b/specification/delimiters.yml
@@ -0,0 +1,158 @@
+overview: |
+  Set Delimiter tags are used to change the tag delimiters for all content
+  following the tag in the current compilation unit.
+
+  The tag's content MUST be any two non-whitespace sequences (separated by
+  whitespace) EXCEPT an equals sign ('=') followed by the current closing
+  delimiter.
+
+  Set Delimiter tags SHOULD be treated as standalone when appropriate.
+tests:
+  - name: Pair Behavior
+    desc: The equals sign (used on both sides) should permit delimiter changes.
+    data: { text: 'Hey!' }
+    template: '{{=<% %>=}}(<%text%>)'
+    expected: '(Hey!)'
+
+  - name: Special Characters
+    desc: Characters with special meaning regexen should be valid delimiters.
+    data: { text: 'It worked!' }
+    template: '({{=[ ]=}}[text])'
+    expected: '(It worked!)'
+
+  - name: Sections
+    desc: Delimiters set outside sections should persist.
+    data: { section: true, data: 'I got interpolated.' }
+    template: |
+      [
+      {{#section}}
+        {{data}}
+        |data|
+      {{/section}}
+
+      {{= | | =}}
+      |#section|
+        {{data}}
+        |data|
+      |/section|
+      ]
+    expected: |
+      [
+        I got interpolated.
+        |data|
+
+        {{data}}
+        I got interpolated.
+      ]
+
+  - name: Inverted Sections
+    desc: Delimiters set outside inverted sections should persist.
+    data: { section: false, data: 'I got interpolated.' }
+    template: |
+      [
+      {{^section}}
+        {{data}}
+        |data|
+      {{/section}}
+
+      {{= | | =}}
+      |^section|
+        {{data}}
+        |data|
+      |/section|
+      ]
+    expected: |
+      [
+        I got interpolated.
+        |data|
+
+        {{data}}
+        I got interpolated.
+      ]
+
+  - name: Partial Inheritence
+    desc: Delimiters set in a parent template should not affect a partial.
+    data: { value: 'yes' }
+    partials:
+      include: '.{{value}}.'
+    template: |
+      [ {{>include}} ]
+      {{= | | =}}
+      [ |>include| ]
+    expected: |
+      [ .yes. ]
+      [ .yes. ]
+
+  - name: Post-Partial Behavior
+    desc: Delimiters set in a partial should not affect the parent template.
+    data: { value: 'yes' }
+    partials:
+      include: '.{{value}}. {{= | | =}} .|value|.'
+    template: |
+      [ {{>include}} ]
+      [ .{{value}}.  .|value|. ]
+    expected: |
+      [ .yes.  .yes. ]
+      [ .yes.  .|value|. ]
+
+  # Whitespace Sensitivity
+
+  - name: Surrounding Whitespace
+    desc: Surrounding whitespace should be left untouched.
+    data: { }
+    template: '| {{=@ @=}} |'
+    expected: '|  |'
+
+  - name: Outlying Whitespace (Inline)
+    desc: Whitespace should be left untouched.
+    data: { }
+    template: " | {{=@ @=}}\n"
+    expected: " | \n"
+
+  - name: Standalone Tag
+    desc: Standalone lines should be removed from the template.
+    data: { }
+    template: |
+      Begin.
+      {{=@ @=}}
+      End.
+    expected: |
+      Begin.
+      End.
+
+  - name: Indented Standalone Tag
+    desc: Indented standalone lines should be removed from the template.
+    data: { }
+    template: |
+      Begin.
+        {{=@ @=}}
+      End.
+    expected: |
+      Begin.
+      End.
+
+  - name: Standalone Line Endings
+    desc: '"\r\n" should be considered a newline for standalone tags.'
+    data: { }
+    template: "|\r\n{{= @ @ =}}\r\n|"
+    expected: "|\r\n|"
+
+  - name: Standalone Without Previous Line
+    desc: Standalone tags should not require a newline to precede them.
+    data: { }
+    template: "  {{=@ @=}}\n="
+    expected: "="
+
+  - name: Standalone Without Newline
+    desc: Standalone tags should not require a newline to follow them.
+    data: { }
+    template: "=\n  {{=@ @=}}"
+    expected: "=\n"
+
+  # Whitespace Insensitivity
+
+  - name: Pair with Padding
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { }
+    template: '|{{= @   @ =}}|'
+    expected: '||'
diff --git a/specification/interpolation.yml b/specification/interpolation.yml
new file mode 100644
--- /dev/null
+++ b/specification/interpolation.yml
@@ -0,0 +1,238 @@
+overview: |
+  Interpolation tags are used to integrate dynamic content into the template.
+
+  The tag's content MUST be a non-whitespace character sequence NOT containing
+  the current closing delimiter.
+
+  This tag's content names the data to replace the tag.  A single period (`.`)
+  indicates that the item currently sitting atop the context stack should be
+  used; otherwise, name resolution is as follows:
+    1) Split the name on periods; the first part is the name to resolve, any
+    remaining parts should be retained.
+    2) Walk the context stack from top to bottom, finding the first context
+    that is a) a hash containing the name as a key OR b) an object responding
+    to a method with the given name.
+    3) If the context is a hash, the data is the value associated with the
+    name.
+    4) If the context is an object, the data is the value returned by the
+    method with the given name.
+    5) If any name parts were retained in step 1, each should be resolved
+    against a context stack containing only the result from the former
+    resolution.  If any part fails resolution, the result should be considered
+    falsey, and should interpolate as the empty string.
+  Data should be coerced into a string (and escaped, if appropriate) before
+  interpolation.
+
+  The Interpolation tags MUST NOT be treated as standalone.
+tests:
+  - name: No Interpolation
+    desc: Mustache-free templates should render as-is.
+    data: { }
+    template: |
+      Hello from {Mustache}!
+    expected: |
+      Hello from {Mustache}!
+
+  - name: Basic Interpolation
+    desc: Unadorned tags should interpolate content into the template.
+    data: { subject: "world" }
+    template: |
+      Hello, {{subject}}!
+    expected: |
+      Hello, world!
+
+  - name: HTML Escaping
+    desc: Basic interpolation should be HTML escaped.
+    data: { forbidden: '& " < >' }
+    template: |
+      These characters should be HTML escaped: {{forbidden}}
+    expected: |
+      These characters should be HTML escaped: &amp; &quot; &lt; &gt;
+
+  - name: Triple Mustache
+    desc: Triple mustaches should interpolate without HTML escaping.
+    data: { forbidden: '& " < >' }
+    template: |
+      These characters should not be HTML escaped: {{{forbidden}}}
+    expected: |
+      These characters should not be HTML escaped: & " < >
+
+  - name: Ampersand
+    desc: Ampersand should interpolate without HTML escaping.
+    data: { forbidden: '& " < >' }
+    template: |
+      These characters should not be HTML escaped: {{&forbidden}}
+    expected: |
+      These characters should not be HTML escaped: & " < >
+
+  - name: Basic Integer Interpolation
+    desc: Integers should interpolate seamlessly.
+    data: { mph: 85 }
+    template: '"{{mph}} miles an hour!"'
+    expected: '"85 miles an hour!"'
+
+  - name: Triple Mustache Integer Interpolation
+    desc: Integers should interpolate seamlessly.
+    data: { mph: 85 }
+    template: '"{{{mph}}} miles an hour!"'
+    expected: '"85 miles an hour!"'
+
+  - name: Ampersand Integer Interpolation
+    desc: Integers should interpolate seamlessly.
+    data: { mph: 85 }
+    template: '"{{&mph}} miles an hour!"'
+    expected: '"85 miles an hour!"'
+
+  - name: Basic Decimal Interpolation
+    desc: Decimals should interpolate seamlessly with proper significance.
+    data: { power: 1.210 }
+    template: '"{{power}} jiggawatts!"'
+    expected: '"1.21 jiggawatts!"'
+
+  - name: Triple Mustache Decimal Interpolation
+    desc: Decimals should interpolate seamlessly with proper significance.
+    data: { power: 1.210 }
+    template: '"{{{power}}} jiggawatts!"'
+    expected: '"1.21 jiggawatts!"'
+
+  - name: Ampersand Decimal Interpolation
+    desc: Decimals should interpolate seamlessly with proper significance.
+    data: { power: 1.210 }
+    template: '"{{&power}} jiggawatts!"'
+    expected: '"1.21 jiggawatts!"'
+
+  # Context Misses
+
+  - name: Basic Context Miss Interpolation
+    desc: Failed context lookups should default to empty strings.
+    data: { }
+    template: "I ({{cannot}}) be seen!"
+    expected: "I () be seen!"
+
+  - name: Triple Mustache Context Miss Interpolation
+    desc: Failed context lookups should default to empty strings.
+    data: { }
+    template: "I ({{{cannot}}}) be seen!"
+    expected: "I () be seen!"
+
+  - name: Ampersand Context Miss Interpolation
+    desc: Failed context lookups should default to empty strings.
+    data: { }
+    template: "I ({{&cannot}}) be seen!"
+    expected: "I () be seen!"
+
+  # Dotted Names
+
+  - name: Dotted Names - Basic Interpolation
+    desc: Dotted names should be considered a form of shorthand for sections.
+    data: { person: { name: 'Joe' } }
+    template: '"{{person.name}}" == "{{#person}}{{name}}{{/person}}"'
+    expected: '"Joe" == "Joe"'
+
+  - name: Dotted Names - Triple Mustache Interpolation
+    desc: Dotted names should be considered a form of shorthand for sections.
+    data: { person: { name: 'Joe' } }
+    template: '"{{{person.name}}}" == "{{#person}}{{{name}}}{{/person}}"'
+    expected: '"Joe" == "Joe"'
+
+  - name: Dotted Names - Ampersand Interpolation
+    desc: Dotted names should be considered a form of shorthand for sections.
+    data: { person: { name: 'Joe' } }
+    template: '"{{&person.name}}" == "{{#person}}{{&name}}{{/person}}"'
+    expected: '"Joe" == "Joe"'
+
+  - name: Dotted Names - Arbitrary Depth
+    desc: Dotted names should be functional to any level of nesting.
+    data:
+      a: { b: { c: { d: { e: { name: 'Phil' } } } } }
+    template: '"{{a.b.c.d.e.name}}" == "Phil"'
+    expected: '"Phil" == "Phil"'
+
+  - name: Dotted Names - Broken Chains
+    desc: Any falsey value prior to the last part of the name should yield ''.
+    data:
+      a: { }
+    template: '"{{a.b.c}}" == ""'
+    expected: '"" == ""'
+
+  - name: Dotted Names - Broken Chain Resolution
+    desc: Each part of a dotted name should resolve only against its parent.
+    data:
+      a: { b: { } }
+      c: { name: 'Jim' }
+    template: '"{{a.b.c.name}}" == ""'
+    expected: '"" == ""'
+
+  - name: Dotted Names - Initial Resolution
+    desc: The first part of a dotted name should resolve as any other name.
+    data:
+      a: { b: { c: { d: { e: { name: 'Phil' } } } } }
+      b: { c: { d: { e: { name: 'Wrong' } } } }
+    template: '"{{#a}}{{b.c.d.e.name}}{{/a}}" == "Phil"'
+    expected: '"Phil" == "Phil"'
+
+  - name: Dotted Names - Context Precedence
+    desc: Dotted names should be resolved against former resolutions.
+    data:
+      a: { b: { } }
+      b: { c: 'ERROR' }
+    template: '{{#a}}{{b.c}}{{/a}}'
+    expected: ''
+
+  # Whitespace Sensitivity
+
+  - name: Interpolation - Surrounding Whitespace
+    desc: Interpolation should not alter surrounding whitespace.
+    data: { string: '---' }
+    template: '| {{string}} |'
+    expected: '| --- |'
+
+  - name: Triple Mustache - Surrounding Whitespace
+    desc: Interpolation should not alter surrounding whitespace.
+    data: { string: '---' }
+    template: '| {{{string}}} |'
+    expected: '| --- |'
+
+  - name: Ampersand - Surrounding Whitespace
+    desc: Interpolation should not alter surrounding whitespace.
+    data: { string: '---' }
+    template: '| {{&string}} |'
+    expected: '| --- |'
+
+  - name: Interpolation - Standalone
+    desc: Standalone interpolation should not alter surrounding whitespace.
+    data: { string: '---' }
+    template: "  {{string}}\n"
+    expected: "  ---\n"
+
+  - name: Triple Mustache - Standalone
+    desc: Standalone interpolation should not alter surrounding whitespace.
+    data: { string: '---' }
+    template: "  {{{string}}}\n"
+    expected: "  ---\n"
+
+  - name: Ampersand - Standalone
+    desc: Standalone interpolation should not alter surrounding whitespace.
+    data: { string: '---' }
+    template: "  {{&string}}\n"
+    expected: "  ---\n"
+
+  # Whitespace Insensitivity
+
+  - name: Interpolation With Padding
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { string: "---" }
+    template: '|{{ string }}|'
+    expected: '|---|'
+
+  - name: Triple Mustache With Padding
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { string: "---" }
+    template: '|{{{ string }}}|'
+    expected: '|---|'
+
+  - name: Ampersand With Padding
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { string: "---" }
+    template: '|{{& string }}|'
+    expected: '|---|'
diff --git a/specification/inverted.yml b/specification/inverted.yml
new file mode 100644
--- /dev/null
+++ b/specification/inverted.yml
@@ -0,0 +1,193 @@
+overview: |
+  Inverted Section tags and End Section tags are used in combination to wrap a
+  section of the template.
+
+  These tags' content MUST be a non-whitespace character sequence NOT
+  containing the current closing delimiter; each Inverted Section tag MUST be
+  followed by an End Section tag with the same content within the same
+  section.
+
+  This tag's content names the data to replace the tag.  Name resolution is as
+  follows:
+    1) Split the name on periods; the first part is the name to resolve, any
+    remaining parts should be retained.
+    2) Walk the context stack from top to bottom, finding the first context
+    that is a) a hash containing the name as a key OR b) an object responding
+    to a method with the given name.
+    3) If the context is a hash, the data is the value associated with the
+    name.
+    4) If the context is an object and the method with the given name has an
+    arity of 1, the method SHOULD be called with a String containing the
+    unprocessed contents of the sections; the data is the value returned.
+    5) Otherwise, the data is the value returned by calling the method with
+    the given name.
+    6) If any name parts were retained in step 1, each should be resolved
+    against a context stack containing only the result from the former
+    resolution.  If any part fails resolution, the result should be considered
+    falsey, and should interpolate as the empty string.
+  If the data is not of a list type, it is coerced into a list as follows: if
+  the data is truthy (e.g. `!!data == true`), use a single-element list
+  containing the data, otherwise use an empty list.
+
+  This section MUST NOT be rendered unless the data list is empty.
+
+  Inverted Section and End Section tags SHOULD be treated as standalone when
+  appropriate.
+tests:
+  - name: Falsey
+    desc: Falsey sections should have their contents rendered.
+    data: { boolean: false }
+    template: '"{{^boolean}}This should be rendered.{{/boolean}}"'
+    expected: '"This should be rendered."'
+
+  - name: Truthy
+    desc: Truthy sections should have their contents omitted.
+    data: { boolean: true }
+    template: '"{{^boolean}}This should not be rendered.{{/boolean}}"'
+    expected: '""'
+
+  - name: Context
+    desc: Objects and hashes should behave like truthy values.
+    data: { context: { name: 'Joe' } }
+    template: '"{{^context}}Hi {{name}}.{{/context}}"'
+    expected: '""'
+
+  - name: List
+    desc: Lists should behave like truthy values.
+    data: { list: [ { n: 1 }, { n: 2 }, { n: 3 } ] }
+    template: '"{{^list}}{{n}}{{/list}}"'
+    expected: '""'
+
+  - name: Empty List
+    desc: Empty lists should behave like falsey values.
+    data: { list: [ ] }
+    template: '"{{^list}}Yay lists!{{/list}}"'
+    expected: '"Yay lists!"'
+
+  - name: Doubled
+    desc: Multiple inverted sections per template should be permitted.
+    data: { bool: false, two: 'second' }
+    template: |
+      {{^bool}}
+      * first
+      {{/bool}}
+      * {{two}}
+      {{^bool}}
+      * third
+      {{/bool}}
+    expected: |
+      * first
+      * second
+      * third
+
+  - name: Nested (Falsey)
+    desc: Nested falsey sections should have their contents rendered.
+    data: { bool: false }
+    template: "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |"
+    expected: "| A B C D E |"
+
+  - name: Nested (Truthy)
+    desc: Nested truthy sections should be omitted.
+    data: { bool: true }
+    template: "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |"
+    expected: "| A  E |"
+
+  - name: Context Misses
+    desc: Failed context lookups should be considered falsey.
+    data: { }
+    template: "[{{^missing}}Cannot find key 'missing'!{{/missing}}]"
+    expected: "[Cannot find key 'missing'!]"
+
+  # Dotted Names
+
+  - name: Dotted Names - Truthy
+    desc: Dotted names should be valid for Inverted Section tags.
+    data: { a: { b: { c: true } } }
+    template: '"{{^a.b.c}}Not Here{{/a.b.c}}" == ""'
+    expected: '"" == ""'
+
+  - name: Dotted Names - Falsey
+    desc: Dotted names should be valid for Inverted Section tags.
+    data: { a: { b: { c: false } } }
+    template: '"{{^a.b.c}}Not Here{{/a.b.c}}" == "Not Here"'
+    expected: '"Not Here" == "Not Here"'
+
+  - name: Dotted Names - Broken Chains
+    desc: Dotted names that cannot be resolved should be considered falsey.
+    data: { a: { } }
+    template: '"{{^a.b.c}}Not Here{{/a.b.c}}" == "Not Here"'
+    expected: '"Not Here" == "Not Here"'
+
+  # Whitespace Sensitivity
+
+  - name: Surrounding Whitespace
+    desc: Inverted sections should not alter surrounding whitespace.
+    data: { boolean: false }
+    template: " | {{^boolean}}\t|\t{{/boolean}} | \n"
+    expected: " | \t|\t | \n"
+
+  - name: Internal Whitespace
+    desc: Inverted should not alter internal whitespace.
+    data: { boolean: false }
+    template: " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
+    expected: " |  \n  | \n"
+
+  - name: Indented Inline Sections
+    desc: Single-line sections should not alter surrounding whitespace.
+    data: { boolean: false }
+    template: " {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n"
+    expected: " NO\n WAY\n"
+
+  - name: Standalone Lines
+    desc: Standalone lines should be removed from the template.
+    data: { boolean: false }
+    template: |
+      | This Is
+      {{^boolean}}
+      |
+      {{/boolean}}
+      | A Line
+    expected: |
+      | This Is
+      |
+      | A Line
+
+  - name: Standalone Indented Lines
+    desc: Standalone indented lines should be removed from the template.
+    data: { boolean: false }
+    template: |
+      | This Is
+        {{^boolean}}
+      |
+        {{/boolean}}
+      | A Line
+    expected: |
+      | This Is
+      |
+      | A Line
+
+  - name: Standalone Line Endings
+    desc: '"\r\n" should be considered a newline for standalone tags.'
+    data: { boolean: false }
+    template: "|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|"
+    expected: "|\r\n|"
+
+  - name: Standalone Without Previous Line
+    desc: Standalone tags should not require a newline to precede them.
+    data: { boolean: false }
+    template: "  {{^boolean}}\n^{{/boolean}}\n/"
+    expected: "^\n/"
+
+  - name: Standalone Without Newline
+    desc: Standalone tags should not require a newline to follow them.
+    data: { boolean: false }
+    template: "^{{^boolean}}\n/\n  {{/boolean}}"
+    expected: "^\n/\n"
+
+  # Whitespace Insensitivity
+
+  - name: Padding
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { boolean: false }
+    template: '|{{^ boolean }}={{/ boolean }}|'
+    expected: '|=|'
diff --git a/specification/partials.yml b/specification/partials.yml
new file mode 100644
--- /dev/null
+++ b/specification/partials.yml
@@ -0,0 +1,109 @@
+overview: |
+  Partial tags are used to expand an external template into the current
+  template.
+
+  The tag's content MUST be a non-whitespace character sequence NOT containing
+  the current closing delimiter.
+
+  This tag's content names the partial to inject.  Set Delimiter tags MUST NOT
+  affect the parsing of a partial.  The partial MUST be rendered against the
+  context stack local to the tag.  If the named partial cannot be found, the
+  empty string SHOULD be used instead, as in interpolations.
+
+  Partial tags SHOULD be treated as standalone when appropriate.  If this tag
+  is used standalone, any whitespace preceding the tag should treated as
+  indentation, and prepended to each line of the partial before rendering.
+tests:
+  - name: Basic Behavior
+    desc: The greater-than operator should expand to the named partial.
+    data: { }
+    template: '"{{>text}}"'
+    partials: { text: 'from partial' }
+    expected: '"from partial"'
+
+  - name: Failed Lookup
+    desc: The empty string should be used when the named partial is not found.
+    data: { }
+    template: '"{{>text}}"'
+    partials: { }
+    expected: '""'
+
+  - name: Context
+    desc: The greater-than operator should operate within the current context.
+    data: { text: 'content' }
+    template: '"{{>partial}}"'
+    partials: { partial: '*{{text}}*' }
+    expected: '"*content*"'
+
+  - name: Recursion
+    desc: The greater-than operator should properly recurse.
+    data: { content: "X", nodes: [ { content: "Y", nodes: [] } ] }
+    template: '{{>node}}'
+    partials: { node: '{{content}}<{{#nodes}}{{>node}}{{/nodes}}>' }
+    expected: 'X<Y<>>'
+
+  # Whitespace Sensitivity
+
+  - name: Surrounding Whitespace
+    desc: The greater-than operator should not alter surrounding whitespace.
+    data: { }
+    template: '| {{>partial}} |'
+    partials: { partial: "\t|\t" }
+    expected: "| \t|\t |"
+
+  - name: Inline Indentation
+    desc: Whitespace should be left untouched.
+    data: { data: '|' }
+    template: "  {{data}}  {{> partial}}\n"
+    partials: { partial: ">\n>" }
+    expected: "  |  >\n>\n"
+
+  - name: Standalone Line Endings
+    desc: '"\r\n" should be considered a newline for standalone tags.'
+    data: { }
+    template: "|\r\n{{>partial}}\r\n|"
+    partials: { partial: ">" }
+    expected: "|\r\n>|"
+
+  - name: Standalone Without Previous Line
+    desc: Standalone tags should not require a newline to precede them.
+    data: { }
+    template: "  {{>partial}}\n>"
+    partials: { partial: ">\n>"}
+    expected: "  >\n  >>"
+
+  - name: Standalone Without Newline
+    desc: Standalone tags should not require a newline to follow them.
+    data: { }
+    template: ">\n  {{>partial}}"
+    partials: { partial: ">\n>" }
+    expected: ">\n  >\n  >"
+
+  - name: Standalone Indentation
+    desc: Each line of the partial should be indented before rendering.
+    data: { content: "<\n->" }
+    template: |
+      \
+       {{>partial}}
+      /
+    partials:
+      partial: |
+        |
+        {{{content}}}
+        |
+    expected: |
+      \
+       |
+       <
+      ->
+       |
+      /
+
+  # Whitespace Insensitivity
+
+  - name: Padding Whitespace
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { boolean: true }
+    template: "|{{> partial }}|"
+    partials: { partial: "[]" }
+    expected: '|[]|'
diff --git a/specification/sections.yml b/specification/sections.yml
new file mode 100644
--- /dev/null
+++ b/specification/sections.yml
@@ -0,0 +1,263 @@
+overview: |
+  Section tags and End Section tags are used in combination to wrap a section
+  of the template for iteration
+
+  These tags' content MUST be a non-whitespace character sequence NOT
+  containing the current closing delimiter; each Section tag MUST be followed
+  by an End Section tag with the same content within the same section.
+
+  This tag's content names the data to replace the tag.  Name resolution is as
+  follows:
+    1) Split the name on periods; the first part is the name to resolve, any
+    remaining parts should be retained.
+    2) Walk the context stack from top to bottom, finding the first context
+    that is a) a hash containing the name as a key OR b) an object responding
+    to a method with the given name.
+    3) If the context is a hash, the data is the value associated with the
+    name.
+    4) If the context is an object and the method with the given name has an
+    arity of 1, the method SHOULD be called with a String containing the
+    unprocessed contents of the sections; the data is the value returned.
+    5) Otherwise, the data is the value returned by calling the method with
+    the given name.
+    6) If any name parts were retained in step 1, each should be resolved
+    against a context stack containing only the result from the former
+    resolution.  If any part fails resolution, the result should be considered
+    falsey, and should interpolate as the empty string.
+  If the data is not of a list type, it is coerced into a list as follows: if
+  the data is truthy (e.g. `!!data == true`), use a single-element list
+  containing the data, otherwise use an empty list.
+
+  For each element in the data list, the element MUST be pushed onto the
+  context stack, the section MUST be rendered, and the element MUST be popped
+  off the context stack.
+
+  Section and End Section tags SHOULD be treated as standalone when
+  appropriate.
+tests:
+  - name: Truthy
+    desc: Truthy sections should have their contents rendered.
+    data: { boolean: true }
+    template: '"{{#boolean}}This should be rendered.{{/boolean}}"'
+    expected: '"This should be rendered."'
+
+  - name: Falsey
+    desc: Falsey sections should have their contents omitted.
+    data: { boolean: false }
+    template: '"{{#boolean}}This should not be rendered.{{/boolean}}"'
+    expected: '""'
+
+  - name: Context
+    desc: Objects and hashes should be pushed onto the context stack.
+    data: { context: { name: 'Joe' } }
+    template: '"{{#context}}Hi {{name}}.{{/context}}"'
+    expected: '"Hi Joe."'
+
+  - name: Deeply Nested Contexts
+    desc: All elements on the context stack should be accessible.
+    data:
+      a: { one: 1 }
+      b: { two: 2 }
+      c: { three: 3 }
+      d: { four: 4 }
+      e: { five: 5 }
+    template: |
+      {{#a}}
+      {{one}}
+      {{#b}}
+      {{one}}{{two}}{{one}}
+      {{#c}}
+      {{one}}{{two}}{{three}}{{two}}{{one}}
+      {{#d}}
+      {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
+      {{#e}}
+      {{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}
+      {{/e}}
+      {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
+      {{/d}}
+      {{one}}{{two}}{{three}}{{two}}{{one}}
+      {{/c}}
+      {{one}}{{two}}{{one}}
+      {{/b}}
+      {{one}}
+      {{/a}}
+    expected: |
+      1
+      121
+      12321
+      1234321
+      123454321
+      1234321
+      12321
+      121
+      1
+
+  - name: List
+    desc: Lists should be iterated; list items should visit the context stack.
+    data: { list: [ { item: 1 }, { item: 2 }, { item: 3 } ] }
+    template: '"{{#list}}{{item}}{{/list}}"'
+    expected: '"123"'
+
+  - name: Empty List
+    desc: Empty lists should behave like falsey values.
+    data: { list: [ ] }
+    template: '"{{#list}}Yay lists!{{/list}}"'
+    expected: '""'
+
+  - name: Doubled
+    desc: Multiple sections per template should be permitted.
+    data: { bool: true, two: 'second' }
+    template: |
+      {{#bool}}
+      * first
+      {{/bool}}
+      * {{two}}
+      {{#bool}}
+      * third
+      {{/bool}}
+    expected: |
+      * first
+      * second
+      * third
+
+  - name: Nested (Truthy)
+    desc: Nested truthy sections should have their contents rendered.
+    data: { bool: true }
+    template: "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |"
+    expected: "| A B C D E |"
+
+  - name: Nested (Falsey)
+    desc: Nested falsey sections should be omitted.
+    data: { bool: false }
+    template: "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |"
+    expected: "| A  E |"
+
+  - name: Context Misses
+    desc: Failed context lookups should be considered falsey.
+    data: { }
+    template: "[{{#missing}}Found key 'missing'!{{/missing}}]"
+    expected: "[]"
+
+  # Implicit Iterators
+
+  - name: Implicit Iterator - String
+    desc: Implicit iterators should directly interpolate strings.
+    data:
+      list: [ 'a', 'b', 'c', 'd', 'e' ]
+    template: '"{{#list}}({{.}}){{/list}}"'
+    expected: '"(a)(b)(c)(d)(e)"'
+
+  - name: Implicit Iterator - Integer
+    desc: Implicit iterators should cast integers to strings and interpolate.
+    data:
+      list: [ 1, 2, 3, 4, 5 ]
+    template: '"{{#list}}({{.}}){{/list}}"'
+    expected: '"(1)(2)(3)(4)(5)"'
+
+  - name: Implicit Iterator - Decimal
+    desc: Implicit iterators should cast decimals to strings and interpolate.
+    data:
+      list: [ 1.10, 2.20, 3.30, 4.40, 5.50 ]
+    template: '"{{#list}}({{.}}){{/list}}"'
+    expected: '"(1.1)(2.2)(3.3)(4.4)(5.5)"'
+
+  - name: Implicit Iterator - Array
+    desc: Implicit iterators should allow iterating over nested arrays.
+    data:
+      list: [ [1, 2, 3], ['a', 'b', 'c'] ]
+    template: '"{{#list}}({{#.}}{{.}}{{/.}}){{/list}}"'
+    expected: '"(123)(abc)"'
+
+  # Dotted Names
+
+  - name: Dotted Names - Truthy
+    desc: Dotted names should be valid for Section tags.
+    data: { a: { b: { c: true } } }
+    template: '"{{#a.b.c}}Here{{/a.b.c}}" == "Here"'
+    expected: '"Here" == "Here"'
+
+  - name: Dotted Names - Falsey
+    desc: Dotted names should be valid for Section tags.
+    data: { a: { b: { c: false } } }
+    template: '"{{#a.b.c}}Here{{/a.b.c}}" == ""'
+    expected: '"" == ""'
+
+  - name: Dotted Names - Broken Chains
+    desc: Dotted names that cannot be resolved should be considered falsey.
+    data: { a: { } }
+    template: '"{{#a.b.c}}Here{{/a.b.c}}" == ""'
+    expected: '"" == ""'
+
+  # Whitespace Sensitivity
+
+  - name: Surrounding Whitespace
+    desc: Sections should not alter surrounding whitespace.
+    data: { boolean: true }
+    template: " | {{#boolean}}\t|\t{{/boolean}} | \n"
+    expected: " | \t|\t | \n"
+
+  - name: Internal Whitespace
+    desc: Sections should not alter internal whitespace.
+    data: { boolean: true }
+    template: " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
+    expected: " |  \n  | \n"
+
+  - name: Indented Inline Sections
+    desc: Single-line sections should not alter surrounding whitespace.
+    data: { boolean: true }
+    template: " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n"
+    expected: " YES\n GOOD\n"
+
+  - name: Standalone Lines
+    desc: Standalone lines should be removed from the template.
+    data: { boolean: true }
+    template: |
+      | This Is
+      {{#boolean}}
+      |
+      {{/boolean}}
+      | A Line
+    expected: |
+      | This Is
+      |
+      | A Line
+
+  - name: Indented Standalone Lines
+    desc: Indented standalone lines should be removed from the template.
+    data: { boolean: true }
+    template: |
+      | This Is
+        {{#boolean}}
+      |
+        {{/boolean}}
+      | A Line
+    expected: |
+      | This Is
+      |
+      | A Line
+
+  - name: Standalone Line Endings
+    desc: '"\r\n" should be considered a newline for standalone tags.'
+    data: { boolean: true }
+    template: "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|"
+    expected: "|\r\n|"
+
+  - name: Standalone Without Previous Line
+    desc: Standalone tags should not require a newline to precede them.
+    data: { boolean: true }
+    template: "  {{#boolean}}\n#{{/boolean}}\n/"
+    expected: "#\n/"
+
+  - name: Standalone Without Newline
+    desc: Standalone tags should not require a newline to follow them.
+    data: { boolean: true }
+    template: "#{{#boolean}}\n/\n  {{/boolean}}"
+    expected: "#\n/\n"
+
+  # Whitespace Insensitivity
+
+  - name: Padding
+    desc: Superfluous in-tag whitespace should be ignored.
+    data: { boolean: true }
+    template: '|{{# boolean }}={{/ boolean }}|'
+    expected: '|=|'
diff --git a/specs/comments.yml b/specs/comments.yml
deleted file mode 100644
--- a/specs/comments.yml
+++ /dev/null
@@ -1,103 +0,0 @@
-overview: |
-  Comment tags represent content that should never appear in the resulting
-  output.
-
-  The tag's content may contain any substring (including newlines) EXCEPT the
-  closing delimiter.
-
-  Comment tags SHOULD be treated as standalone when appropriate.
-tests:
-  - name: Inline
-    desc: Comment blocks should be removed from the template.
-    data: { }
-    template: '12345{{! Comment Block! }}67890'
-    expected: '1234567890'
-
-  - name: Multiline
-    desc: Multiline comments should be permitted.
-    data: { }
-    template: |
-      12345{{!
-        This is a
-        multi-line comment...
-      }}67890
-    expected: |
-      1234567890
-
-  - name: Standalone
-    desc: All standalone comment lines should be removed.
-    data: { }
-    template: |
-      Begin.
-      {{! Comment Block! }}
-      End.
-    expected: |
-      Begin.
-      End.
-
-  - name: Indented Standalone
-    desc: All standalone comment lines should be removed.
-    data: { }
-    template: |
-      Begin.
-        {{! Indented Comment Block! }}
-      End.
-    expected: |
-      Begin.
-      End.
-
-  - name: Standalone Line Endings
-    desc: '"\r\n" should be considered a newline for standalone tags.'
-    data: { }
-    template: "|\r\n{{! Standalone Comment }}\r\n|"
-    expected: "|\r\n|"
-
-  - name: Standalone Without Previous Line
-    desc: Standalone tags should not require a newline to precede them.
-    data: { }
-    template: "  {{! I'm Still Standalone }}\n!"
-    expected: "!"
-
-  - name: Standalone Without Newline
-    desc: Standalone tags should not require a newline to follow them.
-    data: { }
-    template: "!\n  {{! I'm Still Standalone }}"
-    expected: "!\n"
-
-  - name: Multiline Standalone
-    desc: All standalone comment lines should be removed.
-    data: { }
-    template: |
-      Begin.
-      {{!
-      Something's going on here...
-      }}
-      End.
-    expected: |
-      Begin.
-      End.
-
-  - name: Indented Multiline Standalone
-    desc: All standalone comment lines should be removed.
-    data: { }
-    template: |
-      Begin.
-        {{!
-          Something's going on here...
-        }}
-      End.
-    expected: |
-      Begin.
-      End.
-
-  - name: Indented Inline
-    desc: Inline comments should not strip whitespace
-    data: { }
-    template: "  12 {{! 34 }}\n"
-    expected: "  12 \n"
-
-  - name: Surrounding Whitespace
-    desc: Comment removal should preserve surrounding whitespace.
-    data: { }
-    template: '12345 {{! Comment Block! }} 67890'
-    expected: '12345  67890'
diff --git a/specs/delimiters.yml b/specs/delimiters.yml
deleted file mode 100644
--- a/specs/delimiters.yml
+++ /dev/null
@@ -1,158 +0,0 @@
-overview: |
-  Set Delimiter tags are used to change the tag delimiters for all content
-  following the tag in the current compilation unit.
-
-  The tag's content MUST be any two non-whitespace sequences (separated by
-  whitespace) EXCEPT an equals sign ('=') followed by the current closing
-  delimiter.
-
-  Set Delimiter tags SHOULD be treated as standalone when appropriate.
-tests:
-  - name: Pair Behavior
-    desc: The equals sign (used on both sides) should permit delimiter changes.
-    data: { text: 'Hey!' }
-    template: '{{=<% %>=}}(<%text%>)'
-    expected: '(Hey!)'
-
-  - name: Special Characters
-    desc: Characters with special meaning regexen should be valid delimiters.
-    data: { text: 'It worked!' }
-    template: '({{=[ ]=}}[text])'
-    expected: '(It worked!)'
-
-  - name: Sections
-    desc: Delimiters set outside sections should persist.
-    data: { section: true, data: 'I got interpolated.' }
-    template: |
-      [
-      {{#section}}
-        {{data}}
-        |data|
-      {{/section}}
-
-      {{= | | =}}
-      |#section|
-        {{data}}
-        |data|
-      |/section|
-      ]
-    expected: |
-      [
-        I got interpolated.
-        |data|
-
-        {{data}}
-        I got interpolated.
-      ]
-
-  - name: Inverted Sections
-    desc: Delimiters set outside inverted sections should persist.
-    data: { section: false, data: 'I got interpolated.' }
-    template: |
-      [
-      {{^section}}
-        {{data}}
-        |data|
-      {{/section}}
-
-      {{= | | =}}
-      |^section|
-        {{data}}
-        |data|
-      |/section|
-      ]
-    expected: |
-      [
-        I got interpolated.
-        |data|
-
-        {{data}}
-        I got interpolated.
-      ]
-
-  - name: Partial Inheritence
-    desc: Delimiters set in a parent template should not affect a partial.
-    data: { value: 'yes' }
-    partials:
-      include: '.{{value}}.'
-    template: |
-      [ {{>include}} ]
-      {{= | | =}}
-      [ |>include| ]
-    expected: |
-      [ .yes. ]
-      [ .yes. ]
-
-  - name: Post-Partial Behavior
-    desc: Delimiters set in a partial should not affect the parent template.
-    data: { value: 'yes' }
-    partials:
-      include: '.{{value}}. {{= | | =}} .|value|.'
-    template: |
-      [ {{>include}} ]
-      [ .{{value}}.  .|value|. ]
-    expected: |
-      [ .yes.  .yes. ]
-      [ .yes.  .|value|. ]
-
-  # Whitespace Sensitivity
-
-  - name: Surrounding Whitespace
-    desc: Surrounding whitespace should be left untouched.
-    data: { }
-    template: '| {{=@ @=}} |'
-    expected: '|  |'
-
-  - name: Outlying Whitespace (Inline)
-    desc: Whitespace should be left untouched.
-    data: { }
-    template: " | {{=@ @=}}\n"
-    expected: " | \n"
-
-  - name: Standalone Tag
-    desc: Standalone lines should be removed from the template.
-    data: { }
-    template: |
-      Begin.
-      {{=@ @=}}
-      End.
-    expected: |
-      Begin.
-      End.
-
-  - name: Indented Standalone Tag
-    desc: Indented standalone lines should be removed from the template.
-    data: { }
-    template: |
-      Begin.
-        {{=@ @=}}
-      End.
-    expected: |
-      Begin.
-      End.
-
-  - name: Standalone Line Endings
-    desc: '"\r\n" should be considered a newline for standalone tags.'
-    data: { }
-    template: "|\r\n{{= @ @ =}}\r\n|"
-    expected: "|\r\n|"
-
-  - name: Standalone Without Previous Line
-    desc: Standalone tags should not require a newline to precede them.
-    data: { }
-    template: "  {{=@ @=}}\n="
-    expected: "="
-
-  - name: Standalone Without Newline
-    desc: Standalone tags should not require a newline to follow them.
-    data: { }
-    template: "=\n  {{=@ @=}}"
-    expected: "=\n"
-
-  # Whitespace Insensitivity
-
-  - name: Pair with Padding
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { }
-    template: '|{{= @   @ =}}|'
-    expected: '||'
diff --git a/specs/interpolation.yml b/specs/interpolation.yml
deleted file mode 100644
--- a/specs/interpolation.yml
+++ /dev/null
@@ -1,238 +0,0 @@
-overview: |
-  Interpolation tags are used to integrate dynamic content into the template.
-
-  The tag's content MUST be a non-whitespace character sequence NOT containing
-  the current closing delimiter.
-
-  This tag's content names the data to replace the tag.  A single period (`.`)
-  indicates that the item currently sitting atop the context stack should be
-  used; otherwise, name resolution is as follows:
-    1) Split the name on periods; the first part is the name to resolve, any
-    remaining parts should be retained.
-    2) Walk the context stack from top to bottom, finding the first context
-    that is a) a hash containing the name as a key OR b) an object responding
-    to a method with the given name.
-    3) If the context is a hash, the data is the value associated with the
-    name.
-    4) If the context is an object, the data is the value returned by the
-    method with the given name.
-    5) If any name parts were retained in step 1, each should be resolved
-    against a context stack containing only the result from the former
-    resolution.  If any part fails resolution, the result should be considered
-    falsey, and should interpolate as the empty string.
-  Data should be coerced into a string (and escaped, if appropriate) before
-  interpolation.
-
-  The Interpolation tags MUST NOT be treated as standalone.
-tests:
-  - name: No Interpolation
-    desc: Mustache-free templates should render as-is.
-    data: { }
-    template: |
-      Hello from {Mustache}!
-    expected: |
-      Hello from {Mustache}!
-
-  - name: Basic Interpolation
-    desc: Unadorned tags should interpolate content into the template.
-    data: { subject: "world" }
-    template: |
-      Hello, {{subject}}!
-    expected: |
-      Hello, world!
-
-  - name: HTML Escaping
-    desc: Basic interpolation should be HTML escaped.
-    data: { forbidden: '& " < >' }
-    template: |
-      These characters should be HTML escaped: {{forbidden}}
-    expected: |
-      These characters should be HTML escaped: &amp; &quot; &lt; &gt;
-
-  - name: Triple Mustache
-    desc: Triple mustaches should interpolate without HTML escaping.
-    data: { forbidden: '& " < >' }
-    template: |
-      These characters should not be HTML escaped: {{{forbidden}}}
-    expected: |
-      These characters should not be HTML escaped: & " < >
-
-  - name: Ampersand
-    desc: Ampersand should interpolate without HTML escaping.
-    data: { forbidden: '& " < >' }
-    template: |
-      These characters should not be HTML escaped: {{&forbidden}}
-    expected: |
-      These characters should not be HTML escaped: & " < >
-
-  - name: Basic Integer Interpolation
-    desc: Integers should interpolate seamlessly.
-    data: { mph: 85 }
-    template: '"{{mph}} miles an hour!"'
-    expected: '"85 miles an hour!"'
-
-  - name: Triple Mustache Integer Interpolation
-    desc: Integers should interpolate seamlessly.
-    data: { mph: 85 }
-    template: '"{{{mph}}} miles an hour!"'
-    expected: '"85 miles an hour!"'
-
-  - name: Ampersand Integer Interpolation
-    desc: Integers should interpolate seamlessly.
-    data: { mph: 85 }
-    template: '"{{&mph}} miles an hour!"'
-    expected: '"85 miles an hour!"'
-
-  - name: Basic Decimal Interpolation
-    desc: Decimals should interpolate seamlessly with proper significance.
-    data: { power: 1.210 }
-    template: '"{{power}} jiggawatts!"'
-    expected: '"1.21 jiggawatts!"'
-
-  - name: Triple Mustache Decimal Interpolation
-    desc: Decimals should interpolate seamlessly with proper significance.
-    data: { power: 1.210 }
-    template: '"{{{power}}} jiggawatts!"'
-    expected: '"1.21 jiggawatts!"'
-
-  - name: Ampersand Decimal Interpolation
-    desc: Decimals should interpolate seamlessly with proper significance.
-    data: { power: 1.210 }
-    template: '"{{&power}} jiggawatts!"'
-    expected: '"1.21 jiggawatts!"'
-
-  # Context Misses
-
-  - name: Basic Context Miss Interpolation
-    desc: Failed context lookups should default to empty strings.
-    data: { }
-    template: "I ({{cannot}}) be seen!"
-    expected: "I () be seen!"
-
-  - name: Triple Mustache Context Miss Interpolation
-    desc: Failed context lookups should default to empty strings.
-    data: { }
-    template: "I ({{{cannot}}}) be seen!"
-    expected: "I () be seen!"
-
-  - name: Ampersand Context Miss Interpolation
-    desc: Failed context lookups should default to empty strings.
-    data: { }
-    template: "I ({{&cannot}}) be seen!"
-    expected: "I () be seen!"
-
-  # Dotted Names
-
-  - name: Dotted Names - Basic Interpolation
-    desc: Dotted names should be considered a form of shorthand for sections.
-    data: { person: { name: 'Joe' } }
-    template: '"{{person.name}}" == "{{#person}}{{name}}{{/person}}"'
-    expected: '"Joe" == "Joe"'
-
-  - name: Dotted Names - Triple Mustache Interpolation
-    desc: Dotted names should be considered a form of shorthand for sections.
-    data: { person: { name: 'Joe' } }
-    template: '"{{{person.name}}}" == "{{#person}}{{{name}}}{{/person}}"'
-    expected: '"Joe" == "Joe"'
-
-  - name: Dotted Names - Ampersand Interpolation
-    desc: Dotted names should be considered a form of shorthand for sections.
-    data: { person: { name: 'Joe' } }
-    template: '"{{&person.name}}" == "{{#person}}{{&name}}{{/person}}"'
-    expected: '"Joe" == "Joe"'
-
-  - name: Dotted Names - Arbitrary Depth
-    desc: Dotted names should be functional to any level of nesting.
-    data:
-      a: { b: { c: { d: { e: { name: 'Phil' } } } } }
-    template: '"{{a.b.c.d.e.name}}" == "Phil"'
-    expected: '"Phil" == "Phil"'
-
-  - name: Dotted Names - Broken Chains
-    desc: Any falsey value prior to the last part of the name should yield ''.
-    data:
-      a: { }
-    template: '"{{a.b.c}}" == ""'
-    expected: '"" == ""'
-
-  - name: Dotted Names - Broken Chain Resolution
-    desc: Each part of a dotted name should resolve only against its parent.
-    data:
-      a: { b: { } }
-      c: { name: 'Jim' }
-    template: '"{{a.b.c.name}}" == ""'
-    expected: '"" == ""'
-
-  - name: Dotted Names - Initial Resolution
-    desc: The first part of a dotted name should resolve as any other name.
-    data:
-      a: { b: { c: { d: { e: { name: 'Phil' } } } } }
-      b: { c: { d: { e: { name: 'Wrong' } } } }
-    template: '"{{#a}}{{b.c.d.e.name}}{{/a}}" == "Phil"'
-    expected: '"Phil" == "Phil"'
-
-  - name: Dotted Names - Context Precedence
-    desc: Dotted names should be resolved against former resolutions.
-    data:
-      a: { b: { } }
-      b: { c: 'ERROR' }
-    template: '{{#a}}{{b.c}}{{/a}}'
-    expected: ''
-
-  # Whitespace Sensitivity
-
-  - name: Interpolation - Surrounding Whitespace
-    desc: Interpolation should not alter surrounding whitespace.
-    data: { string: '---' }
-    template: '| {{string}} |'
-    expected: '| --- |'
-
-  - name: Triple Mustache - Surrounding Whitespace
-    desc: Interpolation should not alter surrounding whitespace.
-    data: { string: '---' }
-    template: '| {{{string}}} |'
-    expected: '| --- |'
-
-  - name: Ampersand - Surrounding Whitespace
-    desc: Interpolation should not alter surrounding whitespace.
-    data: { string: '---' }
-    template: '| {{&string}} |'
-    expected: '| --- |'
-
-  - name: Interpolation - Standalone
-    desc: Standalone interpolation should not alter surrounding whitespace.
-    data: { string: '---' }
-    template: "  {{string}}\n"
-    expected: "  ---\n"
-
-  - name: Triple Mustache - Standalone
-    desc: Standalone interpolation should not alter surrounding whitespace.
-    data: { string: '---' }
-    template: "  {{{string}}}\n"
-    expected: "  ---\n"
-
-  - name: Ampersand - Standalone
-    desc: Standalone interpolation should not alter surrounding whitespace.
-    data: { string: '---' }
-    template: "  {{&string}}\n"
-    expected: "  ---\n"
-
-  # Whitespace Insensitivity
-
-  - name: Interpolation With Padding
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { string: "---" }
-    template: '|{{ string }}|'
-    expected: '|---|'
-
-  - name: Triple Mustache With Padding
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { string: "---" }
-    template: '|{{{ string }}}|'
-    expected: '|---|'
-
-  - name: Ampersand With Padding
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { string: "---" }
-    template: '|{{& string }}|'
-    expected: '|---|'
diff --git a/specs/inverted.yml b/specs/inverted.yml
deleted file mode 100644
--- a/specs/inverted.yml
+++ /dev/null
@@ -1,193 +0,0 @@
-overview: |
-  Inverted Section tags and End Section tags are used in combination to wrap a
-  section of the template.
-
-  These tags' content MUST be a non-whitespace character sequence NOT
-  containing the current closing delimiter; each Inverted Section tag MUST be
-  followed by an End Section tag with the same content within the same
-  section.
-
-  This tag's content names the data to replace the tag.  Name resolution is as
-  follows:
-    1) Split the name on periods; the first part is the name to resolve, any
-    remaining parts should be retained.
-    2) Walk the context stack from top to bottom, finding the first context
-    that is a) a hash containing the name as a key OR b) an object responding
-    to a method with the given name.
-    3) If the context is a hash, the data is the value associated with the
-    name.
-    4) If the context is an object and the method with the given name has an
-    arity of 1, the method SHOULD be called with a String containing the
-    unprocessed contents of the sections; the data is the value returned.
-    5) Otherwise, the data is the value returned by calling the method with
-    the given name.
-    6) If any name parts were retained in step 1, each should be resolved
-    against a context stack containing only the result from the former
-    resolution.  If any part fails resolution, the result should be considered
-    falsey, and should interpolate as the empty string.
-  If the data is not of a list type, it is coerced into a list as follows: if
-  the data is truthy (e.g. `!!data == true`), use a single-element list
-  containing the data, otherwise use an empty list.
-
-  This section MUST NOT be rendered unless the data list is empty.
-
-  Inverted Section and End Section tags SHOULD be treated as standalone when
-  appropriate.
-tests:
-  - name: Falsey
-    desc: Falsey sections should have their contents rendered.
-    data: { boolean: false }
-    template: '"{{^boolean}}This should be rendered.{{/boolean}}"'
-    expected: '"This should be rendered."'
-
-  - name: Truthy
-    desc: Truthy sections should have their contents omitted.
-    data: { boolean: true }
-    template: '"{{^boolean}}This should not be rendered.{{/boolean}}"'
-    expected: '""'
-
-  - name: Context
-    desc: Objects and hashes should behave like truthy values.
-    data: { context: { name: 'Joe' } }
-    template: '"{{^context}}Hi {{name}}.{{/context}}"'
-    expected: '""'
-
-  - name: List
-    desc: Lists should behave like truthy values.
-    data: { list: [ { n: 1 }, { n: 2 }, { n: 3 } ] }
-    template: '"{{^list}}{{n}}{{/list}}"'
-    expected: '""'
-
-  - name: Empty List
-    desc: Empty lists should behave like falsey values.
-    data: { list: [ ] }
-    template: '"{{^list}}Yay lists!{{/list}}"'
-    expected: '"Yay lists!"'
-
-  - name: Doubled
-    desc: Multiple inverted sections per template should be permitted.
-    data: { bool: false, two: 'second' }
-    template: |
-      {{^bool}}
-      * first
-      {{/bool}}
-      * {{two}}
-      {{^bool}}
-      * third
-      {{/bool}}
-    expected: |
-      * first
-      * second
-      * third
-
-  - name: Nested (Falsey)
-    desc: Nested falsey sections should have their contents rendered.
-    data: { bool: false }
-    template: "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |"
-    expected: "| A B C D E |"
-
-  - name: Nested (Truthy)
-    desc: Nested truthy sections should be omitted.
-    data: { bool: true }
-    template: "| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |"
-    expected: "| A  E |"
-
-  - name: Context Misses
-    desc: Failed context lookups should be considered falsey.
-    data: { }
-    template: "[{{^missing}}Cannot find key 'missing'!{{/missing}}]"
-    expected: "[Cannot find key 'missing'!]"
-
-  # Dotted Names
-
-  - name: Dotted Names - Truthy
-    desc: Dotted names should be valid for Inverted Section tags.
-    data: { a: { b: { c: true } } }
-    template: '"{{^a.b.c}}Not Here{{/a.b.c}}" == ""'
-    expected: '"" == ""'
-
-  - name: Dotted Names - Falsey
-    desc: Dotted names should be valid for Inverted Section tags.
-    data: { a: { b: { c: false } } }
-    template: '"{{^a.b.c}}Not Here{{/a.b.c}}" == "Not Here"'
-    expected: '"Not Here" == "Not Here"'
-
-  - name: Dotted Names - Broken Chains
-    desc: Dotted names that cannot be resolved should be considered falsey.
-    data: { a: { } }
-    template: '"{{^a.b.c}}Not Here{{/a.b.c}}" == "Not Here"'
-    expected: '"Not Here" == "Not Here"'
-
-  # Whitespace Sensitivity
-
-  - name: Surrounding Whitespace
-    desc: Inverted sections should not alter surrounding whitespace.
-    data: { boolean: false }
-    template: " | {{^boolean}}\t|\t{{/boolean}} | \n"
-    expected: " | \t|\t | \n"
-
-  - name: Internal Whitespace
-    desc: Inverted should not alter internal whitespace.
-    data: { boolean: false }
-    template: " | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
-    expected: " |  \n  | \n"
-
-  - name: Indented Inline Sections
-    desc: Single-line sections should not alter surrounding whitespace.
-    data: { boolean: false }
-    template: " {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n"
-    expected: " NO\n WAY\n"
-
-  - name: Standalone Lines
-    desc: Standalone lines should be removed from the template.
-    data: { boolean: false }
-    template: |
-      | This Is
-      {{^boolean}}
-      |
-      {{/boolean}}
-      | A Line
-    expected: |
-      | This Is
-      |
-      | A Line
-
-  - name: Standalone Indented Lines
-    desc: Standalone indented lines should be removed from the template.
-    data: { boolean: false }
-    template: |
-      | This Is
-        {{^boolean}}
-      |
-        {{/boolean}}
-      | A Line
-    expected: |
-      | This Is
-      |
-      | A Line
-
-  - name: Standalone Line Endings
-    desc: '"\r\n" should be considered a newline for standalone tags.'
-    data: { boolean: false }
-    template: "|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|"
-    expected: "|\r\n|"
-
-  - name: Standalone Without Previous Line
-    desc: Standalone tags should not require a newline to precede them.
-    data: { boolean: false }
-    template: "  {{^boolean}}\n^{{/boolean}}\n/"
-    expected: "^\n/"
-
-  - name: Standalone Without Newline
-    desc: Standalone tags should not require a newline to follow them.
-    data: { boolean: false }
-    template: "^{{^boolean}}\n/\n  {{/boolean}}"
-    expected: "^\n/\n"
-
-  # Whitespace Insensitivity
-
-  - name: Padding
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { boolean: false }
-    template: '|{{^ boolean }}={{/ boolean }}|'
-    expected: '|=|'
diff --git a/specs/partials.yml b/specs/partials.yml
deleted file mode 100644
--- a/specs/partials.yml
+++ /dev/null
@@ -1,109 +0,0 @@
-overview: |
-  Partial tags are used to expand an external template into the current
-  template.
-
-  The tag's content MUST be a non-whitespace character sequence NOT containing
-  the current closing delimiter.
-
-  This tag's content names the partial to inject.  Set Delimiter tags MUST NOT
-  affect the parsing of a partial.  The partial MUST be rendered against the
-  context stack local to the tag.  If the named partial cannot be found, the
-  empty string SHOULD be used instead, as in interpolations.
-
-  Partial tags SHOULD be treated as standalone when appropriate.  If this tag
-  is used standalone, any whitespace preceding the tag should treated as
-  indentation, and prepended to each line of the partial before rendering.
-tests:
-  - name: Basic Behavior
-    desc: The greater-than operator should expand to the named partial.
-    data: { }
-    template: '"{{>text}}"'
-    partials: { text: 'from partial' }
-    expected: '"from partial"'
-
-  - name: Failed Lookup
-    desc: The empty string should be used when the named partial is not found.
-    data: { }
-    template: '"{{>text}}"'
-    partials: { }
-    expected: '""'
-
-  - name: Context
-    desc: The greater-than operator should operate within the current context.
-    data: { text: 'content' }
-    template: '"{{>partial}}"'
-    partials: { partial: '*{{text}}*' }
-    expected: '"*content*"'
-
-  - name: Recursion
-    desc: The greater-than operator should properly recurse.
-    data: { content: "X", nodes: [ { content: "Y", nodes: [] } ] }
-    template: '{{>node}}'
-    partials: { node: '{{content}}<{{#nodes}}{{>node}}{{/nodes}}>' }
-    expected: 'X<Y<>>'
-
-  # Whitespace Sensitivity
-
-  - name: Surrounding Whitespace
-    desc: The greater-than operator should not alter surrounding whitespace.
-    data: { }
-    template: '| {{>partial}} |'
-    partials: { partial: "\t|\t" }
-    expected: "| \t|\t |"
-
-  - name: Inline Indentation
-    desc: Whitespace should be left untouched.
-    data: { data: '|' }
-    template: "  {{data}}  {{> partial}}\n"
-    partials: { partial: ">\n>" }
-    expected: "  |  >\n>\n"
-
-  - name: Standalone Line Endings
-    desc: '"\r\n" should be considered a newline for standalone tags.'
-    data: { }
-    template: "|\r\n{{>partial}}\r\n|"
-    partials: { partial: ">" }
-    expected: "|\r\n>|"
-
-  - name: Standalone Without Previous Line
-    desc: Standalone tags should not require a newline to precede them.
-    data: { }
-    template: "  {{>partial}}\n>"
-    partials: { partial: ">\n>"}
-    expected: "  >\n  >>"
-
-  - name: Standalone Without Newline
-    desc: Standalone tags should not require a newline to follow them.
-    data: { }
-    template: ">\n  {{>partial}}"
-    partials: { partial: ">\n>" }
-    expected: ">\n  >\n  >"
-
-  - name: Standalone Indentation
-    desc: Each line of the partial should be indented before rendering.
-    data: { content: "<\n->" }
-    template: |
-      \
-       {{>partial}}
-      /
-    partials:
-      partial: |
-        |
-        {{{content}}}
-        |
-    expected: |
-      \
-       |
-       <
-      ->
-       |
-      /
-
-  # Whitespace Insensitivity
-
-  - name: Padding Whitespace
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { boolean: true }
-    template: "|{{> partial }}|"
-    partials: { partial: "[]" }
-    expected: '|[]|'
diff --git a/specs/sections.yml b/specs/sections.yml
deleted file mode 100644
--- a/specs/sections.yml
+++ /dev/null
@@ -1,263 +0,0 @@
-overview: |
-  Section tags and End Section tags are used in combination to wrap a section
-  of the template for iteration
-
-  These tags' content MUST be a non-whitespace character sequence NOT
-  containing the current closing delimiter; each Section tag MUST be followed
-  by an End Section tag with the same content within the same section.
-
-  This tag's content names the data to replace the tag.  Name resolution is as
-  follows:
-    1) Split the name on periods; the first part is the name to resolve, any
-    remaining parts should be retained.
-    2) Walk the context stack from top to bottom, finding the first context
-    that is a) a hash containing the name as a key OR b) an object responding
-    to a method with the given name.
-    3) If the context is a hash, the data is the value associated with the
-    name.
-    4) If the context is an object and the method with the given name has an
-    arity of 1, the method SHOULD be called with a String containing the
-    unprocessed contents of the sections; the data is the value returned.
-    5) Otherwise, the data is the value returned by calling the method with
-    the given name.
-    6) If any name parts were retained in step 1, each should be resolved
-    against a context stack containing only the result from the former
-    resolution.  If any part fails resolution, the result should be considered
-    falsey, and should interpolate as the empty string.
-  If the data is not of a list type, it is coerced into a list as follows: if
-  the data is truthy (e.g. `!!data == true`), use a single-element list
-  containing the data, otherwise use an empty list.
-
-  For each element in the data list, the element MUST be pushed onto the
-  context stack, the section MUST be rendered, and the element MUST be popped
-  off the context stack.
-
-  Section and End Section tags SHOULD be treated as standalone when
-  appropriate.
-tests:
-  - name: Truthy
-    desc: Truthy sections should have their contents rendered.
-    data: { boolean: true }
-    template: '"{{#boolean}}This should be rendered.{{/boolean}}"'
-    expected: '"This should be rendered."'
-
-  - name: Falsey
-    desc: Falsey sections should have their contents omitted.
-    data: { boolean: false }
-    template: '"{{#boolean}}This should not be rendered.{{/boolean}}"'
-    expected: '""'
-
-  - name: Context
-    desc: Objects and hashes should be pushed onto the context stack.
-    data: { context: { name: 'Joe' } }
-    template: '"{{#context}}Hi {{name}}.{{/context}}"'
-    expected: '"Hi Joe."'
-
-  - name: Deeply Nested Contexts
-    desc: All elements on the context stack should be accessible.
-    data:
-      a: { one: 1 }
-      b: { two: 2 }
-      c: { three: 3 }
-      d: { four: 4 }
-      e: { five: 5 }
-    template: |
-      {{#a}}
-      {{one}}
-      {{#b}}
-      {{one}}{{two}}{{one}}
-      {{#c}}
-      {{one}}{{two}}{{three}}{{two}}{{one}}
-      {{#d}}
-      {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
-      {{#e}}
-      {{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}
-      {{/e}}
-      {{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
-      {{/d}}
-      {{one}}{{two}}{{three}}{{two}}{{one}}
-      {{/c}}
-      {{one}}{{two}}{{one}}
-      {{/b}}
-      {{one}}
-      {{/a}}
-    expected: |
-      1
-      121
-      12321
-      1234321
-      123454321
-      1234321
-      12321
-      121
-      1
-
-  - name: List
-    desc: Lists should be iterated; list items should visit the context stack.
-    data: { list: [ { item: 1 }, { item: 2 }, { item: 3 } ] }
-    template: '"{{#list}}{{item}}{{/list}}"'
-    expected: '"123"'
-
-  - name: Empty List
-    desc: Empty lists should behave like falsey values.
-    data: { list: [ ] }
-    template: '"{{#list}}Yay lists!{{/list}}"'
-    expected: '""'
-
-  - name: Doubled
-    desc: Multiple sections per template should be permitted.
-    data: { bool: true, two: 'second' }
-    template: |
-      {{#bool}}
-      * first
-      {{/bool}}
-      * {{two}}
-      {{#bool}}
-      * third
-      {{/bool}}
-    expected: |
-      * first
-      * second
-      * third
-
-  - name: Nested (Truthy)
-    desc: Nested truthy sections should have their contents rendered.
-    data: { bool: true }
-    template: "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |"
-    expected: "| A B C D E |"
-
-  - name: Nested (Falsey)
-    desc: Nested falsey sections should be omitted.
-    data: { bool: false }
-    template: "| A {{#bool}}B {{#bool}}C{{/bool}} D{{/bool}} E |"
-    expected: "| A  E |"
-
-  - name: Context Misses
-    desc: Failed context lookups should be considered falsey.
-    data: { }
-    template: "[{{#missing}}Found key 'missing'!{{/missing}}]"
-    expected: "[]"
-
-  # Implicit Iterators
-
-  - name: Implicit Iterator - String
-    desc: Implicit iterators should directly interpolate strings.
-    data:
-      list: [ 'a', 'b', 'c', 'd', 'e' ]
-    template: '"{{#list}}({{.}}){{/list}}"'
-    expected: '"(a)(b)(c)(d)(e)"'
-
-  - name: Implicit Iterator - Integer
-    desc: Implicit iterators should cast integers to strings and interpolate.
-    data:
-      list: [ 1, 2, 3, 4, 5 ]
-    template: '"{{#list}}({{.}}){{/list}}"'
-    expected: '"(1)(2)(3)(4)(5)"'
-
-  - name: Implicit Iterator - Decimal
-    desc: Implicit iterators should cast decimals to strings and interpolate.
-    data:
-      list: [ 1.10, 2.20, 3.30, 4.40, 5.50 ]
-    template: '"{{#list}}({{.}}){{/list}}"'
-    expected: '"(1.1)(2.2)(3.3)(4.4)(5.5)"'
-
-  - name: Implicit Iterator - Array
-    desc: Implicit iterators should allow iterating over nested arrays.
-    data:
-      list: [ [1, 2, 3], ['a', 'b', 'c'] ]
-    template: '"{{#list}}({{#.}}{{.}}{{/.}}){{/list}}"'
-    expected: '"(123)(abc)"'
-
-  # Dotted Names
-
-  - name: Dotted Names - Truthy
-    desc: Dotted names should be valid for Section tags.
-    data: { a: { b: { c: true } } }
-    template: '"{{#a.b.c}}Here{{/a.b.c}}" == "Here"'
-    expected: '"Here" == "Here"'
-
-  - name: Dotted Names - Falsey
-    desc: Dotted names should be valid for Section tags.
-    data: { a: { b: { c: false } } }
-    template: '"{{#a.b.c}}Here{{/a.b.c}}" == ""'
-    expected: '"" == ""'
-
-  - name: Dotted Names - Broken Chains
-    desc: Dotted names that cannot be resolved should be considered falsey.
-    data: { a: { } }
-    template: '"{{#a.b.c}}Here{{/a.b.c}}" == ""'
-    expected: '"" == ""'
-
-  # Whitespace Sensitivity
-
-  - name: Surrounding Whitespace
-    desc: Sections should not alter surrounding whitespace.
-    data: { boolean: true }
-    template: " | {{#boolean}}\t|\t{{/boolean}} | \n"
-    expected: " | \t|\t | \n"
-
-  - name: Internal Whitespace
-    desc: Sections should not alter internal whitespace.
-    data: { boolean: true }
-    template: " | {{#boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
-    expected: " |  \n  | \n"
-
-  - name: Indented Inline Sections
-    desc: Single-line sections should not alter surrounding whitespace.
-    data: { boolean: true }
-    template: " {{#boolean}}YES{{/boolean}}\n {{#boolean}}GOOD{{/boolean}}\n"
-    expected: " YES\n GOOD\n"
-
-  - name: Standalone Lines
-    desc: Standalone lines should be removed from the template.
-    data: { boolean: true }
-    template: |
-      | This Is
-      {{#boolean}}
-      |
-      {{/boolean}}
-      | A Line
-    expected: |
-      | This Is
-      |
-      | A Line
-
-  - name: Indented Standalone Lines
-    desc: Indented standalone lines should be removed from the template.
-    data: { boolean: true }
-    template: |
-      | This Is
-        {{#boolean}}
-      |
-        {{/boolean}}
-      | A Line
-    expected: |
-      | This Is
-      |
-      | A Line
-
-  - name: Standalone Line Endings
-    desc: '"\r\n" should be considered a newline for standalone tags.'
-    data: { boolean: true }
-    template: "|\r\n{{#boolean}}\r\n{{/boolean}}\r\n|"
-    expected: "|\r\n|"
-
-  - name: Standalone Without Previous Line
-    desc: Standalone tags should not require a newline to precede them.
-    data: { boolean: true }
-    template: "  {{#boolean}}\n#{{/boolean}}\n/"
-    expected: "#\n/"
-
-  - name: Standalone Without Newline
-    desc: Standalone tags should not require a newline to follow them.
-    data: { boolean: true }
-    template: "#{{#boolean}}\n/\n  {{/boolean}}"
-    expected: "#\n/\n"
-
-  # Whitespace Insensitivity
-
-  - name: Padding
-    desc: Superfluous in-tag whitespace should be ignored.
-    data: { boolean: true }
-    template: '|{{# boolean }}={{/ boolean }}|'
-    expected: '|=|'
diff --git a/stache.cabal b/stache.cabal
--- a/stache.cabal
+++ b/stache.cabal
@@ -31,7 +31,7 @@
 -- POSSIBILITY OF SUCH DAMAGE.
 
 name:                 stache
-version:              0.1.7
+version:              0.1.8
 cabal-version:        >= 1.10
 license:              BSD3
 license-file:         LICENSE.md
@@ -46,7 +46,7 @@
 extra-doc-files:      CHANGELOG.md
                     , README.md
 data-files:           bench-data/*.mustache
-                    , specs/*.yml
+                    , specification/*.yml
                     , templates/*.mustache
 
 source-repository head
@@ -97,7 +97,7 @@
                     , hspec            >= 2.0  && < 3.0
                     , hspec-megaparsec >= 0.2  && < 0.4
                     , megaparsec       >= 5.0  && < 6.0
-                    , stache           >= 0.1.7
+                    , stache           >= 0.1.8
                     , text             >= 1.2  && < 1.3
   other-modules:      Text.Mustache.Compile.THSpec
                     , Text.Mustache.ParserSpec
@@ -122,7 +122,7 @@
                     , file-embed
                     , hspec            >= 2.0  && < 3.0
                     , megaparsec       >= 5.0  && < 6.0
-                    , stache           >= 0.1.7
+                    , stache           >= 0.1.8
                     , text             >= 1.2  && < 1.3
                     , yaml             >= 0.8  && < 0.9
   if flag(dev)
@@ -140,10 +140,10 @@
                     , criterion        >= 0.6.2.1 && < 1.2
                     , deepseq          >= 1.4  && < 1.5
                     , megaparsec       >= 5.0  && < 6.0
-                    , stache           >= 0.1.7
+                    , stache           >= 0.1.8
                     , text             >= 1.2  && < 1.3
   if flag(dev)
-    ghc-options:      -Wall -Werror
+    ghc-options:      -O2 -Wall -Werror
   else
     ghc-options:      -O2 -Wall
   default-language:   Haskell2010
