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 (comma_separated, datetime, email, slug and url here)
  • Native API integration of completely custom types (markdown here)
  • Guaranteed data integrity, including prevention of unhandled extra fields
import enolib
import markdown as python_markdown
from enolib.locales import de
from enotype import comma_separated, datetime, email, slug, url

def markdown(value):
  return python_markdown.markdown(value)

# Makes the .required_xxx_value() and .optional_xxx_value() methods available below
enolib.register(comma_separated, datetime, email, markdown, slug, url)

def read_post(filename):
  with open(filename, 'r') as file:
    input = file.read()

  document = enolib.parse(input, locale=de, source=filename)
  author = document.fieldset('Verfasser')
  post = {
    'author': {
      'name': author.entry('Name').required_string_value(),
      'email': author.entry('Email').optional_email_value(),
      'website': author.entry('Website').optional_url_value()
    'title': document.field('Titel').required_string_value(),
    'date': document.field('Veröffentlicht').required_datetime_value(),
    'permalink': document.field('Permalink').required_slug_value(),
    'abstract': document.field('Abstract').optional_markdown_value(),
    'body': document.field('Text').required_markdown_value(),
    'tags': document.field('Tags').required_comma_separated_values()

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


Next page: AST inspection