JavaScript implementation of the Markless document markup standard
https://shirakumo.org/docs/markless-js
- JavaScript 94.6%
- CSS 3.1%
- HTML 2.3%
# About Markless-JS
This is an ECMA6/JavaScript implementation of the ''Markless''(link https://shirakumo.org/docs/markless) document markup standard. It provides a module to parse Markless documents into an abstract tree representation, as well as a transform to turn that AST into HTML for display.
The system is written in a modular way, allowing you to extend it with additional component types, markup syntax, and to customise the transformation into other representations.
Markless-JS can be used directly in the browser, or as a NodeJS module. If you would like to give it a try, an ''interactive demonstration''(link https://shirakumo.org/docs/markless-js) based on this library is also available.
## Basic Usage
The most basic usage is simply via ``parse`` to parse a document in its string form, and ``toHTML`` to turn the resulting AST into ``HTMLElement``s which you can then append to the browser document somewhere, or serialise out to a string.
::javascript
import {parse,toHTML} from "markless";
console.log(toHTML(parse("# Hello!")).outerHTML);
::
### Constraining Syntax
By default Markless includes a couple of constructs that can be dangerous if exposed to untrusted users, such as on messaging apps or general posting environments.
Markless-JS allows you to constrain the syntax that is permitted quite thoroughly, and also includes default sets for use in such constrained environments. For example:
::javascript
import * as markless from "markless";
markless.parse("! error Hah!", {
directives: markless.messagingDirectives,
embedTypes: markless.messagingEmbedTypes,
embedOptions: markless.messagingEmbedOptions,
compoundOptions: markless.messagingCompoundOptions});
::
You can of course also use your own sets of directives and so on to fit your specific use-case.
### Note for NodeJS
In the NodeJS case, please be aware that the HTML conversion will return an ad-hoc, minimal DOM implementation rather than relying on jsdom, due to browser compatibility problems.
If you require more sophisticated HTML DOM manipulation, the advice is to simply use ``el.outerHTML`` to retrieve the stringified representation of the HTML and re-parse that with your DOM implementation of choice.
## New Directives
The parser is written in such a way that you can extend it with new directives and components not part of standard Markless. To do this you'll want to create subclasses of ``Component`` and ``Directive``, then include the new directives in your ``Document``s to activate their syntax.
A simple example to provide left and right quotes follows
::javascript
import * as markless from "markless";
class LeftQuote extends markless.components.UnitComponent{
kind = markless.components.Inline;
get text(){ return '\u201C'; }
}
class RightQuote extends markless.components.UnitComponent{
kind = markless.components.Inline;
get text(){ return '\u201D'; }
}
class LeftQuoteDir extends markless.directives.InlineDirective{
name = 'left-quote';
prefix = / "/y;
begin(_line, cursor){
this.document.top.component.children.push(
this.makeComponent(LeftQtuote.consructor, {}, cursor));
return cursor+2;
}
}
class RightQuoteDir extends markless.directives.InlineDirective{
name = 'left-quote';
prefix = /"[. ]/y;
begin(_line, cursor){
this.document.top.component.children.push(
this.makeComponent(RightQtuote.consructor, {}, cursor));
return cursor+2;
}
}
new markless.parse('She said "Ha ha ha".', {
directives: [new LeftQuoteDir(), new RightQuoteDir(), ...markless.defaultDirectives]
});
::
You may also want to split the component and directive definitions into their own respective modules, in the same way as they are split in Markless-JS itself. That way they can both keep the same class names.