• Stars
    star
    930
  • Rank 49,124 (Top 1.0 %)
  • Language
    JavaScript
  • Created about 14 years ago
  • Updated about 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Towards open digital publishing

Substance

Substance is a JavaScript library for manipulating documents based on data. It enables you to build completely custom web-based editors. See Substance in action:

Motivation

Building a web editor is a hard task. Native browser support for text editing is limited and not reliable and there are many pitfalls such as handling selections, copy&paste or undo/redo. Substance was developed to solve the common problems of web-editing and provides API's for building custom editors.

With Substance you can:

  • Define a custom article schema
  • Manipulate content and annotations using operations and transactions
  • Define a custom HTML structure and attach a Substance Surface on it to make it editable
  • Implement custom tools for any possible task like toggling annotations, inserting content or replacing text
  • Control undo/redo behavior and copy&paste
  • and more.

Getting started

A good way to get started with Substance is checking out our fully customizable and highly reliable HTML Editor component. Unlike most web-based editors, Substance operates on a Javascript data model, and uses HTML just as an input and output format. You can inject the editor using React.render.

var HtmlEditor = require('substance-html-editor');

React.render(
  $$(HtmlEditor, {
    ref: 'htmlEditor',
    content: '<p>Hello <strong>world</strong></p><p>Some <em>emphasized</em> text</p>',
    toolbar: Toolbar,
    enabledTools: ["text", "strong", "emphasis"],
    onContentChanged: function(doc, change) {
      console.log('new content', doc.toHtml());
    }
  }),
  document.getElementById('editor_container')
);

Please see the README of HtmlEditor for configuration options.

Defining custom article formats.

Substance allows you to define completely custom article formats.

var Paragraph = Substance.Document.Paragraph;
var Emphasis = Substance.Document.Emphasis;
var Strong = Substance.Document.Strong;

var Highlight = Document.ContainerAnnotation.extend({
  name: 'highlight',
  properties: {
    created_at: 'date'
  }
});

var schema = new Document.Schema("my-article", "1.0.0");
schema.getDefaultTextType = function() {
  return "paragraph";
};
schema.addNodes([Paragraph, Emphasis, Strong, Highlight]);

A very simple one is the HtmlArticle specification used by our HtmlEditor. Lens Writer defines a scientific article including bib items and figures with captions etc.

Manipulate documents programmatically

Substance documents can be manipulated incrementally using simple operations. Let's grab an existing article implementation and create instances for it.

var doc = new RichTextArticle();

When you want to update a document, you should wrap your changes in a transaction, so you don't end up in inconsistent in-between states. The API is fairly easy. Let's create several paragraph nodes in one transaction

doc.transaction(function(tx) {
  tx.create({
    id: "p1",
    type: "paragraph",
    content: "Hi I am a Substance paragraph."
  });

  tx.create({
    id: "p2",
    type: "paragraph",
    content: "And I am the second pargraph"
  });
});

A Substance document works like an object store, you can create as many nodes as you wish and assign unique id's to them. However in order to show up as content, we need to show them on a container.

doc.transaction(function(tx) {
  // Get the body container
  var body = tx.get('body');

  body.show('p1');
  body.show('p2');
});

Now let's make a strong annotation. In Substance annotations are stored separately from the text. Annotations are just regular nodes in the document. They refer to a certain range (startOffset, endOffset) in a text property (path).

doc.transaction(function(tx) {
  tx.create({
    "id": "s1",
    "type": "strong",
    "path": [
      "p1",
      "content"
    ],
    "startOffset": 10,
    "endOffset": 19
  });
});

Developing editors

In order to build your own editor based on Substance we recommend that you poke into the code of existing editors. HtmlEditor implements an editor for HTML content in under 200 lines of code.

Editor initialization

Editors to setup a bit of Substance infrastructure first, most importantly a Substance Surface, that maps DOM selections to internal document selections. Here's the most important parts from the initialization phase.

this.surfaceManager = new Substance.Surface.SurfaceManager(doc);
this.clipboard = new Substance.Surface.Clipboard(this.surfaceManager, doc.getClipboardImporter(), doc.getClipboardExporter());
var editor = new Substance.Surface.ContainerEditor('body');
this.surface = new Surface(this.surfaceManager, doc, editor);

A Surface instance requires a SurfaceManager, which keeps track of multiple Surfaces and dispatches to the currently active one. It also requires an editor. There are two kinds of editors: A ContainerEditor manages a sequence of nodes, including breaking and merging of text nodes. A FormEditor by contrast allows you to define a fixed structure of your editable content. Furthermore we initialized a clipboard instance and tie it to the Surface Manager.

We also setup a registry for components (such as Paragraph) and tools (e.g. EmphasisTool, StrongTrool). Our editor will then be able to dynamically retrieve the right view component for a certain node type.

2-column editing

We provide a framework, that allows building

Development

Testing

  1. Running the test-suite headless (using Phantom.js)
$ npm test
  1. Running the test-suite in a browser for debugging:
$ npm start

Then open http://localhost:4201/test in your browser.

  1. Running test-suite using Karma to generate a code coverage report.
$ npm run karma

The report will be stored in the coverage folder.

More Repositories

1

substance

A JavaScript library for web-based content editing.
JavaScript
2,741
star
2

texture

A visual editor for research.
JavaScript
1,000
star
3

data

A uniform interface for domain data (deprecated)
JavaScript
655
star
4

surface

A building block for web-based text editors
JavaScript
166
star
5

examples

Learn Substance by example.
JavaScript
155
star
6

lens

Lens - open science content creation and display
JavaScript
124
star
7

dar

Reproducible Document Archive
82
star
8

document

Substance Document Model
JavaScript
52
star
9

simple-writer

All you need to get started with Substance editor development.
JavaScript
28
star
10

io

IO is a minimal publishing system based on Pandoc, Substance and eLife Lens. It powers substance.io
CSS
28
star
11

chronicle

A git inspired versioning API.
JavaScript
27
star
12

operator

Operational Transformation for strings, arrays and objects.
JavaScript
26
star
13

letterpress

Cross Media Publishing for Substance documents
Haskell
23
star
14

notes

Real-time collaborative notes editing.
JavaScript
21
star
15

dot

Decentralized Operational Transformation (DOT)
JavaScript
16
star
16

forms

Web forms with Substance.
JavaScript
14
star
17

collab-writer

Realtime collaboration example.
JavaScript
14
star
18

store

Substance Document Storage Layer
JavaScript
13
star
19

regexp

Use Regular Expressions in Javascript with a comprehensible interface.
JavaScript
9
star
20

journal-old

Run a journal based on Substance (WIP)
JavaScript
7
star
21

commander

A substantial keyboard event mapper based on Mousetrap and inspired by Sublime.
JavaScript
7
star
22

application

Build Substance apps using Views, Controllers and Modules (CommonJS)
JavaScript
7
star
23

example-editor

Substance Example Editor
JavaScript
7
star
24

util

General Purpose Utils
JavaScript
6
star
25

converter

Pandoc in β€” Substance out and the other way round.
JavaScript
6
star
26

ui

Substance user interface components (deprecated)
JavaScript
6
star
27

screwdriver

Command line utility to manage Substance applications.
Python
6
star
28

nodes

Common node types for Substance.Article implementations.
JavaScript
6
star
29

chef-tutorial

Our internal Chef tutorial.
Ruby
5
star
30

test

Substance testing facility.
JavaScript
5
star
31

compiler

Takes a Substance document as an input and turns it into a web publication ready to be self-hosted
JavaScript
5
star
32

client

Substance Client API
JavaScript
5
star
33

bundler

Simple high-level build tool.
JavaScript
5
star
34

substance-website-legacy

Substance Website
JavaScript
4
star
35

pages

Static site generator.
JavaScript
4
star
36

tutorial

The official Substance Tutorial for developers.
JavaScript
4
star
37

archivist-writer

Archivist Writer based on the latest Substance
JavaScript
4
star
38

dar-server

Filesystem backend for document archives
JavaScript
4
star
39

texture-jats

JavaScript
3
star
40

library

Where Substance Documents feel at home.
JavaScript
3
star
41

archivist-composer

A composer for interviews, used by the archivist project
JavaScript
2
star
42

website

The new Substance website
JavaScript
2
star
43

docs

Substance API Docs
HTML
2
star
44

code

Substance Developer Resources
JavaScript
2
star
45

article

Substance Document Reference Implementation
JavaScript
2
star
46

replicator

Replication between two Data.Stores.
JavaScript
2
star
47

shell

Substance Native Shell
Ruby
2
star
48

webhook-tasks

A custom service which builds API docs et. al. triggered by github webhooks.
Shell
2
star
49

legacy-docs

Substance documentation repository. You're contributions are welcome!
2
star
50

sourcedata-smartfigure-editor

SourceData FigurePackages.
JavaScript
2
star
51

sublime

A custom sublime integration that helps us dealing with our many modules
Python
2
star
52

electron-environment

Environment for web development based on electron.
JavaScript
1
star
53

spellchecker

JavaScript
1
star
54

hub

Experimental server for realtime collab
JavaScript
1
star
55

writer-old

Substance Writer Component
JavaScript
1
star
56

substance.github.com

Substance website
JavaScript
1
star
57

server-utils

Substance server utilities
JavaScript
1
star
58

legacy-composer

JavaScript
1
star
59

archivist-interview

Archivist Article Format
JavaScript
1
star
60

console

Interactive Console to playfully manipulate a Substance document.
JavaScript
1
star
61

starter-legacy

A minimal Substance editor for learning Substance.
JavaScript
1
star
62

ember-cli-substance

Ember-CLI integration of Substance.
JavaScript
1
star
63

react-example

A minimal react project.
JavaScript
1
star
64

scientist-pandoc

A minimal document authoring solution for scientists, based on Pandoc Markdown
1
star
65

archivist-indexer

Archivist indexer based on ElasticSearch
JavaScript
1
star