uniorg is an accurate Org-mode parser compatible with unified ecosystem.
Why
I want to publish my braindump from org-mode notes. None of the parsers I tried have provided enough precision.
uniorg strives for parsing accuracy rather than speed or ease of writing the parser.
uniorg follows Org Syntax and Org Element API. It draws heavily from org-element.el, which means uniorg sees org files the same way as org-mode does. The code is full of regexes but that's exactly how org-mode parses files.
Though, there are a couple of intentional deviations from org-mode that make Uniorg more pleasant or easier to work with.
Demo
- https://braindump.rasen.dev/uniorg โ play with how uniorg parses and translates org files.
- examples/next-blog-starter โ uniorg-powered Next.js blog example (https://org-blog-starter.vercel.app).
- examples/org-braindump โ uniorg-powered Next.js website tailored to publishing an interlinked collection of notes (https://org-braindump.vercel.app).
- examples/example โ a simple CLI tool to convert org files to html.
Status
uniorg successfully parses most of the org syntax. However, there are a couple of places I haven't finished yet:
- inlinetask
- babel-call, inline-babel-call, inline-src-block
- dynamic-block
- target, radio-target
- line-break
- export-snippet
- macro
- switches and parameters in src-block and example-block
- repeater/warning props in timestamp
The rest of the syntax should work fine and exactly the same way as in Emacs (including complex list nesting, links, drawers, clock entries, latex, etc.). If you want to help with items above, grep parser.ts for TODO:
.
Packages
This repository contains the following packages:
uniorg
โ Typescript definitions of uniorg syntax treeuniorg-parse
โ Parse org-mode files to uniorg syntax treesuniorg-stringify
โ Stringify uniorg syntax tree to org-mode stringuniorg-rehype
โ Transform uniorg syntax trees to rehypeuniorg-extract-keywords
โ Store org-mode keywords to vfileuniorg-attach
โ Convertattachment:
links tofile:
linksuniorg-slug
โ Add anchors to headings using GitHub's algorithmorgast-util-to-string
โ Utility to get the plain text content of a nodeorgast-util-visit-ids
โ Utility to visit all org nodes with ids
unified
uniorg is compatible with unified ecosystem, so you can take advantage of many existing plugins.
For example, here's how you transform an org-mode to html.
import { unified } from 'unified';
import parse from 'uniorg-parse';
import uniorg2rehype from 'uniorg-rehype';
import stringify from 'rehype-stringify';
const processor = unified().use(parse).use(uniorg2rehype).use(stringify);
processor
.process(`* org-mode example\n your text goes here`)
.then((file) => console.log(file.value));
Plugins for code syntax highlight (rehype-highlight, @mapbox/rehype-prism) and latex-formatting (rehype-katex, rehype-mathjax) should work out of the box:
import { unified } from 'unified';
import parse from 'uniorg-parse';
import uniorg2rehype from 'uniorg-rehype';
import highlight from 'rehype-highlight';
import katex from 'rehype-katex';
import stringify from 'rehype-stringify';
const processor = unified()
.use(parse)
.use(uniorg2rehype)
.use(highlight)
.use(katex)
.use(stringify);
processor
.process(
`* org-mode example
When $a \ne 0$, there are two solutions to \(ax^2 + bx + c = 0\) and they are
$$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$
#+begin_src js
console.log('uniorg is cool!');
#+end_src
`
)
.then((file) => console.log(file.value));