home tools

Neopolitan

Notes with Superpowers

Head's up

Neopolitan is currently embedded in the app I use to build my websites. I'm in the process of splitting it out to its own project. It won't be available for general use until that work is finished. I'll update this page when it's ready.

Introduction

Neopolitan is a way to take notes. It's easy to learn, quick to customize, and super powerful.

Sections

Section Names

Neopolitan note are made of sections. Sections are defined by lines that start with two dashes followed by a name. Content for the section comes after an empty line.

-- title

A Neopolitan Overview
The section names can be pretty much anything as long as they don't contain spaces.

Section Flags and Attributes

Sections can have metadata attached to them in the form of flags and attributes.

Flags are pieces of text that start with two dashes on the lines below a section name. For example, this is an image section with a flag for the image's filename. The content portion of the section is used for the image's alt text:

-- image 
-- example-image.jpg

This is where the alt text for the image goes.
Attributes work the same way as flags but start with a keyword followed by a colon. For example, here's a "aside" section with a "class" attribute of "warning":
-- aside 
-- class: warning

There is where you can put something 
that needs extra attention.

Section Types

Section content is treated as paragraphs by default. Adding a section type after a section name changes the handling. Two section types are "list" and "checklist". Changing the type of a section is done by the name of the type after the name of the section:

-- notes list

- A note about something. 

- Another note about something.
-- todo checklist 

[] Something that needs to be done

[x] Something that has been done.
The section types can also be used generically as their own section names:
-- list

- Item for a list without a more
specific section name. 

- And another item for the list.
List of Section Types

The full list of section types is:

Special Sections

There are a few section sections that aren't parsed as paragraphs by default. They are:

The defaults for these sections map to how they'll be used the majority of the time. They ensure that different implementations of Neopolitan will have a consistent baseline.

Spans

Section content can contain spans. They're snippets that wrap text to alter it in some way.

Example Span

A basic span looks like this:

<<code|console.log()>>
The parts are:

Here's what a span looks like surrounded by more content:

The JavaScript function <<code|console.log()>>
prints information to the developer console.
When that content is turned into a web page the span turns into an HTML `<code>` tag like this:
The JavaScript function <code>console.log()</code>
prints information to the developer console.

Span Attributes

Spans can have attributes that further enhance their content. They're added by using additional pipes to separate them from the content. For example, a class attribute can be added to the span like this:

<<code|console.log()|class: featured>>
which outputs this HTML:
<code class="featured">console.log()</code>
Multiple attributes can be added by using more pipes. For example, this span (which also shows how spans can be split across lines) adds a `data-language` attribute that can be used to apply syntax highlighting to the code:
<<code
  |console.log()
  |class: featured
  |data-language: javascript>>
The output HTML looks like this:
<code class="featured" data-language="javascript">console.log()</code>

Span Shorthands

There are shorthands for frequenly used spans. For example, backtics denote code spans. The orignal example above:

<<code|console.log()|class: featured|language: javascript>>
can be written as:
``console.log()|class: featured|language: javascript``
Full List of Span Shorthands

Content Generation

Neopolitan notes are designed to be turned into or other forms of content (e.g. web pages). Apps apply templates to the notes to generate the final content. Since each app is responsible for its own templates, the same note can be laid out in any number of ways. Updating templates redesigns pages without having to change the notes.

Technical Overview

Neopolitan is a specification for turning a plain-text document into an Abstract Syntax Tree (AST). Parsers are responsible for converting notes into ASTs. Those ASTs are handed off to other processes that are responsible for generating the final output.

The AST identifies the names, types, flags and attributes of sections and spans. Content generators match those details with corresponding templates to render the final output. The specifics of how that happens are the responsibility of the generator.

Why Not Markdown?

Neopolitan is similar to another format called Markdown. Both rely on text files to store their content and formatting details. The first question anyone who knows about Markdown asks when I tell them about Neopolitan is why I don't use it instead.

The short answer comes down the the core design features of Neopolitan:

Layout Flexibility

Here's an example to help demonstrate what Neopolitan is capable of. It's a book-review section that includes attributes for the title, author, and cover image along with the review itself.

-- book-review
-- title: Dungeon Crawler Carl
-- author: Matt Dinniman
-- cover: dungeon-crawler-carl-cover.jpg

First off, I did the audio book instead
of the paper copy. I don't know how much
I would have liked the physical version
but the narrator for the audio book
is absolute gold. 

etc.
Apps that use Neopolitan can access the content and attributes as independent pieces of data. They can be placed wherever they need to be in the output. The HTML for a web page might looks like this:
<div class="book-review">
  <div>
    <img 
      src="dungeon-crawler-carl-cover.jpg"
      alt="The book cover for Dungeon Crawler Carl"
    />
  </div>
  <div>
    <div class="title">Dungeon Crawler Carl</div>
    <div class="by">by Matt Dinniman</div>
    <p>
      First off, I did the audio book instead
      of the paper copy. I don't know how much
      I would have liked the physical version
      but the narrator for the audio book
      is absolute gold. 
    </p>
    <p>
      etc.
    </p>
  </div>
</div>
When, in turn, gets rendered like this:
The book cover for Dungeon Crawler Carl
Dungeon Crawler Carl
by Matt Dinniman

First off, I did the audio book instead of the paper copy. I don't know how much I would have liked the physical version but the narrator for the audio book is absolute gold.

etc.

Achieving that layout in Markdown would require writing the HTML directly in the file. That's entirely possible but removes the ability to change the layout without editing every document that has a book review in it. It also means you can't use the same content in multiple ways without duplicating it.

Data Access

Neopolitan allows section content, flags, and attributes to be treated as data that's available beyond the individual notes that contain them. Consider a collection of notes that have book reviews scattered among them. You can generate a page that lists all their titles and authors in one place with links pointing to the full review. Another page could be created for each author listing all the books by them that you've reviewed.

Your content effectively becomes a database you can query to output content in any number of ways. All without having to maintain different copies of the same content in multiple places.

Wrap-Up

Neopolitan is designed to be as simple as possible while providing flexibility for your content. Defining your own sections, spans, attributes, and flags let you create notes for just about anything. The ability to treat everything as data means you can lay out, link and, index your content out in any number of ways.

I've been using Neopolitan for a few years and couldn't be happier with it.
Once the parser is available, I hope you'll enjoy it too.

-a

Endnotes