TomatenMark

TomatenMark is a work-in-progress lightweight markup language inspired by to D★Mark, with two changes: anonymous blocks, and indentation-free blocks.

Examples

Some technical writing:

@begin section[important]

#title Something

Pork belly et tattooed aut corporis quidem intelligentsia. Impedit schlitz gastropub nihil meditation voluptatem ullam viral.

#note[important] Blah

~listing[lang=ruby]
def greet(name)
  puts "Uhh, hi #{name} I guess"

  roll_eyes
end
~

Pork belly et tattooed aut corporis quidem intelligentsia. Impedit schlitz gastropub nihil meditation voluptatem ullam viral.

@end section

It’s intended for structured technical writing, but It could work for a play, too. Here is a scene with some set description, dialogue and stage directions:

@begin scene

#desc Old wooden house interior or something.

@begin dia[who=Nora]
okay

well

can we agree now that you’ll
do what you need to do
to make the divorce ‘official’.
@end dia

@begin dia[who=Torvald]
and why do I need to do that.
@end dia

#dir Something wild happens idk.

@end scene

This would be parsed as something like this (as XML, because XML is not too terrible at making up prose tbh):

<scene>
  <desc>Old wooden house interior or something.</desc>
  <dialogue who="Nora">
    <p>okay</p>
    <p>well</p>
    <p>can we agree now that you’ll<br />do what you need to do<br />to make the divorce ‘official’.</p>
  </dialogue>
  <dialogue who="Torvald">
    <p>and why do I need to do that.</p>
  </dialogue>
  <dir>Something wild happens idk.</dir>
</scene>

To do: figure out parentheticals in this example.

Syntax model

There are four block types (regular, anonymous, begin/end, and literal), and one inline type.

Blocks

Regular block:

#warning This is some admonition of sorts.
#note[target=instructors] This is a message only for instructors.

The block type follows the opening #, and attributes can follow the block type.

Anonymous block:

Here is a regular paragraph.

Anonymous blocks don’t support attributes.

Begin/end:

@begin section

Here is a paragraph inside the section.

@end section
@begin monologue[who=Nora]

Oh woe blah blah etc.

@end monologue

The block type follows the @begin and @end keywords, and attributes can follow the block type.

Literal:

~listing
abc
something something

literal text here
~
~listing[lang=ruby]
def greet(name)
  puts "Uhh, hi #{name} I guess"

  roll_eyes
end
~

The block type follows the opening ~, and attributes can follow the block type. The block consists of everything until the closing ~; content between the opening and closing line will be treated as literal lines (i.e. no block elements will be interpreted), but can contain inline elements.

Inline

Inline is easier, because there is only one syntax: This is %emph{very} important.

Attributes

To do: Describe attributes

Document model

There are only two node types: text and element.

Text is just that —  text.

Elements have a type (optional the element is anonymous; e.g. note or nil), optional attributes (a key-value map), and children (an array of elements and/or text nodes).

Context

I am creating this markup language so that I can write Article: Operator precedence parsing explained.1

In Week­notes 2025 W04: Scary, man, I talked about this lightweight markup language for the first time. It has evolved since then — including the name.

See also


  1. Look, I am fully aware that I do not need to create a markup language to write this article. Just… leave me be! I enjoy this stuff! ↩︎