OpenIndented Markup Language

An indented, easy-to-parse, easy-to-read, easy-to-write markup language.

Home FAQ Implementation

The origin

OpenIndented Markup Language (OIML) started as a command language (with a different name) for a visual novel engine like system from a private company. I kept refining the syntax in my spare time in the last 4 years and this is the result.

What's so different about it?

Unlike most of the markup languages used for similar purposes (e.g. TOML, YAML, JSON), OIML does not have a separate "mapping" the only container construct in OIML is a kind of 3-tuple called a "block" which can in turn contains other blocks; this design originates from the command language it was derived from, where the syntax originally designed to represent a list of commands was reused as the syntax for mapping; in this regard, OIML is closer to XML rather than JSON and YAML. Consider this XML snippet:

<description>
  simple example build file
</description>
<!-- set global properties for this build -->
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>

<target name="init">
  <!-- Create the time stamp -->
  <tstamp/>
  <!-- Create the build directory structure used by compile -->
  <mkdir dir="${build}"/>
</target>

<target name="compile" depends="init"
      description="compile the source">
  <!-- Compile the Java code from ${src} into ${build} -->
  <javac srcdir="${src}" destdir="${build}"/>
</target>
        

XML like this can be trivially adapted to OIML:

decription:
    : simple example build file
// set global properties for this build
property name="src" location="src"
property name="build" location="build"
property name="dist" location="dist"

target name="init":
    // Create the time stamp
    tstamp
    // Create the build directory structure used by compile
    mkdir: ${build}

target name="compile":
    depends:
        : init
    description:
        : compile the soure
    // Compile the Java code from ${src} into ${build}
    javc srcdir="${src}" destdir="${build}"
        

A more "OIML-native" way is to write it like this:

decription:
    : simple example build file
// set global properties for this build
property: src
    location: src
property: build
    location: build
property: dist
    location: dist

target: init
    // Create the time stamp
    tstamp
    // Create the build directory structure used by compile
    mkdir: ${build}

target: compile
    depends:
        : init
    description:
        : compile the soure
    // Compile the Java code from ${src} into ${build}
    javc srcdir="${src}" destdir="${build}"
        

Why no multi-line string literal?

I found it extremely annoying to manually format multi-line string literals under the 80-column rule that a lot of people believe to be a superior rule to have, so I make sure the rule won't make sense and you'll have to enable word wrap in your editor.

See also:

Why prohibit tab altogether?

Because tab can have different width in different editor settings and OIML is indented, one could have make a mistake and have the wrong indent in their OIML files; to strictly uphold the core goal of strong predictability, using tab for indent is prohibited to make sure this kind of situation won't happen.

Why no anchors & aliases & tags etc. (like in YAML)?

Higher-level constructs like anchors are unnecessary for a markup language mainly aimed to be a configuration language; they make the language more complex while providing little to no real benefits. If you want higher-level constructs it's better to use a separate language like Dhall.

Did you get your idea from Plan9 ndb or Recfiles?

No. The command language I mentioned before was largely inspired by the scripting language of Ren'Py, but later it took on a life of its own.