|
|
|
// Token class
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* class Token
|
|
|
|
**/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* new Token(type, tag, nesting)
|
|
|
|
*
|
|
|
|
* Create new token and fill passed properties.
|
|
|
|
**/
|
|
|
|
function Token(type, tag, nesting) {
|
|
|
|
/**
|
|
|
|
* Token#type -> String
|
|
|
|
*
|
|
|
|
* Type of the token (string, e.g. "paragraph_open")
|
|
|
|
**/
|
|
|
|
this.type = type;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#tag -> String
|
|
|
|
*
|
|
|
|
* html tag name, e.g. "p"
|
|
|
|
**/
|
|
|
|
this.tag = tag;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#attrs -> Array
|
|
|
|
*
|
|
|
|
* Html attributes. Format: `[ [ name1, value1 ], [ name2, value2 ] ]`
|
|
|
|
**/
|
|
|
|
this.attrs = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#map -> Array
|
|
|
|
*
|
|
|
|
* Source map info. Format: `[ line_begin, line_end ]`
|
|
|
|
**/
|
|
|
|
this.map = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#nesting -> Number
|
|
|
|
*
|
|
|
|
* Level change (number in {-1, 0, 1} set), where:
|
|
|
|
*
|
|
|
|
* - `1` means the tag is opening
|
|
|
|
* - `0` means the tag is self-closing
|
|
|
|
* - `-1` means the tag is closing
|
|
|
|
**/
|
|
|
|
this.nesting = nesting;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#level -> Number
|
|
|
|
*
|
|
|
|
* nesting level, the same as `state.level`
|
|
|
|
**/
|
|
|
|
this.level = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#children -> Array
|
|
|
|
*
|
|
|
|
* An array of child nodes (inline and img tokens)
|
|
|
|
**/
|
|
|
|
this.children = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#content -> String
|
|
|
|
*
|
|
|
|
* In a case of self-closing tag (code, html, fence, etc.),
|
|
|
|
* it has contents of this tag.
|
|
|
|
**/
|
|
|
|
this.content = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#markup -> String
|
|
|
|
*
|
|
|
|
* '*' or '_' for emphasis, fence string for fence, etc.
|
|
|
|
**/
|
|
|
|
this.markup = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#info -> String
|
|
|
|
*
|
|
|
|
* Additional information:
|
|
|
|
*
|
|
|
|
* - Info string for "fence" tokens
|
|
|
|
* - The value "auto" for autolink "link_open" and "link_close" tokens
|
|
|
|
**/
|
|
|
|
this.info = '';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#meta -> Object
|
|
|
|
*
|
|
|
|
* A place for plugins to store an arbitrary data
|
|
|
|
**/
|
|
|
|
this.meta = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#block -> Boolean
|
|
|
|
*
|
|
|
|
* True for block-level tokens, false for inline tokens.
|
|
|
|
* Used in renderer to calculate line breaks
|
|
|
|
**/
|
|
|
|
this.block = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token#hidden -> Boolean
|
|
|
|
*
|
|
|
|
* If it's true, ignore this element when rendering. Used for tight lists
|
|
|
|
* to hide paragraphs.
|
|
|
|
**/
|
|
|
|
this.hidden = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token.attrIndex(name) -> Number
|
|
|
|
*
|
|
|
|
* Search attribute index by name.
|
|
|
|
**/
|
|
|
|
Token.prototype.attrIndex = function attrIndex(name) {
|
|
|
|
var attrs, i, len;
|
|
|
|
|
|
|
|
if (!this.attrs) { return -1; }
|
|
|
|
|
|
|
|
attrs = this.attrs;
|
|
|
|
|
|
|
|
for (i = 0, len = attrs.length; i < len; i++) {
|
|
|
|
if (attrs[i][0] === name) { return i; }
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token.attrPush(attrData)
|
|
|
|
*
|
|
|
|
* Add `[ name, value ]` attribute to list. Init attrs if necessary
|
|
|
|
**/
|
|
|
|
Token.prototype.attrPush = function attrPush(attrData) {
|
|
|
|
if (this.attrs) {
|
|
|
|
this.attrs.push(attrData);
|
|
|
|
} else {
|
|
|
|
this.attrs = [ attrData ];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token.attrSet(name, value)
|
|
|
|
*
|
|
|
|
* Set `name` attribute to `value`. Override old value if exists.
|
|
|
|
**/
|
|
|
|
Token.prototype.attrSet = function attrSet(name, value) {
|
|
|
|
var idx = this.attrIndex(name),
|
|
|
|
attrData = [ name, value ];
|
|
|
|
|
|
|
|
if (idx < 0) {
|
|
|
|
this.attrPush(attrData);
|
|
|
|
} else {
|
|
|
|
this.attrs[idx] = attrData;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token.attrGet(name)
|
|
|
|
*
|
|
|
|
* Get the value of attribute `name`, or null if it does not exist.
|
|
|
|
**/
|
|
|
|
Token.prototype.attrGet = function attrGet(name) {
|
|
|
|
var idx = this.attrIndex(name), value = null;
|
|
|
|
if (idx >= 0) {
|
|
|
|
value = this.attrs[idx][1];
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Token.attrJoin(name, value)
|
|
|
|
*
|
|
|
|
* Join value to existing attribute via space. Or create new attribute if not
|
|
|
|
* exists. Useful to operate with token classes.
|
|
|
|
**/
|
|
|
|
Token.prototype.attrJoin = function attrJoin(name, value) {
|
|
|
|
var idx = this.attrIndex(name);
|
|
|
|
|
|
|
|
if (idx < 0) {
|
|
|
|
this.attrPush([ name, value ]);
|
|
|
|
} else {
|
|
|
|
this.attrs[idx][1] = this.attrs[idx][1] + ' ' + value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = Token;
|