Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

textom

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

textom

Object model for natural languages

  • 0.4.1
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

TextOM Build Status Coverage Status

Object model for manipulating natural language in JavaScript.

  • For parsing capabilities, see parse-latin;
  • For a pluggable system for analysing and manipulating natural language, see retext;
  • For semantics of natural language nodes, see NLCST.

Installation

npm:

$ npm install textom

Component.js:

$ component install wooorm/textom

Bower:

$ bower install textom

Duo:

var TextOMConstructor = require('wooorm/textom');

UMD (globals/AMD/CommonJS) (uncompressed and minified:

<script src="path/to/textom.js"></script>
<script>
  var TextOM = new TextOMConstructor();
</script>

Usage

var TextOMConstructor = require('textom');

/**
 * Construct a new ``document''.
 */

var TextOM = new TextOMConstructor();

/**
 * Construct a new root node.
 */

var root = new TextOM.RootNode();

API

See below for IDL definitions.

Let’s say all following examples start with below code.

Any changes made by below examples are discarded upon their ending.

var TextOMConstructor = require('textom');

/* Construct a new ``document''. */
var TextOM = new TextOMConstructor();

/* Construct a root node. */
var root = new TextOM.RootNode();

/* Add a paragraph node. */
var paragraph = new TextOM.ParagraphNode();
root.append(paragraph);

/* Add a sentence node. */
var sentence = new TextOM.SentenceNode();
paragraph.append(sentence);

/* Add words, symbols, punctuation, and white space. */
var dogs = sentence.append(new TextOM.WordNode()),
    space0 = sentence.append(new TextOM.WhiteSpaceNode(' ')),
    ampersand = sentence.append(new TextOM.SymbolNode('&')),
    space1 = sentence.append(new TextOM.WhiteSpaceNode(' ')),
    cats = sentence.append(new TextOM.WordNode()),
    fullStop = sentence.append(new TextOM.PunctuationNode('.'));

/* Add words. */
var dogsText = dogs.append(new TextOM.TextNode('Dogs')),
    catsText = cats.append(new TextOM.TextNode('cats'));

/* Check root's content. */
root.toString(); // 'Dogs & cats.'

TextOM

Object.

TextOM.Node() [NLCST:Node]

Constructor.

TextOM.Node.on(name, listener)
TextOM.RootNode.on('someeventname', function () {});

Subscribe listener to name events on instances of Node.

TextOM.Node.off(name?, listener?)
TextOM.WordNode.off('someeventname');
  • off(name, listener): Unsubscribe listener from name events on instances of Node;
  • off(name): Unsubscribe from name events on instances of Node;
  • off(): Unsubscribe from events on instances of Node.
TextOM.Node#on(name, listener)
root.on('someeventname', function () {});

Subscribe listener to name events on node.

TextOM.Node#off(name?, listener?)
dogs.off('someeventname');
  • off(name, listener): Unsubscribe listener from name events on node;
  • off(name): Unsubscribe from name events on node;
  • off(): Unsubscribe from events on node.
TextOM.Node#emit(name, parameters...)
TextOM.WordNode.on('someeventname', function () {
    this; // dogs
});

dogs.emit('someeventname');
  • emit(name, parameters...): Fire a name event with parameters on node;
  • emit(name): Fire a name event on node.

Bubbles through nodes constructors. In the case of dogs: WordNode, Element, Child, Parent, Node.

TextOM.Node#trigger(name, context, parameters...)
root.on('someeventnameinside', function (context) {
    this; // root
    context; // dogsText
});

dogsText.trigger('someeventname', dogs);
  • trigger(name, context, parameters...): Fire a name event with parameters on node;
  • trigger(name, context): Fire a name event on node;
  • trigger(name): Same as TextOM\.Node#emit(name).

emits an event, and triggers name + "inside" events on context and its parents, and their constructor.

In the case of dogsText: someeventname is emitted on dogsText and TextNode, and someeventname is triggered on dogs and WordNode; sentence and SentenceNode; paragraph and ParagraphNode; root and RootNode.

TextOM.Node#nodeName

Identifier for Nodes.

TextOM.Node#TextOM
root.TextOM === TextOM; // true

TextOM object associated with node.

TextOM.Node#ROOT_NODE

Identifier for RootNodes.

TextOM.Node#PARAGRAPH_NODE

Identifier for ParagraphNodes.

TextOM.Node#SENTENCE_NODE

Identifier for SentenceNodes.

TextOM.Node#WORD_NODE

Identifier for WordNodes.

TextOM.Node#SYMBOL_NODE

Identifier for SymbolNodes.

TextOM.Node#PUNCTUATION_NODE

Identifier for PunctuationNodes.

TextOM.Node#WHITE_SPACE_NODE

Identifier for WhiteSpaceNodes.

TextOM.Node#SOURCE_NODE

Identifier for SourceNodes.

TextOM.Node#TEXT_NODE

Identifier for TextNodes.

TextOM.Node#NODE

Identifier for Nodes.

TextOM.Node#PARENT

Identifier for Parents.

TextOM.Node#ELEMENT

Identifier for Elements.

TextOM.Node#CHILD

Identifier for Childs.

TextOM.Node#TEXT

Identifier for Texts.

TextOM.Parent() [NLCST:Parent]

Constructor (Node).

TextOM.Parent#nodeName

Identifier for Parents.

TextOM.Parent#head
paragraph.head; // sentence
sentence.head; // dogs

First Child of parent or null.

TextOM.Parent#tail
paragraph.tail; // null (see description below);
sentence.tail; // fullStop

Last Child of parent (if more than one child exists) or null.

TextOM.Parent#length
root.length; // 1
sentence.length; // 6

Number of children in parent.

TextOM.Parent#prepend(child)
sentence.head; // dogs
sentence.prepend(fullStop);
sentence.head; // fullStop

Insert child as parents first child.

TextOM.Parent#prependAll(child[])
sentence.head; // dogs
sentence.prependAll([fullStop, cats]);
sentence.head; // fullStop
sentence.head.next; // cat

Insert every child in children at the start of parent.

Adheres to sorting (the first child in children will become parents head).

TextOM.Parent#append(child)
sentence.tail; // fullStop
sentence.append(dogs);
sentence.tail; // dogs

Insert child as parents last child.

TextOM.Parent#appendAll(child[])
sentence.tail; // fullStop
sentence.appendAll([dogs, cats]);
sentence.tail; // cats
sentence.tail.prev; // dogs

Insert every child in children at the end of parent.

Adheres to sorting (the last child in children will become parents tail).

TextOM.Parent#item(index?)
root.item(); // paragraph
sentence.item(0); // dogs
sentence.item(5); // fullStop
sentence.item(6); // null
  • item(index): Get Child at index in parent or null;
  • item(): Get parents first Child or null.
TextOM.Parent#toString()
root.toString(); // "Dogs & cats."
'' + sentence; // "Dogs & cats."

Get parents content.

TextOM.Parent#valueOf()
dogs.valueOf();
/**
 * {
 *   "type": "WordNode",
 *   "children": [
 *     {
 *       "type": "TextNode",
 *       "value": "Dogs"
 *     }
 *   ]
 * }
 */

Get parents NLCST representation.

TextOM.Child()

Constructor (Node).

TextOM.Child#nodeName

Identifier for Childs.

TextOM.child#parent
dogs.parent; // sentence
sentence.parent; // paragraph
paragraph.parent; // root

childs Parent or null.

TextOM.child#prev
dogs.prev; // null
space0.prev; // dogs

childs preceding sibling (Child) or null.

TextOM.child#next
cats.next; // fullStop
fullStop.next; // null

childs following sibling (Child) or null.

TextOM.Child#before(sibling)
dogs.prev; // null
dogs.before(cats);
dogs.prev; // cats

Insert sibling (Child) as childs preceding sibling in parent.

TextOM.Child#beforeAll(child[])
dogs.prev; // null
dogs.beforeAll([cats, space0]);
dogs.prev; // space0
dogs.prev.prev; // cats

Insert every (Child) in siblings (Array) before child in parent.

Adheres to sorting (the last sibling in siblings will become childs prev).

TextOM.Child#after(child)
cats.next; // null
cats.after(dogs);
cats.next; // dogs

Insert sibling (Child) as childs following sibling in parent.

TextOM.Child#afterAll(child[])
cats.next; // null
cats.afterAll([space0, dogs]);
cats.next; // space0
cats.next.next; // dogs

Insert every (Child) in siblings (Array) after child in parent.

Adheres to sorting (the first sibling in siblings will become childs next).

TextOM.Child#remove()
root.toString(); // "Dogs & cats."
fullStop.remove();
root.toString(); // "Dogs & cats"

Remove child from parent.

TextOM.Child#replace(sibling)
root.toString(); // "Dogs & cats."
cats.replace(dogs);
root.toString(); // " & Dogs"

Replace child with sibling (Child) in parent.

TextOM.Element()

Constructor (Parent and Child).

TextOM.Element#nodeName

Identifier for Elements.

TextOM.Element#split(position?)
sentence.prev; // null
sentence.toString(); // "Dogs & cats."
sentence.split(2);
sentence.toString(); // "& cats"
sentence.prev.toString(); // "Dogs "

Split element in two.

  • split(position): A new node, prependee (a new instance of elements constructor), is inserted before element in parent. prependee receives the children from 0 to position (not including). element receives the children from position (including);
  • split(): A new node, prependee (a new instance of elements constructor), is inserted before element in parent.
TextOM.Text(value?) [NLCST:Text]

Constructor (Child).

TextOM.Text#nodeName

Identifier for Texts.

TextOM.Text#toString()
dogsText.toString(); // "Dogs"
space1.toString(); // " "
fullStop.toString(); // "."

Get texts value.

TextOM.Text#valueOf()
dogsText.valueOf();
/**
 * {
 *   "type": "TextNode",
 *   "value": "Dogs"
 * }
 */

Get texts NLCST representation.

TextOM.Text#fromString(value?)
root.toString(); // "Dogs & cats."
catsText.fromString();
root.toString(); // "Dogs & ."
catsText.fromString("Lions");
root.toString(); // "Dogs & Lions."
  • fromString(value): Set texts value to value;
  • fromString(): Remove texts value.
TextOM.Text#split(position?)
catsText.prev; // null
catsText.toString(); // "cats"
catsText.split(2);
catsText.toString(); // "ts"
catsText.prev.toString(); // "ca"

Split text in two.

  • split(position): A new node, prependee (a new instance of texts constructor), is inserted before text in parent. prependee receives the value from 0 to position (not including). text receives the value from position (including);
  • split(): A new node, prependee (a new instance of texts constructor), is inserted before text in parent.
TextOM.RootNode() [NLCST:RootNode]

Constructor (Parent).

TextOM.RootNode#type

Identifier for RootNodes.

TextOM.ParagraphNode() [NLCST:ParagraphNode]

Constructor (Element).

TextOM.ParagraphNode#type

Identifier for ParagraphNodes.

TextOM.SentenceNode() [NLCST:SentenceNode]

Constructor (Element).

TextOM.SentenceNode#type

Identifier for SentenceNodes.

TextOM.WordNode() [NLCST:WordNode]

Constructor (Element).

TextOM.WordNode#type

Identifier for WordNodes.

TextOM.SymbolNode() [NLCST:SymbolNode]

Constructor (Text).

TextOM.SymbolNode#type

Identifier for SymbolNodes.

TextOM.PunctuationNode() [NLCST:PunctuationNode]

Constructor (SymbolNode).

TextOM.PunctuationNode#type

Identifier for PunctuationNodes.

TextOM.WhiteSpaceNode() [NLCST:WhiteSpaceNode]

Constructor (SymbolNode).

TextOM.WhiteSpaceNode#type

Identifier for WhiteSpaceNodes.

TextOM.SourceNode() [NLCST:SourceNode]

Constructor (Text).

TextOM.SourceNode#type

Identifier for SourceNodes.

TextOM.TextNode() [NLCST:TextNode]

Constructor (Text).

TextOM.TextNode#type

Identifier for TextNodes.

IDL

The below IDL-like document gives a short view of the defined interfaces by TextOM.

module textom
{
  [Constructor]
  interface Node {
    const string nodeName = "Node"

    const string NODE = "Node"
    const string PARENT = "Parent"
    const string ELEMENT = "Element"
    const string CHILD = "Child"
    const string TEXT = "Text"

    const string ROOT_NODE = "RootNode"
    const string PARAGRAPH_NODE = "ParagraphNode"
    const string SENTENCE_NODE = "SentenceNode"
    const string WORD_NODE = "WordNode"
    const string SYMBOL_NODE = "SymbolNode"
    const string PUNCTUATION_NODE = "PunctuationNode"
    const string WHITE_SPACE_NODE = "WhiteSpaceNode"
    const string SOURCE_NODE = "SourceNode"
    const string TEXT_NODE = "TextNode"

    void on(String type, Function callback);
    void off(optional String type = null, optional Function callback = null);
  };

  [Constructor,
   ArrayClass]
  interface Parent {
    readonly attribute string nodeName = "Parent";

    getter Child? item(unsigned long index);
    readonly attribute unsigned long length;

    readonly attribute Child? head;
    readonly attribute Child? tail;

    Child prepend(Child child);
    Child append(Child child);

    Child[] prependAll(Child[] children);
    Child[] appendAll(Child[] children);

    [NewObject] Object valueOf();

    string toString();
  };
  Parent implements Node;

  [Constructor]
  interface Child {
    readonly attribute nodeName = "Child"

    readonly attribute Parent? parent;
    readonly attribute Child? prev;
    readonly attribute Child? next;

    Child before(Child child);
    Child after(Child child);
    Child replace(Child child);
    Child remove(Child child);

    Child[] beforeAll(Child[] children);
    Child[] afterAll(Child[] children);
  };
  Child implements Node;

  [Constructor]
  interface Element {
    readonly attribute nodeName = "Element"

    [NewObject] Element split(unsigned long position);
  };
  Element implements Child;
  Element implements Parent;

  [Constructor(optional String value = "")]
  interface Text {
    readonly attribute nodeName = "Text"

    [NewObject] Object valueOf();

    string toString();

    string fromString(String value);
    [NewObject] Text split(unsigned long position);
  };
  Text implements Child;

  [Constructor]
  interface RootNode {
    readonly attribute string type = "RootNode";
  };
  RootNode implements Parent;

  [Constructor]
  interface ParagraphNode {
    readonly attribute string type = "ParagraphNode";
  };
  ParagraphNode implements Element;

  [Constructor]
  interface SentenceNode {
    readonly attribute string type = "SentenceNode";
  };
  SentenceNode implements Element;

  [Constructor]
  interface WordNode {
    readonly attribute string type = "WordNode";
  };
  WordNode implements Element;

  [Constructor(optional String value = "")]
  interface SymbolNode {
    readonly attribute string type = "SymbolNode";
  };
  SymbolNode implements Text;

  [Constructor(optional String value = "")]
  interface PunctuationNode {
    readonly attribute string type = "PunctuationNode";
  };
  PunctuationNode implements SymbolNode;

  [Constructor(optional String value = "")]
  interface WhiteSpaceNode {
    readonly attribute string type = "WhiteSpaceNode";
  };
  WhiteSpaceNode implements SymbolNode;

  [Constructor(optional String value = "")]
  interface TextNode {
    readonly attribute string type = "TextNode";
  };

  [Constructor(optional String value = "")]
  interface SourceNode {
    readonly attribute string type = "SourceNode";
  };
  SourceNode implements Text;
}

Events

TextOM provides events which can be subscribed to, to get notified when something changes.

Event can be subscribed to through on() methods, and unsubscribed to through off() methods. These methods exist on every instance and on every constructor.

When subscribing to an instance's events, listener is invoked for changes to that specific instance. When subscribing to a constructor's events, listener is invoked for changes to any of constructor's instances.

List of events

remove [non-bubbling]
dogs.on('remove', function (previous) {
  this === dogs; // true
  previous === sentence; // true
});

dogs.remove();

Fires when a Child is removed from previousParent.

  • this: Removed Child;
  • parameters:
    • previous: Removed from Parent.
insert [non-bubbling]
dogs.on('insert', function () {
  this === dogs; // true
});

sentence.append(dogs);

Fires when a Child is inserted into a Parent.

changetext [non-bubbling]
dogsText.on('changetext', function (current, previous) {
  this === dogsText; // true
  current === 'Poodles'; // true
  previous === 'Dogs'; // true
});

dogsText.fromString('Poodles');

Fires when a Text changes value.

  • this: Changed Text;
  • parameters:
    • current: Current value;
    • previous: Previous value;
change [non-bubbling]
dogs.on('change', function () {
  this === dogs; // true
});

dogsText.fromString('Poodles');
// or: dogsText.remove();
// or: dogs.insert(catsText);

Fires when a direct child of a parent changes: either its value, when a new child is inserted, or when a child is removed.

changetextinside [bubbling]
root.on('changetextinside', function (node, current, previous) {
  this === root; // true
  node === catsText; // true
  current === 'lions'; // true
  previous === 'cats'; // true
});

catsText.fromString('lions');

Fires when a Text inside an ancestor.

  • this: Ancestor of a Text;
  • parameters:
    • node: Changed Text;
    • current: Current value;
    • previous: Previous value;
insertinside [bubbling]
sentence.on('insertinside', function (node) {
  this === sentence; // true
  node === ampersand; // true
});

sentence.append(ampersand);

Fires when a Child is inserted inside an ancestor.

  • this: Ancestor of a Child;
  • parameters:
removeinside [bubbling]
root.on('removeinside', function (node, previous) {
  this === root; // true
  node === dogs; // true
  previous === sentence; // true;
});

dogs.remove();

Fires when a Child is removed inside an ancestor.

  • this: Ancestor of a Child;
  • parameters:
changeinside [bubbling]
root.on('changeinside', function (parent) {
  this === root; // true
  parent === sentence; // true
});

dogs.remove();
// or sentence.insert(dogs)
// or dogsText.fromString('cats');

Fires when a Child is removed inside an ancestor.

  • this: Ancestor of a Child;
  • parameters:
    • parent: Parent of the change.

Bubbling & Non-bubbling events

TextOM provides two types of events: Bubbling and non-bubbling. In API terms, bubbling event names end with "inside".

Non-bubbling (“normal”) events

Normal events fire on instances of Child and do not fire on ancestors. They additionally fire on all constructors of the instance.

Let’s say we have the example code given in API, and add the following line to it:

dogsText.fromString('Poodles');

A "changetext" event fires on dogsText. Because dogsText is a TextNode, the event fires on TextNode too. Because TextNode inherits from Text, the event also fires on Text, continuing with Child, and finally Node.

Bubbling events

Bubbling events start on a Parent and continue through its ancestors. These events also fire on the ancestors constructor.

Let’s say we have the example code given in API, and add the following line to it:

dogsText.fromString('Wolves');

A "changetextinside" event fires on dogsText parent, dogs, and because dogs is a WordNode, the event fires on WordNode too, continuing with sentence and SentenceNode, paragraph and ParagraphNode, and finally root and RootNode.

Performance

Not that intersting. Fast enough. Just for checking performance regression for new features.

              Parent
  80,260 op/s » Append 1 new node to an empty parent
  41,993 op/s » Append 2 new nodes to an empty parent
  28,576 op/s » Append 3 new nodes to an empty parent
  42,302 op/s » Append 1 attached node to an empty parent
  21,049 op/s » Append 2 attached nodes to an empty parent
  14,704 op/s » Append 3 attached nodes to an empty parent
     416 op/s » Append 100 attached nodes to an empty parent
  81,406 op/s » Prepend 1 new node to an empty parent
  41,051 op/s » Prepend 2 new nodes to an empty parent
  28,024 op/s » Prepend 3 new nodes to an empty parent
  41,487 op/s » Prepend 1 attached node to an empty parent
  21,122 op/s » Prepend 2 attached nodes to an empty parent
  14,269 op/s » Prepend 3 attached nodes to an empty parent
     405 op/s » Prepend 100 attached nodes to an empty parent

              Child
  39,223 op/s » Insert 1 new node after an only child
  26,724 op/s » Insert 2 new nodes after an only child
  19,999 op/s » Insert 3 new nodes after an only child
  26,779 op/s » Insert 1 attached node after an only child
  16,336 op/s » Insert 2 attached nodes after an only child
  11,969 op/s » Insert 3 attached nodes after an only child
     386 op/s » Insert 100 attached nodes after a first child
  39,727 op/s » Insert 1 new node before a first child
  26,254 op/s » Insert 2 new nodes before a first child
  20,122 op/s » Insert 3 new nodes before a first child
  27,033 op/s » Insert 1 attached node before a first child
  16,842 op/s » Insert 2 attached nodes before a first child
  12,220 op/s » Insert 3 attached nodes before a first child
     398 op/s » Insert 100 attached nodes before a first child

              Parent: all
  78,500 op/s » Append 1 new node to an empty parent
  55,596 op/s » Append 2 new nodes to an empty parent
  42,358 op/s » Append 3 new nodes to an empty parent
  40,838 op/s » Append 1 attached node to an empty parent
  24,457 op/s » Append 2 attached nodes to an empty parent
  16,675 op/s » Append 3 attached nodes to an empty parent
     552 op/s » Append 100 attached nodes to an empty parent
  78,364 op/s » Prepend 1 new node to an empty parent
  56,193 op/s » Prepend 2 new nodes to an empty parent
  42,430 op/s » Prepend 3 new nodes to an empty parent
  38,994 op/s » Prepend 1 attached node to an empty parent
  23,559 op/s » Prepend 2 attached nodes to an empty parent
  16,943 op/s » Prepend 3 attached nodes to an empty parent
     568 op/s » Prepend 100 attached nodes to an empty parent

              Child: all
  40,011 op/s » Insert 1 new node after an only child
  32,734 op/s » Insert 2 new nodes after an only child
  27,943 op/s » Insert 3 new nodes after an only child
  26,499 op/s » Insert 1 attached node after an only child
  18,801 op/s » Insert 2 attached nodes after an only child
  14,400 op/s » Insert 3 attached nodes after an only child
     560 op/s » Insert 100 attached nodes after a first child
  39,973 op/s » Insert 1 new node before a first child
  32,195 op/s » Insert 2 new nodes before a first child
  27,934 op/s » Insert 3 new nodes before a first child
  26,765 op/s » Insert 1 attached node before a first child
  19,257 op/s » Insert 2 attached nodes before a first child
  14,836 op/s » Insert 3 attached nodes before a first child
     594 op/s » Insert 100 attached nodes before a first child

License

MIT © Titus Wormer

Keywords

FAQs

Package last updated on 24 Jan 2015

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc