Socket
Socket
Sign inDemoInstall

markdown-it

Package Overview
Dependencies
Maintainers
1
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

markdown-it - npm Package Compare versions

Comparing version 2.1.3 to 2.2.0

lib/presets/zero.js

1

bower.json

@@ -20,2 +20,3 @@ {

"docs",
"apidoc",
"lib",

@@ -22,0 +23,0 @@ "node_modules",

@@ -0,1 +1,11 @@

2.2.0 / 2014-12-28
------------------
- Updated CM spec conformance to v0.13.
- API docs.
- Added 'zero' preset.
- Fixed several crashes, when some basic rules are disabled
(block termination check, references check).
2.1.3 / 2014-12-24

@@ -2,0 +12,0 @@ ------------------

25

lib/helpers/parse_link_label.js

@@ -8,11 +8,8 @@ // Parse link label

module.exports = function parseLinkLabel(state, start) {
var level, found, marker,
module.exports = function parseLinkLabel(state, start, disableNested) {
var level, found, marker, prevPos,
labelEnd = -1,
max = state.posMax,
oldPos = state.pos,
oldFlag = state.isInLabel;
oldPos = state.pos;
if (state.isInLabel) { return -1; }
if (state.labelUnmatchedScopes) {

@@ -24,3 +21,2 @@ state.labelUnmatchedScopes--;

state.pos = start + 1;
state.isInLabel = true;
level = 1;

@@ -30,5 +26,3 @@

marker = state.src.charCodeAt(state.pos);
if (marker === 0x5B /* [ */) {
level++;
} else if (marker === 0x5D /* ] */) {
if (marker === 0x5D /* ] */) {
level--;

@@ -41,3 +35,13 @@ if (level === 0) {

prevPos = state.pos;
state.parser.skipToken(state);
if (marker === 0x5B /* [ */) {
if (prevPos === state.pos - 1) {
// increase level if we find text `[`, which is not a part of any token
level++;
} else if (disableNested) {
state.pos = oldPos;
return -1;
}
}
}

@@ -54,5 +58,4 @@

state.pos = oldPos;
state.isInLabel = oldFlag;
return labelEnd;
};

@@ -8,4 +8,2 @@ // Main perser class

var helpers = require('./helpers');
var assign = require('./common/utils').assign;
var isString = require('./common/utils').isString;
var Renderer = require('./renderer');

@@ -15,6 +13,6 @@ var ParserCore = require('./parser_core');

var ParserInline = require('./parser_inline');
var Ruler = require('./ruler');
var config = {
'default': require('./presets/default'),
zero: require('./presets/zero'),
full: require('./presets/full'),

@@ -38,4 +36,116 @@ commonmark: require('./presets/commonmark')

// Main class
//
/**
* class MarkdownIt
*
* Main parser/renderer class.
*
* ##### Usage
*
* ```javascript
* // node.js, "classic" way:
* var MarkdownIt = require('markdown-it'),
* md = new MarkdownIt();
* var result = md.render('# markdown-it rulezz!');
*
* // node.js, the same, but with sugar:
* var md = require('markdown-it')();
* var result = md.render('# markdown-it rulezz!');
*
* // browser without AMD, added to "window" on script load
* // Note, there are no dash.
* var md = window.markdownit();
* var result = md.render('# markdown-it rulezz!');
* ```
*
* Single line rendering, without paragraph wrap:
*
* ```javascript
* var md = require('markdown-it')();
* var result = md.renderInline('__markdown-it__ rulezz!');
* ```
**/
/**
* new MarkdownIt([presetName, options])
* - presetName (String): optional, `commonmark` / `full` / `zero`
* - options (Object)
*
* Creates parser instanse with given config. Can be called without `new`.
*
* ##### presetName
*
* MarkdownIt provides named presets as a convenience to quickly
* enable/disable active syntax rules and options for common use cases.
*
* - ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) -
* configures parser to strict [CommonMark](http://commonmark.org/) mode.
* - ["full"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/full.js) -
* enables all available rules, but still without html, typographer & autolinker.
* - [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -
* similar to GFM, used when no preset name given.
* - ["zero"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/zero.js) -
* all rules disabled. Useful to quickly setup your config via `.enable()`.
* For example, when you need only `bold` and `italic` markup and nothing else.
*
* ##### options:
*
* - __html__ - `false`. Set `true` to enable HTML tags in source. Be careful!
* That's not safe! You may need external sanitizer to protect output from XSS.
* It's better to extend features via plugins, instead of enabling HTML.
* - __xhtmlOut__ - `false`. Set `true` to add '/' when closing single tags
* (`<br />`). This is needed only for full CommonMark compatibility. In real
* world you will need HTML output.
* - __breaks__ - `false`. Set `true` to convert `\n` in paragraphs into `<br>`.
* - __langPrefix__ - `language-`. CSS language class prefix for fenced blocks.
* Can be useful for external highlighters.
* - __linkify__ - `false`. Set `true` to autoconvert URL-like text to links.
* - __typographer__ - `false`. Set `true` to enable [some language-neutral
* replacement](https://github.com/markdown-it/markdown-it/blob/master/lib/rules_core/replacements.js) +
* quotes beautification (smartquotes).
* - __quotes__ - `“”‘’`, string. Double + single quotes replacement pairs, when
* typographer enabled and smartquotes on. Set doubles to '«»' for Russian,
* '„“' for German.
* - __highlight__ - `null`. Highlighter function for fenced code blocks.
* Highlighter `function (str, lang)` should return escaped HTML. It can also
* return empty string if the source was not changed and should be escaped externaly.
*
* ##### Example
*
* ```javascript
* // commonmark mode
* var md = require('markdown-it')('commonmark');
*
* // default mode
* var md = require('markdown-it')();
*
* // enable everything
* var md = require('markdown-it')('full', {
* html: true,
* linkify: true,
* typographer: true
* });
* ```
*
* ##### Syntax highlighting
*
* ```js
* var hljs = require('highlight.js') // https://highlightjs.org/
*
* var md = require('markdown-it')({
* highlight: function (str, lang) {
* if (lang && hljs.getLanguage(lang)) {
* try {
* return hljs.highlight(lang, str).value;
* } catch (__) {}
* }
*
* try {
* return hljs.highlightAuto(str).value;
* } catch (__) {}
*
* return ''; // use external default escaping
* }
* });
* ```
**/
function MarkdownIt(presetName, options) {

@@ -47,3 +157,3 @@ if (!(this instanceof MarkdownIt)) {

if (!options) {
if (!isString(presetName)) {
if (!utils.isString(presetName)) {
options = presetName || {};

@@ -54,12 +164,71 @@ presetName = 'default';

this.inline = new ParserInline();
this.block = new ParserBlock();
this.core = new ParserCore();
/**
* MarkdownIt#inline -> ParserInline
*
* Instance of [[ParserInline]]. You may need it to add new rules when
* writing plugins. For simple rules control use [[MarkdownIt.disable]] and
* [[MarkdownIt.enable]].
**/
this.inline = new ParserInline();
/**
* MarkdownIt#block -> ParserBlock
*
* Instance of [[ParserBlock]]. You may need it to add new rules when
* writing plugins. For simple rules control use [[MarkdownIt.disable]] and
* [[MarkdownIt.enable]].
**/
this.block = new ParserBlock();
/**
* MarkdownIt#core -> Core
*
* Instance of [[Core]] chain executor. You may need it to add new rules when
* writing plugins. For simple rules control use [[MarkdownIt.disable]] and
* [[MarkdownIt.enable]].
**/
this.core = new ParserCore();
/**
* MarkdownIt#renderer -> Renderer
*
* Instance of [[Renderer]]. Use it to modify output look. Or to add rendering
* rules for new token types, generated by plugins.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')();
*
* function myToken(tokens, idx, options, env, self) {
* //...
* return result;
* };
*
* md.renderer.rules['my_token'] = myToken
* ```
*
* See [[Renderer]] docs and [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js).
**/
this.renderer = new Renderer();
this.ruler = new Ruler();
// Expose utils & helpers for easy acces from plugins
/**
* MarkdownIt#utils -> utils
*
* Assorted utility functions, useful to write plugins. See details
* [here](https://github.com/markdown-it/markdown-it/blob/master/lib/common/utils.js).
**/
this.utils = utils;
/**
* MarkdownIt#helpers -> helpers
*
* Link components parser functions, useful to write plugins. See details
* [here](https://github.com/markdown-it/markdown-it/blob/master/lib/helpers).
**/
this.helpers = helpers;
this.options = {};

@@ -72,6 +241,23 @@ this.configure(config[presetName]);

// Set options, if you did not passed those to constructor
//
/** chainable
* MarkdownIt.set(options)
*
* Set parser options (in the same format as in constructor). Probably, you
* will never need it, but you can change options after constructor call.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')()
* .set({ html: true, breaks: true })
* .set({ typographer, true });
* ```
*
* __Note:__ To achieve the best possible performance, don't modify a
* `markdown-it` instance options on the fly. If you need multiple configurations
* it's best to create multiple instances and initialize each with separate
* config.
**/
MarkdownIt.prototype.set = function (options) {
assign(this.options, options);
utils.assign(this.options, options);
return this;

@@ -81,4 +267,9 @@ };

// Batch loader for components rules states & options
//
/** chainable, internal
* MarkdownIt.configure(presets)
*
* Batch load of all options and compenent settings. This is internal method,
* and you probably will not need it. But if you with - see available presets
* and data structure [here](https://github.com/markdown-it/markdown-it/tree/master/lib/presets)
**/
MarkdownIt.prototype.configure = function (presets) {

@@ -102,4 +293,17 @@ var self = this;

// Sugar to enable rules by names in all chains at once
//
/** chainable
* MarkdownIt.enable(list)
* - list (String|Array): rule name or list of rule names to enable
*
* Enable list or rules. It will automatically find appropriate components,
* containing rules with given names.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')()
* .enable(['sub', 'sup'])
* .disable('smartquotes');
* ```
**/
MarkdownIt.prototype.enable = function (list) {

@@ -113,4 +317,8 @@ [ 'core', 'block', 'inline' ].forEach(function (chain) {

// Sugar to disable rules by names in all chains at once
//
/** chainable
* MarkdownIt.disable(list)
* - list (String|Array): rule name or list of rule names to disable.
*
* The same as [[MarkdownIt.enable]], but turn specified rules off.
**/
MarkdownIt.prototype.disable = function (list) {

@@ -124,12 +332,16 @@ [ 'core', 'block', 'inline' ].forEach(function (chain) {

// Sugar for curried plugins init:
//
// var md = new MarkdownIt();
//
// md.use(plugin1)
// .use(plugin2, opts)
// .use(plugin3);
//
MarkdownIt.prototype.use = function (plugin, opts) {
plugin(this, opts);
/** chainable
* MarkdownIt.use(plugin, options)
*
* Load specified plugin with given options into current parser instance.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')()
* .use(require('makkdown-it-emoji'));
* ```
**/
MarkdownIt.prototype.use = function (plugin, options) {
plugin(this, options);
return this;

@@ -139,5 +351,15 @@ };

// Parse input string, returns tokens array. Modify `env` with
// definitions data.
//
/** internal
* MarkdownIt.parse(src, env) -> Array
* - src (String): source string
* - env (Object): enviroment variables
*
* Parse input string and returns list of block tokens (special token type
* "inline" will contain list of inline tokens). You should not call this
* method directly, until you write custom renderer (for example, to produce
* AST).
*
* `env` is modified with additional info. For example, with references data.
* Also `env` can be used to pass external info to plugins.
**/
MarkdownIt.prototype.parse = function (src, env) {

@@ -152,4 +374,12 @@ var state = new StateCore(this, src, env);

// Main method that does all magic :)
//
/**
* MarkdownIt.render(src [, env]) -> String
* - src (String): source string
* - env (Object): optional, enviroment variables
*
* Render markdown string into html. It does all magic for you :).
*
* `env` is `{}` by default. It's not used now directly, but you can pass
* with it any additional data to plugins.
**/
MarkdownIt.prototype.render = function (src, env) {

@@ -162,4 +392,11 @@ env = env || {};

// Parse content as single string
//
/** internal
* MarkdownIt.parseInline(src, env) -> Array
* - src (String): source string
* - env (Object): enviroment variables
*
* The same as [[MarkdownIt.parse]] but skip all block rules. It returns the
* block tokens list with th single `inline` element, containing parsed inline
* tokens in `children` property.
**/
MarkdownIt.prototype.parseInline = function (src, env) {

@@ -175,4 +412,10 @@ var state = new StateCore(this, src, env);

// Render single string, without wrapping it to paragraphs
//
/**
* MarkdownIt.renderInline(src [, env]) -> String
* - src (String): source string
* - env (Object): optional, enviroment variables
*
* Similar to [[MarkdownIt.render]] but for single paragraph content. Result
* will NOT be wrapped into `<p>` tags.
**/
MarkdownIt.prototype.renderInline = function (src, env) {

@@ -179,0 +422,0 @@ env = env || {};

@@ -1,4 +0,6 @@

// Block parser
/** internal
* class ParserBlock
*
* Block-level tokenizer.
**/
'use strict';

@@ -27,5 +29,11 @@

// Block Parser class
//
/**
* new ParserBlock()
**/
function ParserBlock() {
/**
* ParserBlock#ruler -> Ruler
*
* [[Ruler]] instance. Keep configuration of block rules.
**/
this.ruler = new Ruler();

@@ -93,3 +101,9 @@

var SPACES_RE = /\u00a0/g;
var NULL_RE = /\u0000/g;
/**
* ParserBlock.parse(str, options, env, outTokens)
*
* Process input string and push block tokens into `outTokens`
**/
ParserBlock.prototype.parse = function (src, options, env, outTokens) {

@@ -106,2 +120,5 @@ var state, lineStart = 0, lastTabPos = 0;

// Strin NULL characters
src = src.replace(NULL_RE, '');
// Replace tabs with proper number of spaces (1..4)

@@ -108,0 +125,0 @@ if (src.indexOf('\t') >= 0) {

@@ -1,3 +0,7 @@

// Class of top level (`core`) rules
//
/** internal
* class Core
*
* Top-level rules executor. Glues block/inline parsers and does intermediate
* transformations.
**/
'use strict';

@@ -22,5 +26,11 @@

/**
* new Core()
**/
function Core() {
this.options = {};
/**
* Core#ruler -> Ruler
*
* [[Ruler]] instance. Keep configuration of core rules.
**/
this.ruler = new Ruler();

@@ -34,2 +44,7 @@

/**
* Core.process(state)
*
* Executes core chain rules.
**/
Core.prototype.process = function (state) {

@@ -36,0 +51,0 @@ var i, l, rules;

@@ -1,3 +0,6 @@

// Inline parser
/** internal
* class ParserInline
*
* Tokenizes paragraph content.
**/
'use strict';

@@ -47,9 +50,27 @@

// Inline Parser class
//
/**
* new ParserInline()
**/
function ParserInline() {
// By default CommonMark allows too much in links
// If you need to restrict it - override this with your validator.
/**
* ParserInline#validateLink(url) -> Boolean
*
* Link validation function. CommonMark allows too much in links. By default
* we disable `javascript:` and `vbscript:` schemas. You can change this
* behaviour.
*
* ```javascript
* var md = require('markdown-it')();
* // enable everything
* md.inline.validateLink = function () { return true; }
* ```
**/
this.validateLink = validateLink;
/**
* ParserInline#ruler -> Ruler
*
* [[Ruler]] instance. Keep configuration of inline rules.
**/
this.ruler = new Ruler();

@@ -124,4 +145,7 @@

// Parse input string.
//
/**
* ParserInline.parse(str, options, env, outTokens)
*
* Process input string and push inline tokens into `outTokens`
**/
ParserInline.prototype.parse = function (str, options, env, outTokens) {

@@ -128,0 +152,0 @@ var state = new StateInline(str, this, options, env, outTokens);

@@ -0,1 +1,8 @@

/**
* class Renderer
*
* Generates HTML from parsed token stream. Each instance has independent
* copy of rules. Those can be rewritten with ease. Also, you can add new
* rules if you create plugin and adds new token types.
**/
'use strict';

@@ -12,28 +19,3 @@

////////////////////////////////////////////////////////////////////////////////
// Helpers
function nextToken(tokens, idx) {
if (++idx >= tokens.length - 2) { return idx; }
if ((tokens[idx].type === 'paragraph_open' && tokens[idx].tight) &&
(tokens[idx + 1].type === 'inline' && tokens[idx + 1].content.length === 0) &&
(tokens[idx + 2].type === 'paragraph_close' && tokens[idx + 2].tight)) {
return nextToken(tokens, idx + 2);
}
return idx;
}
// check if we need to hide '\n' before next token
function getBreak(tokens, idx) {
idx = nextToken(tokens, idx);
if (idx < tokens.length &&
tokens[idx].type === 'list_item_close') {
return '';
}
return '\n';
}
////////////////////////////////////////////////////////////////////////////////
var rules = {};

@@ -46,4 +28,4 @@

};
rules.blockquote_close = function (tokens, idx /*, options, env */) {
return '</blockquote>' + getBreak(tokens, idx);
rules.blockquote_close = function (/* tokens, idx, options, env */) {
return '</blockquote>\n';
};

@@ -54,3 +36,3 @@

if (tokens[idx].block) {
return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>' + getBreak(tokens, idx);
return '<pre><code>' + escapeHtml(tokens[idx].content) + '</code></pre>\n';
}

@@ -97,3 +79,3 @@

+ highlighted
+ '</code></pre>' + getBreak(tokens, idx);
+ '</code></pre>\n';
};

@@ -112,3 +94,3 @@

rules.hr = function (tokens, idx, options /*, env */) {
return (options.xhtmlOut ? '<hr />' : '<hr>') + getBreak(tokens, idx);
return (options.xhtmlOut ? '<hr />\n' : '<hr>\n');
};

@@ -120,7 +102,12 @@

};
rules.bullet_list_close = function (tokens, idx /*, options, env */) {
return '</ul>' + getBreak(tokens, idx);
rules.bullet_list_close = function (/* tokens, idx, options, env */) {
return '</ul>\n';
};
rules.list_item_open = function (/* tokens, idx, options, env */) {
return '<li>';
rules.list_item_open = function (tokens, idx /*, options, env */) {
var next = tokens[idx + 1];
if ((next.type === 'list_item_close') ||
(next.type === 'paragraph_open' && next.tight)) {
return '<li>';
}
return '<li>\n';
};

@@ -131,9 +118,9 @@ rules.list_item_close = function (/* tokens, idx, options, env */) {

rules.ordered_list_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];
return '<ol'
+ (token.order > 1 ? ' start="' + token.order + '"' : '')
+ '>\n';
if (tokens[idx].order > 1) {
return '<ol start="' + tokens[idx].order + '">\n';
}
return '<ol>\n';
};
rules.ordered_list_close = function (tokens, idx /*, options, env */) {
return '</ol>' + getBreak(tokens, idx);
rules.ordered_list_close = function (/* tokens, idx, options, env */) {
return '</ol>\n';
};

@@ -146,4 +133,17 @@

rules.paragraph_close = function (tokens, idx /*, options, env */) {
var addBreak = !(tokens[idx].tight && idx && tokens[idx - 1].type === 'inline' && !tokens[idx - 1].content);
return (tokens[idx].tight ? '' : '</p>') + (addBreak ? getBreak(tokens, idx) : '');
// We have 2 cases of "hidden" paragraphs
//
// 1. In tight lists
// 2. When content was stripped (reference definition, for example)
//
if (tokens[idx].tight === true) {
if (!tokens[idx - 1].content) {
return '';
}
if (tokens[idx + 1].type === 'list_item_close') {
return '';
}
return '\n';
}
return '</p>\n';
};

@@ -161,6 +161,6 @@

rules.image = function (tokens, idx, options /*, env */) {
rules.image = function (tokens, idx, options, env, self) {
var src = ' src="' + escapeHtml(tokens[idx].src) + '"';
var title = tokens[idx].title ? (' title="' + escapeHtml(replaceEntities(tokens[idx].title)) + '"') : '';
var alt = ' alt="' + (tokens[idx].alt ? escapeHtml(replaceEntities(tokens[idx].alt)) : '') + '"';
var alt = ' alt="' + self.renderInlineAsText(tokens[idx].tokens, options, env) + '"';
var suffix = options.xhtmlOut ? ' /' : '';

@@ -196,6 +196,6 @@ return '<img' + src + alt + title + suffix + '>';

rules.th_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];
return '<th'
+ (token.align ? ' style="text-align:' + token.align + '"' : '')
+ '>';
if (tokens[idx].align) {
return '<th style="text-align:' + tokens[idx].align + '">';
}
return '<th>';
};

@@ -206,6 +206,6 @@ rules.th_close = function (/* tokens, idx, options, env */) {

rules.td_open = function (tokens, idx /*, options, env */) {
var token = tokens[idx];
return '<td'
+ (token.align ? ' style="text-align:' + token.align + '"' : '')
+ '>';
if (tokens[idx].align) {
return '<td style="text-align:' + tokens[idx].align + '">';
}
return '<td>';
};

@@ -345,11 +345,49 @@ rules.td_close = function (/* tokens, idx, options, env */) {

// Renderer class
/**
* new Renderer()
*
* Creates new [[Renderer]] instance and fill [[Renderer#rules]] with defaults.
**/
function Renderer() {
// Clone rules object to allow local modifications
/**
* Renderer#rules -> Object
*
* Contains render rules for tokens. Can be updated and extended.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')();
*
* md.renderer.rules.strong_open = function () { return '<b>'; };
* md.renderer.rules.strong_close = function () { return '</b>'; };
*
* var result = md.renderInline(...);
* ```
*
* Each rule is called as independed static function with fixed signature:
*
* ```javascript
* function my_token_render(tokens, idx, options, env, self) {
* // ...
* return renderedHTML;
* }
* ```
*
* See [source code](https://github.com/markdown-it/markdown-it/blob/master/lib/renderer.js)
* for more details and examples.
**/
this.rules = assign({}, rules);
// exported helper, for custom rules only
this.getBreak = getBreak;
}
/**
* Renderer.renderInline(tokens, options, env) -> String
* - tokens (Array): list on block tokens to renter
* - options (Object): params of parser instance
* - env (Object): additional data from parsed input (references, for example)
*
* The same as [[Renderer.render]], but for single token of `inline` type.
**/
Renderer.prototype.renderInline = function (tokens, options, env) {

@@ -367,2 +405,37 @@ var result = '',

/** internal
* Renderer.renderInlineAsText(tokens, options, env) -> String
* - tokens (Array): list on block tokens to renter
* - options (Object): params of parser instance
* - env (Object): additional data from parsed input (references, for example)
*
* Special kludge for image `alt` attributes to conform CommonMark spec.
* Don't try to use it! Spec requires to show `alt` content with stripped markup,
* instead of simple escaping.
**/
Renderer.prototype.renderInlineAsText = function (tokens, options, env) {
var result = '',
_rules = this.rules;
for (var i = 0, len = tokens.length; i < len; i++) {
if (tokens[i].type === 'text') {
result += _rules.text(tokens, i, options, env, this);
} else if (tokens[i].type === 'image') {
result += this.renderInlineAsText(tokens[i].tokens, options, env);
}
}
return result;
};
/**
* Renderer.render(tokens, options, env) -> String
* - tokens (Array): list on block tokens to renter
* - options (Object): params of parser instance
* - env (Object): additional data from parsed input (references, for example)
*
* Takes token stream and generates HTML. Probably, you will never need to call
* this method directly.
**/
Renderer.prototype.render = function (tokens, options, env) {

@@ -369,0 +442,0 @@ var i, len,

@@ -1,12 +0,24 @@

// Ruler is helper class to build responsibility chains from parse rules.
// It allows:
//
// - easy stack rules chains
// - getting main chain and named chains content (as arrays of functions)
//
/**
* class Ruler
*
* Helper class, used by [[MarkdownIt#core]], [[MarkdownIt#block]] and
* [[MarkdownIt#inline]] to manage sequences of functions (rules):
*
* - keep rules in defined order
* - assign the name to each rule
* - enable/disable rules
* - add/replace rules
* - allow assign rules to additional named chains (in the same)
* - cacheing lists of active rules
*
* You will not need use this class directly until write plugins. For simple
* rules control use [[MarkdownIt.disable]], [[MarkdownIt.enable]] and
* [[MarkdownIt.use]].
**/
'use strict';
////////////////////////////////////////////////////////////////////////////////
/**
* new Ruler()
**/
function Ruler() {

@@ -80,8 +92,27 @@ // List of added rules. Each element is:

////////////////////////////////////////////////////////////////////////////////
// Public methods
// Replace rule function
//
/**
* Ruler.at(name, fn [, options])
* - name (String): rule name to replace.
* - fn (Function): new rule function.
* - options (Object): new rule options (not mandatory).
*
* Replace rule by name with new function & options. Throws error if name not
* found.
*
* ##### Options:
*
* - __alt__ - array with names of "alternate" chains.
*
* ##### Example
*
* Replace existing typorgapher replacement rule with new one:
*
* ```javascript
* var md = require('markdown-it')();
*
* md.core.ruler.at('replacements', function replace(state) {
* //...
* });
* ```
**/
Ruler.prototype.at = function (name, fn, options) {

@@ -99,4 +130,26 @@ var index = this.__find__(name);

// Add rule to chain before one with given name.
//
/**
* Ruler.before(beforeName, ruleName, fn [, options])
* - beforeName (String): new rule will be added before this one.
* - ruleName (String): name of added rule.
* - fn (Function): rule function.
* - options (Object): rule options (not mandatory).
*
* Add new rule to chain before one with given name. See also
* [[Ruler.after]], [[Ruler.push]].
*
* ##### Options:
*
* - __alt__ - array with names of "alternate" chains.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')();
*
* md.block.ruler.before('paragraph', 'my_rule', function replace(state) {
* //...
* });
* ```
**/
Ruler.prototype.before = function (beforeName, ruleName, fn, options) {

@@ -119,4 +172,26 @@ var index = this.__find__(beforeName);

// Add rule to chain after one with given name.
//
/**
* Ruler.after(afterName, ruleName, fn [, options])
* - afterName (String): new rule will be added after this one.
* - ruleName (String): name of added rule.
* - fn (Function): rule function.
* - options (Object): rule options (not mandatory).
*
* Add new rule to chain after one with given name. See also
* [[Ruler.before]], [[Ruler.push]].
*
* ##### Options:
*
* - __alt__ - array with names of "alternate" chains.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')();
*
* md.inline.ruler.after('text', 'my_rule', function replace(state) {
* //...
* });
* ```
**/
Ruler.prototype.after = function (afterName, ruleName, fn, options) {

@@ -138,4 +213,25 @@ var index = this.__find__(afterName);

// Add rule to the end of chain.
//
/**
* Ruler.push(ruleName, fn [, options])
* - ruleName (String): name of added rule.
* - fn (Function): rule function.
* - options (Object): rule options (not mandatory).
*
* Push new rule to the end of chain. See also
* [[Ruler.before]], [[Ruler.after]].
*
* ##### Options:
*
* - __alt__ - array with names of "alternate" chains.
*
* ##### Example
*
* ```javascript
* var md = require('markdown-it')();
*
* md.core.ruler.push('emphasis', 'my_rule', function replace(state) {
* //...
* });
* ```
**/
Ruler.prototype.push = function (ruleName, fn, options) {

@@ -155,4 +251,12 @@ var opt = options || {};

// Enable rules by names.
//
/**
* Ruler.enable(list [, ignoreInvalid])
* - list (String|Array): list of rule names to enable.
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
*
* Enable rules with given names. If any rule name not found - throw Error.
* Errors can be disabled by second param.
*
* See also [[Ruler.disable]], [[Ruler.enableOnly]].
**/
Ruler.prototype.enable = function (list, ignoreInvalid) {

@@ -176,4 +280,12 @@ if (!Array.isArray(list)) { list = [ list ]; }

// Enable rules by whitelisted names (others will be disables).
//
/**
* Ruler.enableOnly(list [, ignoreInvalid])
* - list (String|Array): list of rule names to enable (whitelist).
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
*
* Enable rules with given names, and disable everything else. If any rule name
* not found - throw Error. Errors can be disabled by second param.
*
* See also [[Ruler.disable]], [[Ruler.enable]].
**/
Ruler.prototype.enableOnly = function (list, ignoreInvalid) {

@@ -188,4 +300,12 @@ if (!Array.isArray(list)) { list = [ list ]; }

// Disable rules by names.
//
/**
* Ruler.disable(list [, ignoreInvalid])
* - list (String|Array): list of rule names to disable.
* - ignoreInvalid (Boolean): set `true` to ignore errors when rule not found.
*
* Disable rules with given names. If any rule name not found - throw Error.
* Errors can be disabled by second param.
*
* See also [[Ruler.enable]], [[Ruler.enableOnly]].
**/
Ruler.prototype.disable = function (list, ignoreInvalid) {

@@ -211,4 +331,11 @@ if (!Array.isArray(list)) {

// Get rules list as array of functions.
//
/**
* Ruler.getRules(chainName) -> Array
*
* Return array of active functions (rules) for given chain name. It analyzes
* rules configuration, compiles caches if not exists and returns result.
*
* Default chain name is `''` (empty string). It can't be skipped. That's
* done intentionally, to keep signature monomorphic for high speed.
**/
Ruler.prototype.getRules = function (chainName) {

@@ -219,5 +346,6 @@ if (this.__cache__ === null) {

return this.__cache__[chainName];
// Chain can be empty, if rules disabled. But we still have to return Array.
return this.__cache__[chainName] || [];
};
module.exports = Ruler;

@@ -7,8 +7,6 @@ // Parse abbreviation definitions, i.e. `*[abbr]: description`

var StateInline = require('../rules_inline/state_inline');
var parseLinkLabel = require('../helpers/parse_link_label');
function parseAbbr(str, parserInline, options, env) {
var state, labelEnd, pos, max, label, title;
var pos, label, title, ch,
max = str.length,
labelEnd = -1;

@@ -20,15 +18,22 @@ if (str.charCodeAt(0) !== 0x2A/* * */) { return -1; }

state = new StateInline(str, parserInline, options, env, []);
labelEnd = parseLinkLabel(state, 1);
for (pos = 2; pos < max; pos++) {
ch = str.charCodeAt(pos);
if (ch === 0x5B /* [ */) {
return -1;
} else if (ch === 0x5D /* ] */) {
labelEnd = pos;
break;
} else if (ch === 0x5C /* \ */) {
pos++;
}
}
if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }
max = state.posMax;
// abbr title is always one line, so looking for ending "\n" here
for (pos = labelEnd + 2; pos < max; pos++) {
if (state.src.charCodeAt(pos) === 0x0A) { break; }
if (str.charCodeAt(pos) === 0x0A) { break; }
}
label = str.slice(2, labelEnd);
label = str.slice(2, labelEnd).replace(/\\(.)/g, '$1');
title = str.slice(labelEnd + 2, pos).trim();

@@ -35,0 +40,0 @@ if (title.length === 0) { return -1; }

@@ -5,3 +5,2 @@ 'use strict';

var StateInline = require('../rules_inline/state_inline');
var parseLinkLabel = require('../helpers/parse_link_label');
var parseLinkDestination = require('../helpers/parse_link_destination');

@@ -13,3 +12,4 @@ var parseLinkTitle = require('../helpers/parse_link_title');

function parseReference(str, parser, options, env) {
var state, labelEnd, pos, max, code, start, href, title, label;
var state, pos, code, start, href, title, label, ch, max,
labelEnd = -1;

@@ -21,8 +21,18 @@ if (str.charCodeAt(0) !== 0x5B/* [ */) { return -1; }

state = new StateInline(str, parser, options, env, []);
labelEnd = parseLinkLabel(state, 0);
max = state.posMax;
for (pos = 1; pos < max; pos++) {
ch = str.charCodeAt(pos);
if (ch === 0x5B /* [ */) {
return -1;
} else if (ch === 0x5D /* ] */) {
labelEnd = pos;
break;
} else if (ch === 0x5C /* \ */) {
pos++;
}
}
if (labelEnd < 0 || str.charCodeAt(labelEnd + 1) !== 0x3A/* : */) { return -1; }
max = state.posMax;
// [label]: destination 'title'

@@ -29,0 +39,0 @@ // ^^^ skip optional whitespace here

// Simple typographyc replacements
//
// '' → ‘’
// "" → “”. Set '«»' for Russian, '„“' for German, empty to disable
// (c) (C) → ©
// (tm) (TM) → ™
// (r) (R) → ®
// +- → ±
// (p) (P) -> §
// ... → … (also ?.... → ?.., !.... → !..)
// ???????? → ???, !!!!! → !!!, `,,` → `,`
// -- → &ndash;, --- → &mdash;
//
'use strict';

@@ -4,0 +15,0 @@

@@ -1,60 +0,78 @@

// Process ~~deleted text~~
'use strict';
module.exports = function del(state, silent) {
var found,
pos,
// parse sequence of markers,
// "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (pos >= max) { can_open = false; }
count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function(state, silent) {
var startCount,
count,
tagCount,
found,
stack,
res,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
marker = state.src.charCodeAt(start);
if (state.src.charCodeAt(start) !== 0x7E/* ~ */) { return false; }
if (marker !== 0x7E/* ~ */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x7E/* ~ */) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (lastChar === 0x7E/* ~ */) { return false; }
if (nextChar === 0x7E/* ~ */) { return false; }
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x7E/* ~ */) { pos++; }
if (pos > start + 3) {
// sequence of 4+ markers taking as literal, same as in a emphasis
state.pos += pos - start;
if (!silent) { state.pending += state.src.slice(start, pos); }
res = scanDelims(state, start);
startCount = res.delims;
if (!res.can_open) {
state.pos += startCount;
if (!silent) { state.pending += state.src.slice(start, state.pos); }
return true;
}
state.pos = start + 2;
stack = 1;
if (state.level >= state.options.maxNesting) { return false; }
stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
state.pos = start + startCount;
while (state.pos + 1 < max) {
if (state.src.charCodeAt(state.pos) === 0x7E/* ~ */) {
if (state.src.charCodeAt(state.pos + 1) === 0x7E/* ~ */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;
if (nextChar !== 0x7E/* ~ */ && lastChar !== 0x7E/* ~ */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '~~'
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '~~'
stack++;
} // else {
// // standalone ' ~~ ' indented with spaces
// }
if (stack <= 0) {
found = true;
break;
}
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === marker) {
res = scanDelims(state, state.pos);
count = res.delims;
tagCount = Math.floor(count / 2);
if (res.can_close) {
if (tagCount >= stack) {
state.pos += count - 2;
found = true;
break;
}
stack -= tagCount;
state.pos += count;
continue;
}
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
}

@@ -61,0 +79,0 @@

@@ -27,17 +27,12 @@ // Process *this* and _that_

if (count >= 4) {
// sequence of four or more unescaped markers can't start/end an emphasis
can_open = can_close = false;
} else {
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
if (marker === 0x5F /* _ */) {
// check if we aren't inside the word
if (isAlphaNum(lastChar)) { can_open = false; }
if (isAlphaNum(nextChar)) { can_close = false; }
}
if (marker === 0x5F /* _ */) {
// check if we aren't inside the word
if (isAlphaNum(lastChar)) { can_open = false; }
if (isAlphaNum(nextChar)) { can_close = false; }
}

@@ -130,15 +125,13 @@

if (!silent) {
if (startCount === 2 || startCount === 3) {
// we have `startCount` starting and ending markers,
// now trying to serialize them into tokens
for (count = startCount; count > 1; count -= 2) {
state.push({ type: 'strong_open', level: state.level++ });
}
if (startCount === 1 || startCount === 3) {
state.push({ type: 'em_open', level: state.level++ });
}
if (count % 2) { state.push({ type: 'em_open', level: state.level++ }); }
state.parser.tokenize(state);
if (startCount === 1 || startCount === 3) {
state.push({ type: 'em_close', level: --state.level });
}
if (startCount === 2 || startCount === 3) {
if (count % 2) { state.push({ type: 'em_close', level: --state.level }); }
for (count = startCount; count > 1; count -= 2) {
state.push({ type: 'strong_close', level: --state.level });

@@ -145,0 +138,0 @@ }

@@ -43,7 +43,5 @@ // Process inline footnotes (^[...])

});
state.linkLevel++;
oldLength = state.tokens.length;
state.parser.tokenize(state);
state.env.footnotes.list[footnoteId] = { tokens: state.tokens.splice(oldLength) };
state.linkLevel--;
}

@@ -50,0 +48,0 @@

@@ -1,60 +0,78 @@

// Process ++inserted text++
'use strict';
module.exports = function ins(state, silent) {
var found,
pos,
// parse sequence of markers,
// "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (pos >= max) { can_open = false; }
count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function(state, silent) {
var startCount,
count,
tagCount,
found,
stack,
res,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
marker = state.src.charCodeAt(start);
if (state.src.charCodeAt(start) !== 0x2B/* + */) { return false; }
if (marker !== 0x2B/* + */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x2B/* + */) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (lastChar === 0x2B/* + */) { return false; }
if (nextChar === 0x2B/* + */) { return false; }
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x2B/* + */) { pos++; }
if (pos !== start + 2) {
// sequence of 3+ markers taking as literal, same as in a emphasis
state.pos += pos - start;
if (!silent) { state.pending += state.src.slice(start, pos); }
res = scanDelims(state, start);
startCount = res.delims;
if (!res.can_open) {
state.pos += startCount;
if (!silent) { state.pending += state.src.slice(start, state.pos); }
return true;
}
state.pos = start + 2;
stack = 1;
if (state.level >= state.options.maxNesting) { return false; }
stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
state.pos = start + startCount;
while (state.pos + 1 < max) {
if (state.src.charCodeAt(state.pos) === 0x2B/* + */) {
if (state.src.charCodeAt(state.pos + 1) === 0x2B/* + */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;
if (nextChar !== 0x2B/* + */ && lastChar !== 0x2B/* + */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '++'
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '++'
stack++;
} // else {
// // standalone ' ++ ' indented with spaces
// }
if (stack <= 0) {
found = true;
break;
}
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === marker) {
res = scanDelims(state, state.pos);
count = res.delims;
tagCount = Math.floor(count / 2);
if (res.can_close) {
if (tagCount >= stack) {
state.pos += count - 2;
found = true;
break;
}
stack -= tagCount;
state.pos += count;
continue;
}
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
}

@@ -61,0 +79,0 @@

@@ -9,13 +9,15 @@ // Process [links](<to> "stuff")

var normalizeReference = require('../helpers/normalize_reference');
var StateInline = require('../rules_inline/state_inline');
module.exports = function links(state, silent) {
var labelStart,
var code,
href,
label,
labelEnd,
label,
href,
title,
labelStart,
pos,
ref,
code,
title,
tokens,
isImage = false,

@@ -36,3 +38,3 @@ oldPos = state.pos,

labelStart = start + 1;
labelEnd = parseLinkLabel(state, start);
labelEnd = parseLinkLabel(state, start, !isImage);

@@ -100,6 +102,4 @@ // parser failed to find ']', so it's not a valid link

//
if (typeof state.env.references === 'undefined') { return false; }
// do not allow nested reference links
if (state.linkLevel > 0) { return false; }
// [foo] [bar]

@@ -118,4 +118,6 @@ // ^^ optional whitespace (can include newlines)

} else {
pos = start - 1;
pos = labelEnd + 1;
}
} else {
pos = labelEnd + 1;
}

@@ -145,2 +147,11 @@

if (isImage) {
var newState = new StateInline(
state.src.slice(labelStart, labelEnd),
state.parser,
state.options,
state.env,
tokens = []
);
newState.parser.tokenize(newState);
state.push({

@@ -150,3 +161,3 @@ type: 'image',

title: title,
alt: state.src.substr(labelStart, labelEnd - labelStart),
tokens: tokens,
level: state.level

@@ -161,5 +172,3 @@ });

});
state.linkLevel++;
state.parser.tokenize(state);
state.linkLevel--;
state.push({ type: 'link_close', level: --state.level });

@@ -166,0 +175,0 @@ }

@@ -1,60 +0,78 @@

// Process ==highlighted text==
'use strict';
module.exports = function del(state, silent) {
var found,
pos,
// parse sequence of markers,
// "start" should point at a valid marker
function scanDelims(state, start) {
var pos = start, lastChar, nextChar, count,
can_open = true,
can_close = true,
max = state.posMax,
marker = state.src.charCodeAt(start);
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
while (pos < max && state.src.charCodeAt(pos) === marker) { pos++; }
if (pos >= max) { can_open = false; }
count = pos - start;
nextChar = pos < max ? state.src.charCodeAt(pos) : -1;
// check whitespace conditions
if (nextChar === 0x20 || nextChar === 0x0A) { can_open = false; }
if (lastChar === 0x20 || lastChar === 0x0A) { can_close = false; }
return {
can_open: can_open,
can_close: can_close,
delims: count
};
}
module.exports = function(state, silent) {
var startCount,
count,
tagCount,
found,
stack,
res,
max = state.posMax,
start = state.pos,
lastChar,
nextChar;
marker = state.src.charCodeAt(start);
if (state.src.charCodeAt(start) !== 0x3D/* = */) { return false; }
if (marker !== 0x3D/* = */) { return false; }
if (silent) { return false; } // don't run any pairs in validation mode
if (start + 4 >= max) { return false; }
if (state.src.charCodeAt(start + 1) !== 0x3D/* = */) { return false; }
if (state.level >= state.options.maxNesting) { return false; }
lastChar = start > 0 ? state.src.charCodeAt(start - 1) : -1;
nextChar = state.src.charCodeAt(start + 2);
if (lastChar === 0x3D/* = */) { return false; }
if (nextChar === 0x3D/* = */) { return false; }
if (nextChar === 0x20 || nextChar === 0x0A) { return false; }
pos = start + 2;
while (pos < max && state.src.charCodeAt(pos) === 0x3D/* = */) { pos++; }
if (pos !== start + 2) {
// sequence of 3+ markers taking as literal, same as in a emphasis
state.pos += pos - start;
if (!silent) { state.pending += state.src.slice(start, pos); }
res = scanDelims(state, start);
startCount = res.delims;
if (!res.can_open) {
state.pos += startCount;
if (!silent) { state.pending += state.src.slice(start, state.pos); }
return true;
}
state.pos = start + 2;
stack = 1;
if (state.level >= state.options.maxNesting) { return false; }
stack = Math.floor(startCount / 2);
if (stack <= 0) { return false; }
state.pos = start + startCount;
while (state.pos + 1 < max) {
if (state.src.charCodeAt(state.pos) === 0x3D/* = */) {
if (state.src.charCodeAt(state.pos + 1) === 0x3D/* = */) {
lastChar = state.src.charCodeAt(state.pos - 1);
nextChar = state.pos + 2 < max ? state.src.charCodeAt(state.pos + 2) : -1;
if (nextChar !== 0x3D/* = */ && lastChar !== 0x3D/* = */) {
if (lastChar !== 0x20 && lastChar !== 0x0A) {
// closing '=='
stack--;
} else if (nextChar !== 0x20 && nextChar !== 0x0A) {
// opening '=='
stack++;
} // else {
// // standalone ' == ' indented with spaces
// }
if (stack <= 0) {
found = true;
break;
}
while (state.pos < max) {
if (state.src.charCodeAt(state.pos) === marker) {
res = scanDelims(state, state.pos);
count = res.delims;
tagCount = Math.floor(count / 2);
if (res.can_close) {
if (tagCount >= stack) {
state.pos += count - 2;
found = true;
break;
}
stack -= tagCount;
state.pos += count;
continue;
}
if (res.can_open) { stack += tagCount; }
state.pos += count;
continue;
}

@@ -61,0 +79,0 @@

@@ -23,9 +23,2 @@ // Inline parser state

this.isInLabel = false; // Set true when seek link label - we should disable
// "paired" rules (emphasis, strikes) to not skip
// tailing `]`
this.linkLevel = 0; // Increment for each nesting link. Used to prevent
// nesting in definitions
this.linkContent = ''; // Temporary storage for link url

@@ -32,0 +25,0 @@

{
"name": "markdown-it",
"version": "2.1.3",
"version": "2.2.0",
"description": "Markdown-it - modern pluggable markdown parser.",

@@ -5,0 +5,0 @@ "keywords": [

@@ -14,3 +14,3 @@ # markdown-it

- High speed!
- Community written __[plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin)__ and [other packages](https://www.npmjs.org/browse/keyword/markdown-it) on npm.
- Community-written __[plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin)__ and [other packages](https://www.npmjs.org/browse/keyword/markdown-it) on npm.

@@ -20,11 +20,5 @@ __Table of content__

- [Install](#install)
- [Usage](#usage)
- [Configuring](#configuring)
- [constructor(preset, options)](#constructorpreset-options)
- [.set({ keys: values })](#set-keys-values-)
- [.use(plugin, options)](#useplugin-options)
- [Syntax highlighting](#syntax-highlighting)
- [Typographer](#typographer)
- [Syntax extensions](#syntax-extensions)
- [Manage rules](#manage-rules)
- [Usage examples](#usage-examples)
- [API](#api)
- [Syntax extensions](#syntax-extensions)
- [Benchmark](#benchmark)

@@ -49,4 +43,10 @@ - [Authors](#authors)

## Usage
## Usage examples
See __[API documentation](https://markdown-it.github.io/markdown-it/)__ for more
info and examples.
### Simple
```js

@@ -56,7 +56,7 @@ // node.js, "classic" way:

md = new MarkdownIt();
console.log(md.render('# markdown-it rulezz!'));
var result = md.render('# markdown-it rulezz!');
// node.js, the same, but with sugar:
var md = require('markdown-it')();
console.log(md.render('# markdown-it rulezz!'));
var result = md.render('# markdown-it rulezz!');

@@ -66,27 +66,18 @@ // browser without AMD, added to "window" on script load

var md = window.markdownit();
console.log(md.render('# markdown-it rulezz!'));
var result = md.render('# markdown-it rulezz!');
```
Single line rendering, without paragraph wrap:
### Configuring
```js
var md = require('markdown-it')();
var result = md.renderInline('__markdown-it__ rulezz!');
```
By default `markdown-it` is configured to be similar to GFM, but with HTML disabled.
This is easy to change if you prefer different settings.
Usually, you will define everything via constructor.
### Init with presets and options
#### constructor(preset, options)
(*) preset define combination of active rules and options. Can be
`"full"`|`"commonmark"`|`"zero"` or `"default"` if skipped.
__preset__ (String) - `"full"`|`"commonmark"`, optional.
`markdown-it` offers some presets as a convenience to quickly enable/disable
active syntax rules and options for common use cases.
- ["commonmark"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/commonmark.js) - enable strict [CommonMark](http://commonmark.org/) mode.
- ["full"](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/full.js) -
all rules enabled, but still without html, typographer & autolinker.
- [default](https://github.com/markdown-it/markdown-it/blob/master/lib/presets/default.js) -
when no preset name given.
```js

@@ -105,8 +96,4 @@ // commonmark mode

});
```
__options__
```js
// Actual default values
// full options list (defaults)
var md = require('markdown-it')({

@@ -134,25 +121,6 @@ html: false, // Enable HTML tags in source

### Plugins load
#### .set({ keys: values })
Probably, you will never need it. But you can change options after
constructor call.
```js
var md = require('markdown-it')()
.set({ html: true, breaks: true })
.set({ typographer, true });
```
**Note:** To achieve the best possible performance, don't modify a `markdown-it`
instance on the fly. If you need multiple configurations it's best to create
multiple instances and initialize each with separate config.
#### .use(plugin, options)
Sugar to activate plugins.
```js
var md = require('markdown-it')()
.use(plugin1)

@@ -177,3 +145,3 @@ .use(plugin2, opts)

return hljs.highlight(lang, str).value;
} catch (err) {}
} catch (__) {}
}

@@ -183,3 +151,3 @@

return hljs.highlightAuto(str).value;
} catch (err) {}
} catch (__) {}

@@ -192,37 +160,9 @@ return ''; // use external default escaping

### Typographer
## API
Although full-weight typographical replacements are language specific, `markdown-it`
provides coverage for the most common and universal use cases:
[API documentation](https://markdown-it.github.io/markdown-it/)
```js
var md = require('markdown-it')({
typographer: true,
quotes: '“”‘’'
});
// Disable rules at all:
md.disable([ 'replacements', 'smartquotes' ]);
## Syntax extensions
// Actual default replacements:
//
// '' → ‘’
// "" → “”. Set '«»' for Russian, '„“' for German, empty to disable
// (c) (C) → ©
// (tm) (TM) → ™
// (r) (R) → ®
// +- → ±
// (p) (P) -> §
// ... → … (also ?.... → ?.., !.... → !..)
// ???????? → ???, !!!!! → !!!, `,,` → `,`
// -- → &ndash;, --- → &mdash;
//
```
Of course, you can also add your own rules or replace the defaults with something
more advanced or specific to your language.
### Syntax extensions
Enabled by default:

@@ -298,3 +238,3 @@

As you can see, `markdown-it` doesn't pay with speed for it's flexibility.
Because it's written in monomorphyc style and use JIT inline caches effectively.
Because it's written in monomorphyc style and uses JIT inline caches effectively.

@@ -307,2 +247,5 @@

_markdown-it_ is the result of the decision of the authors who contributed to
99% of the _Remarkable_ code to move to a project with the same authorship but
new leadership (Vitaly and Alex). It's not a fork.

@@ -309,0 +252,0 @@ ## References / Thanks

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

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