Let's say you have some text, actually a bunch of text files, and maybe that looks like this:

---
layout: post
title: "Magic Missile"
date: 2014-08-24
source: PHB.257
classes: [sorcerer; wizard]
---

**1st-level evocation**

**Casting Time**: 1 action

**Range**: 120 feet

**Components**: V, S

**Duration**: Instantaneous

You create three glowing darts of magical force. Each dart hits a creature of your choice that you can see within range. A dart deals 1d4 + 1 force damage to its target. The darts all strike simultaneously, and you can direct them to hit one creature or several.

**At Higher Levels.** When you cast this spell using a spell slot of 2nd level or higher, the spell creates one more dart for each slot level above 1st.

Let's say you want it to look pretty, maybe like this:

Magic Missile

1st-level evocation
Casting Time: 1 action
Range: 120 feet
Components: V, S
Duration: Instantaneous

You create three glowing darts of magical force. Each dart hits a creature of your choice that you can see within range. A dart deals 1d4 + 1 force damage to its target. The darts all strike simultaneously, and you can direct them to hit one creature or several.

At Higher Levels.When you cast this spell using a spell slot of 2nd level or higher, the spell creates one more dart for each slot level above 1st.

Cool, but what if you have a bunch of that data, in various formats, and don't want to write a {python|php|perl|etc} script for all of them.

How about instead you just describe your data in a human readable way and then describe how you want it rendered and then have it all done for you? Sounds cool, yeah?

Well then...

How about you describe the file above like this:

expect(---)
expect(layout: post)
expect(title: ) readUnquote(title)
expect(date: ) skipLine()
expect(source:) skipLine()
expect(class:) readSurround(classes, ( ) )
expect(---)
expect(**) readWord(level) readUntil(**,school) skip(**)
expect(**Casting Time**: ) readLine(casting_time)
expect(**Range**: ) readLine(range)
expect(**Components**: ) hope(V, set(verbal, V)) skip(,) hope(S, set(somatic, S)) skip(,) hope(M, readLine(material))
expect(**Duration**: ) readLine(duration)
readUntil(**At Higher Levels.** , description)
hope(**At Higher Levels.**, readAll(scaling))

And then you describe how to render it like this:

### [.title]
| | |
| --- | --- |
| _[.level] [.school]_ |
| **Casting Time** | [.casting_time] |
| **Range** | [.range] |
| **Components** | [=if(verbal, V, )][=if(somatic, S, )][=if(material, M [.material])] |
| **Duration** | [.duration] |

[.description]

[=if(scaling,**At Higher Levels.** [.scaling])]

Here it is in action:

Taking this source data: magic-missile.markdown
And this input frame spell.frame
I run a parse() function, feeding it the markdown and frame
Which returns (actually ran this function to output this)
Array
(
[title] => Magic Missile
[classes] => sorcerer, wizard
[level] => 1st-level
[school] => evocation
[casting_time] => 1 action
[range] => 120 feet
[verbal] => V
[somatic] => S
[duration] => Instantaneous
[description] => You create three glowing darts of magical force. Each dart hits a creature of your choice that you can see within range. A dart deals 1d4 + 1 force damage to its target. The darts all strike simultaneously, and you can direct them to hit one creature or several.{!n}{!n}
[scaling] => When you cast this spell using a spell slot of 2nd level or higher, the spell creates one more dart for each slot level above 1st.{!n}
)
Finally, I pass that to a the render markdown spell.render
which also means I you can get at the parsed data as a json file (yup, this is also generated from dynamically from the above files)

This html is generated from the above 3 files:

Magic Missile

1st-level evocation
Casting Time 1 action
Range 120 feet
Components V S
Duration Instantaneous

You create three glowing darts of magical force. Each dart hits a creature of your choice that you can see within range. A dart deals 1d4 + 1 force damage to its target. The darts all strike simultaneously, and you can direct them to hit one creature or several.

At Higher Levels. When you cast this spell using a spell slot of 2nd level or higher