A complete example

This complete example is an extensive showcase of enolib, demonstrating that parsing eno, although more verbose than other formats, has much to offer:

  • Decoupling of the field names the user prefers/understands from the ones a developer wants to use in the code
  • Out of the box localized parser and validation errors that can be directly displayed to a non-technical user
  • Out of the box validation of predefined high-level types (commaSeparated, datetime, email, slug and url here)
  • Native API integration of completely custom types (markdown here)
  • Guaranteed data integrity, including prevention of unhandled extra fields
const fs = require('fs');
const enolib = require('enolib');
const markdownIt = require('markdown-it')();

const { de } = require('enolib/locales');
const { commaSeparated, datetime, email, slug, url } = require('enotype');

const markdown = value => markdownIt.render(value);

// Makes the .requiredXxxValue() and .optionalXxxValue() methods available below
enolib.register({ commaSeparated, datetime, email, markdown, slug, url }); 

const readPost = filename => {
  const input = fs.readFileSync(filename, 'utf-8');
  const document = enolib.parse(input, { locale: de, source: filename });
  const author = document.fieldset('Verfasser');
  const post = {
    author: {
      name: author.entry('Name').requiredStringValue(),
      email: author.entry('Email').optionalEmailValue(),
      website: author.entry('Website').optionalUrlValue()
    title: document.field('Titel').requiredStringValue(),
    date: document.field('Veröffentlicht').requiredDatetimeValue(),
    permalink: document.field('Permalink').requiredSlugValue(),
    abstract: document.field('Abstract').optionalMarkdownValue(),
    body: document.field('Text').requiredMarkdownValue(),
    tags: document.field('Tags').requiredCommaSeparatedValues()

  // Throws an error when there are unhandled, mis-typed or unneeded fields in the document
  return post;


Next page: AST inspection