This node.js module implements an org-mode file format parser. Org-mode is a cool Emacs package that lets you structure information in a nice way, and export it in html, latex, pdf and so on.
I was unable to find a JavaScript parser for org-mode. Now we have one. Org-mode is so useful you will start writing in org-mode instead of text files for everything needing a bit of structuring.
It is also XML-free and yes, we like it :)
A lot of unit testing (over 90) and a pretty fast parser (see below). Also, it has minimal requirements.
Take a look at http://gioorgi.com/tag/org-mode-parser/ for latest news
The full installation can be obtained via the npm package repository On a shell which can run node, try out these lines:
curl http://nodejs.org/dist/v0.10.28/node-v0.10.28.tar.gz | tar xzvf -
(cd node-v0.10.28/ ; ./configure --prefix=$HOME ; make && make install)
curl --insecure https://www.npmjs.org/install.sh | bash
npm install org-mode-parser
or launch fast-install.sh
var org=require('../lib/org-mode-parser');
org.makelist("README.org", function (nodelist){
// Here nodelist is a list of Orgnode objects (ref:putyourcode)
console.dir(nodelist[0]);
});
The parser’s main entry point is the makelist function, which accepts a filename and a callback function. makelist() will pass to the function the list of parsed nodes as first parameter, as described in the opening example.
You can optionally build a query object called OrgQuery to easily select subtree, search tags, et cetera:
var org=require('../lib/org-mode-parser');
org.makelist("./test/treeLevel.org",function(nodes){
var ofd=new org.OrgQuery(nodes);
// ofd is a complex object for use in querying and so on
console.log(ofd.selectTag('complex').first().toOrgString());
});
Supported methods of OrgQuery are:
- selectSubtree(node) Extract the nodes hierarchically below the given input
- selectTag(tagString)
- sortBy
- reject(function)
- rejectTag(tagName)
- toArray()
- each(functionToPassEach)
- random() Extract a random element
- toHtml(options) Generate a fair html rendering. This code is not meant to replace org-mode export functionality, but can be an handy friend. For options usage example see test/to-html-test.js
See the unit test section ‘basicLibraries OrgQuery-Complex’ on test/parseTest.js for more usage examples, and do not miss the FAQ
The input must be a well-formed org-mode file. Parser can detect some corruptions, but it does not provide a complete sanity check.
In general, every API component described in the API section is here to stay. Compatibility will be retained as far as possible in future releases.
At the time of writing, the parser is pretty fast. On a Linux virtual machine, we get about 20.000 nodes per seconds. We will keep an eye on performance.
You are welcome to help us stress test the parser and find its true limits.
Org-mode-parser depends only on two packages, underscore and vows. Vows dependency is used only for regression tests, so the parser really depends only on underscore.
Take a look at the examples/ directory for some tiny examples. Please look at test/parserTest.js file for API usage examples. Tests are commented and pretty self-explanatory: they are the primary source for correctness of this module.
On npm repository. The master branch on GitHub is the development version, so use it at your own risk.
OrgQuery is a very handy object (see below), because it allows you to filter nodes in a structured way. Use it instead of hand-parsing.
Use the OrgQuery.rejectArchived() method
Yes, but org mode wants them to be declared (see par 2.9 Drawers on documentation). Thus, it is best to not rely on undeclared drawers, because the parser could change in the future to be more stringent. Also, undeclared drawers are not indented!
var org=require('../lib/org-mode-parser');
org.makelist("./README.org",function(nl){
var q=new org.OrgQuery(nl);
var subtree=q.selectSubtree(q.selectTag('releaseNotes').first());
console.log("Dev version is:"+subtree.selectTag('dev').first().headline);
});
No, at least not at the moment.
Code name: Tetzuya
- Simple html rendering engine. Jade is an optional requirement if you want to use it as template engine. It is requiered on-demand. Anyway we suggest to install it
- Support for source block #+begin_src / #+end_src
- Quickcheck for stronger unit test (only embrional setup)
- Fixes by contributors:
- Support for closed timestamp (thesebas/feature/closed-timestamp)
- data-language addition (by guozhen)
- [fix] don’t parse lien when processing source code (by guozhen)
- Style/language pass on README.org (by aviav)
- fix typo in README.org (by kevzettler)
- fix up tortureTest to not crash the parser in the malformed property drawer (by natto)
- Merge branch ‘client-side-rendering’ into api/extension (giorgi + natto)
- Nodejs 4.x+ required (do not tested below, should work anyway)
- Added CONTTRIB file
Potential break-change: Now unknown directive are retained
Republish (0.1.0 never see light)
- Visual Studio 2015 compatibility
- Tested on node v0.12.2
- API Change: IllegalArgumentException and ParseError disappears. They are replaced with simple Error object because in node 0.10.x the toString() of the old objects was wrong. Parsing error are targeted to human beings, so avoid trapping them for complex recovery puropse
- Added the examples/site-publisher example
- Tested against latest node version
- Removed direct dependecy from vows, only used for testing
anOrgQuery.selectSubtree(i) now will accept only these types of i objects:
- A Orgnode
- A 1-size OrgQuery collection
- empty/null
Keep in mind the following rule for understanding the behavior:
q.selectSubtree(emptyNodeList) === q.selectSubtree(null) == q.selectSubtree() === q
which is a bit naif, but it will not break the existing API.
Evaluted the option of omitting first() on mono results, but API gets dirty. For play with it, see commit tag dev_orgquery_one_node_merge (6dd58da5e3a90e3f651bba4949cbe7b95155bc6b) and serch for the use of the “mergeFrom” method, now disabled.
Minor documentation fixes
- Addedd support for generic :DRAWER: syntax
- Archive tag is supported
Missed:
- links/ Footnotes are still completly missed
- Ordered/Bulletin list are still missed, but org-mode will present it in a nice way anyway
- Added new OrgQuery methods:
- sortBy
- reject
- toArray
- each
- :PROPERTIES: without :END: generates an error now. The parser is quite weak, but can detect this simple case.
BUGFIXES:
- OrgQuery had a bug, and collected nodes could not be unique in some rare situations. Now we relay on underscore library for generating unique id
- Added a set of stronger guards on constructors
- Added the ability to regenerate the Orgnode as string using the method toOrgString() Be carefully, the method is still experimental and do not emit: a) Comments b) SCHEDULE,DEADLINE and CLOCK directive
- Added the OrgQuery object, for doing queries like
- subtree extraction with .selectSubtree
- tag-based searches with selectTag
Even if the OrgQuery try to play nice, it is not yet an array, so avoid using it directly with _.each(…)
- Comments are stripped off during parsing.
- Special directive starting with ‘#+’ are mostly ignored during the parsing, for instance #+AUTHOR etc
- Tables are not parsed at all.
- In org-mode tags cannot have “-” character in name. They are split in subwords. The parser allow this instead, so be careful when editing by hand org files.
- properties can have “-” but this will force you to access them with the array syntax instead of the dot notation, so we strongly suggest to avoid “-” and special java character in property names. Relay on “_”, for instance.
- SCHEDULE,DEADLINE and CLOCK directives now are correctly parsed
- Added a performance watchdog to track slowdowns
- Added the ability to return performance data via makelist
- Started restructuring parser for better performance.
- Minor API Change: null is the default value for tag,priority,scheduled, deadline when not set. e.tags.existingtag is true if existingtag is there. Anyway is better to use “existingtag” in e.tags which is a better syntax
First revision
https://github.com/daitangio/org-mode-parser
Globally install vows and try out something like:
npm install -g vows@0.7.0
NODE_PATH=$(dirname $(which node))/../lib/node_modules:. ./bin/testme
At the time of writing, the github repository is the master code repository
- Check the package.json version
- Issue the following commands:
./bin/releaseVersion.sh ORG_MODE_PARSER_0.0.6