orangevolt-macrop v0.1.4
ATTENTION : Orangevolt Gentle contains a newer updated version of orangevolt-macrop completely rewritten in ES6.
This repository is kept alive just for historical reasons.
orangevolt-macrop provides a NPM module and browser script suitable for parsing extended Creole Wiki generic extension elements (the "Double-less-than-greater-than" notation to be concrete).
orangevolt-macrop is more or less a fully configurable macro processor ... thats why it's named macrop :-)
What is it good for ?
When generating HTML (or even text) you can utilize orangevolt-macrop to inject something using macros, no matter what kind of source text you use ( Markdown, gfm or just HTML).
The package provides an API to parse text and a higher level method to encapsulate the parser and your macros.
Creole Wiki generic extension element syntax
orangevolt-macrop recognizes Creole Wiki generic extension element syntax including a few extras. Creole Wiki generic extension element is basically a bit like html but with doubled << and >> characters:
An example:
hello,
<<mymacro foo bar="mee" john=doe />>
Here is the example code : 
<<highlight caption="javascript">>
	var s = "hello world !";
	console.log( s);
<</highlight>>
That's it !orangevolt-macrop API method parse( input) will split the input into strings and parsed macro objects :
[
  "hello,\n",
  {
    "source": "<<mymacro foo bar=\"mee\" john=doe />>",
    "namespace": "",
    "name": "mymacro",
    "attributes": {
      "foo": true,
      "bar": "mee",
      "john": "doe"
    },
    "content": ""
  },
  "\n\nHere is the example code : \n\n",
  {
    "source": "<<highlight caption=\"javascript\">>\n\tvar s = \"hello world !\";\n\tconsole.log( s);\n<</highlight>>",
    "namespace": "",
    "name": "highlight",
    "attributes": {
      "caption": "javascript"
    },
    "content": "\tvar s = \"hello world !\";\n\tconsole.log( s);"
  },
  "\n\nThat's it !"
]You can apply macros by simply iterating over the returned array and process the array contents.
a more complex example incorporating macro namespaces :
sadsadsaa
<<ns1-ns2:ns3:too 
  co-al-foo 
  ns1-ns2:ns3:bar="JOHN DOE" 
  content="
    take it from a 
    multiline attribute
  "
>>
  before
  <<source foo='bar' />>
  between
  <<rendered target="html"/>>
  after
<</ns1-ns2:ns3:too>>
        
whats up ?will be parsed into
[
  "sadsadsaa\n\n",
  {
    "source": "<<ns1-ns2:ns3:too \n  co-al-foo \n  ns1-ns2:ns3:bar=\"JOHN DOE\" \n  content=\"\n    take it from a \n    multiline attribute\n  \"\n>>\n  before\n  <<source foo='bar' />>\n  between\n  <<rendered target=\"html\"/>>\n  after\n<</ns1-ns2:ns3:too>>",
    "namespace": "ns1-ns2:ns3:",
    "name": "too",
    "attributes": {
      "co-al-foo": true,
      "ns1-ns2:ns3:bar": "JOHN DOE",
      "content": "    take it from a \n    multiline attribute"
    },
    "content": "  before\n  <<source foo='bar' />>\n  between\n  <<rendered target=\"html\"/>>\n  after"
  },
  "\n        \nwhats up ?\n    "
]Macros with namespace will be split into namespace and name where as attributes will no be split off (-> it's up to you).
They can be nested (when using different names for the nested macros) by recursively call the parse( input) method on node.content 
Requirements
orangevolt-macrop has no dependencies.
Installation
- ``$ npm install orangevolt-macrop``
- Browser - Link ``orangevolt-macrop.js`` source file via **SCRIPT** tag into your browser.
Features
- Macros can be nested (when using different names for the nested macros) by recursively call the parse( input)method onmacro.content
- Attributes names may contain :and-(execpt at start and end)
- Attributes without a value (like foo in the example) are intepreted as flags and will have value trueapplied
- Attributes without a value with a heading !will be intepreted as flag with valuefalseapplied
- Attributes values may be wrapped in ',"or simply provided as a token
- Macro names can be namespaced using :and/or-. The namespace is just informative and will not be taken into account for evaluating the right macro.
- Attribute values are allowed to be multiline
- Empty attribute values ( those only containing \r\n or \s) will be ''
- API method orangevolt.macrop( {})()A catch all macro can be applied using the macro name *
API
NodeJs
Assuming that you've already installed the orangevolt-macrop package you can access the API using
var macrop = require( './orangevolt-macrop.js').orangevolt.macrop;Browser
Include orangevolt-macrop in your web page :
<script type="text/javascript" src="orangevolt-macrop.js"></script>Now you can access the API using
var macrop = window.orangevolt.macrop;orangevolt.macrop
The package provides 3 functions :
- orangevolt.macrop.parse( input)- Parses the input and returns an mixed array of strings and **objects** (-> macros)
- orangevolt.macrop.process( /*parse output*/ nodes, /*macros*/ { ... }, /*optional options*/ { ... })- Processes the output of ``orangevolt.macrop.parse( input)`` using macros and return the resulting array. * input : the input string to parse * macros : an object providing macros * options : an optional **object** transporting options to your macros Example : ````javascript var macros = { mymacro : function( node, i) { /* node = { name : ..., namespace : ..., attributes : { ...}, content : ..., ... ) -> the node parsed by macrop i = the index of the node in the nodes argument of process(...) this = { result : [], // the resulting array nodes : [], // the nodes argument of process() macros : {}, // the macros argument options: {}} // the options argument } */ // do something here with the node data // and return what you want to see in the array returned by process( ... ) } } orangevolt.macrop.process( nodes, macros) ```` Fallback macro : If you provide a macro with key '__*__' it will be called when ever no macro with ``node.name`` was found.
- orangevolt.macrop( /*macros*/ { ... }, /*optional options*/ { ... })- Can be used to create a function encapsulating the parse/process call utilizing macros and options Example : ````javascript var macros = { ... }; // generate a pre configured macrop processor var processor = orangevolt.macrop( macros, {}); // processor will parse and process the input using the given macros and options processor( input); ````
Development
Clone the package from orangevolt-macrop
git clone git@github.com:lgersman/orangevolt-macrop.gitStart hacking, your help is appreciated. :-)
You can execute
grunt devto see the tests running utilizing gruntjs live-reload feature in your browser.
Caveats
When grunt dev aborts with Fatal error: watch ENOSPC message you're system is getting out of 
inotify watch handles. 
Go to the terminal and enter
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -pto increase inotify watch handles (See http://stackoverflow.com/questions/16748737/grunt-watch-error-waiting-fatal-error-watch-enospc).
Testing
$ npm test or $ grunt test
- Browser
$ grunt dev 
Navigate in the opened browser window to folder spec (http://localhost:9090/spec/)
License
orangevolt-macrop is dual licensed under



