Overview

Linenoise

Linenoise is a small library for creating DOM fragments from a terse syntax that somewhat resembles CSS selectors( see also 'zen code') fixme: link. The format can be somewhat ugly to look at, hence the name.

Download the code, minified if you like, from fixme url here. Add it to a script tag and you should be set.

The library is probably not super useful on node.js, so it's not in npm. It does however export itself if you load it under node, but it assumes there is a "document" object in the global scope.

Usage

When loaded, the library exports a single function, 'linenoise', in the global scope.

The 'linenoise' function takes a template string, and optionally an object with template values as arguments. It returns a DocumentFragment instance that can be inserted into a document.

Syntax

The syntax is a list of nodes and and inheritance markers. Tag nodes look like CSS selectors:

a#some-id.some_class.other_class[href=http://example.org]

This translates into

<a id="some-id" class="some_class other_class" href="http://example.org"></a>

Text nodes are simply strongs enclosed in double quotes:

"foo"

is translated into a simple TextNode containing "foo".

Structure is added to list of nodes by joining them with the symbols "+", ">" and "<".

  • "+": Next node will be a sibling of the previous node.
  • ">": Next node will be a child of the previous node.
  • "<": Next node will be a sibling of the parent of the precious node.

linenoise strings ignore whitespace; it's fine to split them up across multiple lines.

It's possible to use variable interpolation in strings in templates. Variables look like this:

a>"Go to {linktarget}"

The variables are used as keys into the optional 'env' variable that can be passed to the linenoise function.

It's possible to use string interpolation in class names, attributes and IDs as well. See the examples.

Examples

span>"heloes!"


<span>heloes</span>


label+input


<label></label>
<input></input>


dl>dt+dd


<dl>
    <dt></dt>
    <dd></dd>
</dl>


dl>dt>"title"<dd>"definition"


<dl>
    <dt>title</dt>
    <dd>definition</dd>
</dl>


button.action_type_{actiontype}[data-action={actiontype}] > "{actionmessage}"


<button class=" action_type_foo" data-action="foo">
    bar
</button>


h1 >
  "Example!" <
div.form-container >
  form[method=POST, action=save.html] >
    label[for=username] >
      "User name: " <
    input#username[name=username, value={username}] +
    br +
    label[for=password] >
      "Password: " <
    input#password[name=password] +
    br +
    input[type=submit]


<h1>
  Example!
</h1>
<div class=" form-container">
  <form method="POST" action="save.html">
    <label for="username">
      User name:
    </label>
    <input id="username" name="username" value="{username}">
    <br>
    <label for="password">
      Password:
    </label>
    <input id="password" name="password">
    <br>
    <input type="submit">
  </form>
</div>

Todo

  • docs for interpolation
  • shorthand for single child textnode?
  • spaces in class list should be removed
  • posargs
  • boolean attributes
  • deeper attribute resolution
  • Which possibly leads to more full-blowny templating