spangle

1.3.0 • Public • Published

Spangle

Add some razzle-dazzle to strings using formatted ranges.

What do you mean "formatted ranges"?

Specifying text as a combination of a string and formatted ranges is a way to allow clients to display formatted text in whichever way they see fit. This amounts to progressive enhancement or graceful degradation, depending on your point of view.

Backwards-compatibility is built in. If a certain type of formatting is unsupported or has some issue, it can be ignored without affecting the rest of the formatting. In the worst case, you can always display a plain string of text!

Shape of the Data

Formatted text is represented by one or more blocks, each of which has plain text string plus any number of formatting ranges that specify additional inline formatting. It is designed so that the interpreter can skip any formatting data that is unrecognized or unsupported without breaking the overall output.

{
  blocks: [
    // Plaintext
    {
      type: 'text',
      text: 'Hello world!',
    },
    // Text with inline formattin
    {
      type: 'text',
      text: 'This is your text.',
      formatting: [
        { start: 8, end: 12, type: 'emphasis' },
      ],
    },
  ],
}

If you were to render this to HTML, you might have output that looks something like this:

<p>Hello world!</p>
<p>This is <em>your</em> text.</p>

Suppose you wanted to render to Markdown instead. An implementation of that might have output that looks more like this:

Hello world!

This is _your_ text.

Usage

This repository contains a JavaScript implementation for the web, but you could also write interpreters for other languages and/or platforms as well!

The primary implementation is build on unified and rehype-dom. It can both parse and format HTML using an abstract syntax tree and the browser's DOM implementation. This is likely the version you'll need to use if you're building a WYSIWYG editor or something similar.

Parsing HTML

import { parseHtml } from 'spangle';

const output = parseHtml('<p>This is <em>your</em> text.</p>');

console.log(output);
// {
//   blocks: [{
//     type: "text",
//     text: "This is your text.",
//     formatting: [{ start: 8, end: 12, type: "emphasis" }]
//   }],
// }

Formatting HTML

import { formatHtml } from 'spangle';

const output = formatHtml({
  blocks: [{
    type: 'text',
    text: 'This is your text.',
    formatting: [
      { start: 8, end: 12, type: 'emphasis' },
    ],
  }],
});

console.log(output);
// "<p>This is <em>your</em> text.</p>"

Lite Verison

If you're concerned about bundle size or only need to interpret existing spangle-formatted data, you might consider using the "Lite" implementation instead. It does not support parsing!

It's smaller because it excludes the code for parsing HTML and uses a smaller (and less accurate) AST-to-HTML string implementation. Otherwise, the API is the same, so swap the import and you'll be good to go!

import { formatHtml } from 'spangle/lib/lite';

Markdown

This repository also includes an implementation that can parse and format a non-standard version of Markdown. This is probably an easier way to create spangle-formatted data reliably than parsing HTML or writing JSON manually.

Parsing Markdown

import { parseMarkdown } from 'spangle';

const output = parseMarkdown('This is [your]{#f00} text.');

console.log(output);
// {
//   blocks: [{
//     type: "text",
//     text: "This is your text.",
//     formatting: [{ start: 8, end: 12, type: "color", color: "#f00" }]
//   }],
// }

Formatting Markdown

import { formatMarkdown } from 'spangle';

const output = formatMarkdown({
  blocks: [{
    type: 'text',
    text: 'This is your text.',
    formatting: [
      { start: 8, end: 12, type: 'underline' },
    ],
  }],
});

console.log(output);
// "This is __your__ text."

Formatting Types

Check out the constants to see the types of formatting supported.

Note: Formatting ranges include start and end normally, but we're omitting them for the sake of brevity in this documentation.

* Formatting that uses non-standard Markdown is labeled with an asterisk.

Strikethrough / Delete

{ type: 'delete' }
<del>text</del>
~~text~~

Italics / Emphasis

{ type: 'emphasis' }
<em>text</em>
_text_

Inline code

{ type: 'inlineCode' }
<code>text</code>
`text`

Underlined*

{ type: 'underline' }
<span style="text-decoration: underline;">text</code>
__text__

Note: Standard markdown uses double-underscores for strong text.

Colors*

{ type: 'color', color: '#f00' }
<span style="color: #f00;">text</code>
[text]{#f00}

Note: Standard markdown does not support inline colors.

Anchor link

{ type: 'link', url: 'https://example.com' }
<a href="https://example.com">text</a>
[text](https://example.com)

Bold / Strong

{ type: 'strong' }
<strong>text</strong>
**text**

Readme

Keywords

none

Package Sidebar

Install

npm i spangle

Weekly Downloads

168

Version

1.3.0

License

ISC

Unpacked Size

956 kB

Total Files

27

Last publish

Collaborators

  • kmck