Hi! We are the team of Substance, and we're passionate about making web-based content composition easy. We believe that Content is Data and should be separated from presentation. Authors want to create meaningful content in the first place, they don't want to spend time with aligning text, choosing fonts and resizing images.
Also we've made a claim:
Building an editor for everyone is impossible
And we've proposed a solution:
Provide an easy way for communities to build their own editor
The Substance Composer is a foundation for building your own editor tailored for you particular usecase. You can extend basic content types such as Text, Sections and Images with custom types such as Maps, Formulas, or pre-structured types such as an Event content type that allows you entering name, date, organizer etc. You can add whatever you can imagine, the sky is the limit. But here comes the bummer: You need to do it yourself. Our mission is to make it very easy for you, by creating an infrastructure for basic operations such as inserting, moving and deleting nodes, and a generic UI for dealing with patches and comments.
Since collaboration is more imporantant than ever before to create high quality content we've added the concept of patches to turn every readers into a potential collaborator.
The Substance Composer uses operations to transform documents. By keeping track of atomic document operations, the complete history can be replayed and allows users to go back and forth in time. You can either use the web-based editor for manipulating documents, or do it programmatically using the API.
You can implement your own content types. We'll provide a tutorial once the editor stable enough.
Documents are manipulated using commands. Commands are represented as JSON.
Announce a new author collaborating on the document.
{"command": "user:announce", "params": {"user": "michael", "color": "#82AA15"}}Commands for inserting, updating, moving and deleting content nodes.
Insert a new node.
{
"command": "node:insert",
"params": {
"user": "michael",
"type": "text",
"rev": 3,
"attributes": {"content": "Text goes here."}
}
}Move node(s). They are inserted after a specified target node.
{
"command": "node:insert",
"params": {
"user": "michael",
"nodes": ["/section/2", "/text/3"],
"target": "/text/5"
"rev": 12
}
}Make a new node selection.
{
"command": "node:select",
"params": {
"user": "michael",
"nodes": ["/section/2", "/text/3"],
"rev": 12
}
}To be implemented.
To be implemented.
To be implemented.
To be implemented.



