Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

A extensible macro parser/processor implementation recognizing creole style macros/extension written in javascript for browser and Node usage

License

GPL-2.0, MIT licenses found

Licenses found

GPL-2.0
LICENSE-GPL
MIT
LICENSE-MIT

lgersman/orangevolt-macrop

Repository files navigation

ATTENTION : Orangevolt Gentle contains a newer updated version of orangevolt-macrop completely rewritten in ES6.

This repository is kept alive just for historical reasons.

Build status Dependency status NPM version Bitdeli Badge

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.

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

  • NodeJS

    $ 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 on macro.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 true applied
  • Attributes without a value with a heading ! will be intepreted as flag with value false applied
  • 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

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 :

     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 :

     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.git

Start hacking, your help is appreciated. :-)

You can execute

grunt dev

to 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 -p

to 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

About

A extensible macro parser/processor implementation recognizing creole style macros/extension written in javascript for browser and Node usage

Resources

License

GPL-2.0, MIT licenses found

Licenses found

GPL-2.0
LICENSE-GPL
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published