Skip to content

Matchers

Matchers allow you to validate dynamic content in your Markdown documents. There are two types of matchers: regex matchers that match patterns using regular expressions, and all matchers that match everything as an identity function.

A regex matcher is defined using inline code syntax with a specific format: `label:/pattern/`

`label:/regex-pattern/`
  • label: An identifier for the matched value (used in validation output)
  • pattern: A regular expression that matches the content

The pattern is automatically anchored to the start (as if prefixed with ^), so it matches from the beginning of the available text.

schema.mds
`name:/\w+/`
input.md
Alice
Output:
{"name": "Alice"}
schema.mds
`age:/\d+/`
input.md
42
Output:
{"age": "42"}
schema.mds
`name:/\w+/`
input.md
123
schema.mds
`age:/\d+/`
input.md
not a number

All matchers act as an identity function - they always match and return exactly what was passed to them. If a matcher has no regex pattern (just a label in backticks), it becomes an all matcher that accepts all available content in the current context.

The syntax is simply `label` without a regex pattern.

schema.mds
`foo`
input.md
anything goes here
Output:
{"foo":"anything goes here"}
schema.mds
`data`
input.md
@*&^R special chars
Output:
{"data":"@*&^R special chars"}

All matchers accept any input including special characters, spaces, and other spanning (inline) nodes:

schema.mds
`text`
input.md
hello *world* 123!
Output:
{"text":"hello *world* 123!"}
schema.mds
`content`
input.md
*italic text* and regular text
Output:
{"content":"*italic text* and regular text"}
schema.mds
Prefix: `data`
input.md
Prefix: *some italic* and more
Output:
{"data":"*some italic* and more"}

Both regex matchers and all matchers can be combined with literal text as prefixes and suffixes:

schema.mds
Name: `name:/w+/`
input.md
Name: Alice
Output:
{"name":"Alice"}
schema.mds
`count:/d+/` items
input.md
42 items
Output:
{"count":"42"}
schema.mds
User `id:/d+/` logged in
input.md
User 123 logged in
Output:
{"id":"123"}
schema.mds
Name: `name:/w+/`
input.md
Name:
schema.mds
`count:/d+/` items
input.md
42 things

Matchers can work across different spanning node types, like italics and subsequent code spans:

schema.mds
User `id:/d+/` logged in *this is italic*)
input.md
User 123 logged in
Output:
{"id":"123"}
schema.mds
*test*test`foo:/bar/`wolf
input.md
*test*testbarwolf
Output:
{"foo":"bar"}

Matcher labels (for both regex matchers and all matchers) must follow these rules:

  • Must contain only alphanumeric characters (a-z, A-Z, 0-9), hyphens (-), and underscores (_)
  • Cannot contain spaces or other special characters
  • Valid examples: user_name, item-count, id123, MyData
  • Invalid examples: user name (space), data@field (special char), item.count (period)
🚧 Not Implemented Yet

To match without capturing a value, use an underscore (_) as the label:

schema.mds
`_:/w+/`
input.md
hello
Output:
{}

Right now, you can only have one matcher per paragraph (collection of spanning elements). So, for example, the following will not work:

schema.mds
`_:/w+/` `_:/w+/`
input.md
hello

You can validate multiple paragraph nodes into an array by using a repeated matcher. The repeated matcher syntax is {min,max}, where min and max are optional.

Important: Repeating paragraph matchers must be all matchers (`label`), not regex matchers. This is because each paragraph can contain arbitrary content and structure.

schema.mds
`description`{2,3}
input.md
First paragraph.
Second paragraph with *formatting*.
Third paragraph.
Output:
{"description":["First paragraph.","Second paragraph with *formatting*.","Third paragraph."]}
schema.mds
`content`{1,2}
input.md
Only one paragraph here.
Output:
{"content":["Only one paragraph here."]}
schema.mds
`text`{3,3}
input.md
First.
Second.

To match inline code blocks literally instead of treating them as matchers, add ! after the code block:

schema.mds
`test`!
input.md
`test`
schema.mds
The code is `example`! here
input.md
The code is `example` here
schema.mds
`test`!
input.md
test
🚧 Not Implemented Yet

Use !! to match a literal exclamation mark after code:

schema.mds
`code`!!
input.md
`code`!
🚧 Not Implemented Yet

You can validate content by running an executable. Use the syntax label:!command:

schema.mds
`number:!test $0 -gt 0`
input.md
42
Output:
{"number":"42"}

The matched content is passed to the executable:

  • As arguments ($0, $1, etc.)
  • Via stdin (if command reads from stdin)

Exit code 0 means validation passes. Any other exit code indicates failure.