Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

mdast-util-to-hast

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mdast-util-to-hast - npm Package Compare versions

Comparing version
1.0.0
to
2.0.0
+56
lib/all.js
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:all
* @fileoverview Visit all MDAST nodes.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = all;
/* Dependencies. */
var trim = require('trim');
var one = require('./one');
/**
* Transform the children of `parent`.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} parent - Parent to visit.
* @return {Array.<Node>} - HAST nodes.
*/
function all(h, parent) {
var nodes = parent.children || [];
var length = nodes.length;
var values = [];
var index = -1;
var result;
var head;
while (++index < length) {
result = one(h, nodes[index], parent);
if (result) {
if (index && nodes[index - 1].type === 'break') {
if (result.value) {
result.value = trim.left(result.value);
}
head = result.children && result.children[0];
if (head && head.value) {
head.value = trim.left(head.value);
}
}
values = values.concat(result);
}
}
return values;
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:failsafe
* @fileoverview Failsafe to stringify references
* without definitions back to markdown.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = failsafe;
/* Dependencies. */
var u = require('unist-builder');
var all = require('./all');
/**
* Return the content of a reference without definition
* as markdown.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @param {Node?} [definition] - Definition node.
* @return {Array.<string>?} - Node, list of nodes, or nothing.
*/
function failsafe(h, node, definition) {
var subtype = node.referenceType;
if (subtype !== 'collapsed' && subtype !== 'full' && !definition) {
if (node.type === 'imageReference') {
return u('text', '![' + node.alt + ']');
}
return [u('text', '[')].concat(all(h, node), u('text', ']'));
}
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:footnotes
* @fileoverview Generate the footnote footer.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = generateFootnotes;
/* Dependencies. */
var thematicBreak = require('./handlers/thematic-break');
var list = require('./handlers/list');
var wrap = require('./wrap');
/**
* Transform all footnote definitions, if any.
*
* @param {Function} h - Hyperscript DSL.
* @return {Node?} - Compiled footnotes, if any.
*/
function generateFootnotes(h) {
var footnotes = h.footnotes;
var length = footnotes.length;
var index = -1;
var listItems = [];
var def;
if (!length) {
return null;
}
while (++index < length) {
def = footnotes[index];
listItems[index] = {
type: 'listItem',
data: {hProperties: {id: 'fn-' + def.identifier}},
children: def.children.concat({
type: 'link',
url: '#fnref-' + def.identifier,
data: {hProperties: {className: ['footnote-backref']}},
children: [{
type: 'text',
value: '↩'
}]
}),
position: def.position
};
}
return h(null, 'div', {
className: ['footnotes']
}, wrap([
thematicBreak(h),
list(h, {
type: 'list',
ordered: true,
children: listItems
})
], true));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:blockquote
* @fileoverview Handle a `blockquote`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = blockquote;
/* Dependencies. */
var wrap = require('../wrap');
var all = require('../all');
/**
* Transform a block quote.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function blockquote(h, node) {
return h(node, 'blockquote', wrap(all(h, node), true));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:break
* @fileoverview Handle a `break`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = hardBreak;
/* Dependencies. */
var u = require('unist-builder');
/**
* Transform an inline break.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Array.<Node>} - HAST nodes.
*/
function hardBreak(h, node) {
return [h(node, 'br'), u('text', '\n')];
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:code
* @fileoverview Handle `code`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = code;
/* Dependencies. */
var detab = require('detab');
var u = require('unist-builder');
/**
* Transform a code block.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function code(h, node) {
var value = node.value ? detab(node.value + '\n') : '';
var lang = node.lang && node.lang.match(/^[^ \t]+(?=[ \t]|$)/);
var props = {};
if (lang) {
props.className = ['language-' + lang];
}
return h(node.position, 'pre', [
h(node, 'code', props, [u('text', value)])
]);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:delete
* @fileoverview Handle `delete`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = strikethrough;
/* Dependencies. */
var all = require('../all');
/**
* Transform deletions.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function strikethrough(h, node) {
return h(node, 'del', all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:emphasis
* @fileoverview Handle `emphasis`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = emphasis;
/* Dependencies. */
var all = require('../all');
/**
* Transform emphasis
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function emphasis(h, node) {
return h(node, 'em', all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:footnote-reference
* @fileoverview Handle `footnoteReference`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = footnoteReference;
/* Dependencies. */
var u = require('unist-builder');
/**
* Transform a reference to a footnote.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function footnoteReference(h, node) {
var identifier = node.identifier;
return h(node.position, 'sup', {id: 'fnref-' + identifier}, [
h(node, 'a', {
href: '#fn-' + identifier,
className: ['footnote-ref']
}, [u('text', identifier)])
]);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:footnote
* @fileoverview Handle `footnote`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = footnote;
/* Dependencies. */
var footnoteReference = require('./footnote-reference');
/**
* Transform an inline footnote.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function footnote(h, node) {
var identifiers = [];
var identifier = 1;
var footnotes = h.footnotes;
var length = footnotes.length;
var index = -1;
while (++index < length) {
identifiers[index] = footnotes[index].identifier;
}
while (identifiers.indexOf(String(identifier)) !== -1) {
identifier++;
}
identifier = String(identifier);
footnotes.push({
type: 'footnoteDefinition',
identifier: identifier,
children: node.children,
position: node.position
});
return footnoteReference(h, {
type: 'footnoteReference',
identifier: identifier,
position: node.position
});
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:heading
* @fileoverview Handle `heading`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = heading;
/* Dependencies. */
var all = require('../all');
/**
* Transform a heading.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function heading(h, node) {
return h(node, 'h' + node.depth, all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:html
* @fileoverview Handle `html`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = html;
/* Dependencies. */
var u = require('unist-builder');
/**
* Return either a `raw` node, in dangerous mode, or
* nothing.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node|null} - Nothing.
*/
function html(h, node) {
return h.dangerous ? h.augment(node, u('raw', node.value)) : null;
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:image-reference
* @fileoverview Handle `imageReference`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = imageReference;
/* Dependencies. */
var normalize = require('normalize-uri');
var failsafe = require('../failsafe');
/**
* Transform a reference to an image.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function imageReference(h, node) {
var def = h.definition(node.identifier);
var props = {src: normalize((def && def.url) || ''), alt: node.alt};
if (def && def.title != null) {
props.title = def.title;
}
return failsafe(h, node, def) || h(node, 'img', props);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:image
* @fileoverview Handle `image`.
*/
'use strict';
/* eslint-env commonjs */
/* Dependencies. */
var normalize = require('normalize-uri');
/* Expose. */
module.exports = image;
/**
* Transform an image.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function image(h, node) {
var props = {src: normalize(node.url), alt: node.alt};
if (node.title != null) {
props.title = node.title;
}
return h(node, 'img', props);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers
* @fileoverview Handle each node.
*/
'use strict';
/* eslint-env commonjs */
/* Handlers. */
module.exports = {
blockquote: require('./blockquote'),
break: require('./break'),
code: require('./code'),
delete: require('./delete'),
emphasis: require('./emphasis'),
footnoteReference: require('./footnote-reference'),
footnote: require('./footnote'),
heading: require('./heading'),
html: require('./html'),
imageReference: require('./image-reference'),
image: require('./image'),
inlineCode: require('./inline-code'),
linkReference: require('./link-reference'),
link: require('./link'),
listItem: require('./list-item'),
list: require('./list'),
paragraph: require('./paragraph'),
root: require('./root'),
strong: require('./strong'),
table: require('./table'),
text: require('./text'),
thematicBreak: require('./thematic-break'),
yaml: ignore,
definition: ignore,
footnoteDefinition: ignore
};
/**
* Return nothing for nodes which are ignored.
*
* @return {null} - Nothing.
*/
function ignore() {
return null;
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:inline-code
* @fileoverview Handle `inlineCode`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = inlineCode;
/* Dependencies. */
var collapse = require('collapse-white-space');
var u = require('unist-builder');
/**
* Transform inline code.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function inlineCode(h, node) {
return h(node, 'code', [u('text', collapse(node.value))]);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:link-reference
* @fileoverview Handle `linkReference`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = linkReference;
/* Dependencies. */
var normalize = require('normalize-uri');
var failsafe = require('../failsafe');
var all = require('../all');
/**
* Transform a reference to a link.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function linkReference(h, node) {
var def = h.definition(node.identifier);
var props = {href: normalize((def && def.url) || '')};
if (def && def.title != null) {
props.title = def.title;
}
return failsafe(h, node, def) || h(node, 'a', props, all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:link
* @fileoverview Handle `link`.
*/
'use strict';
/* eslint-env commonjs */
/* Dependencies. */
var normalize = require('normalize-uri');
var all = require('../all');
/* Expose. */
module.exports = link;
/**
* Transform a link.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function link(h, node) {
var props = {href: normalize(node.url)};
if (node.title != null) {
props.title = node.title;
}
return h(node, 'a', props, all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:list-item
* @fileoverview Handle `listItem`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = listItem;
/* Dependencies. */
var u = require('unist-builder');
var wrap = require('../wrap');
var all = require('../all');
/**
* Transform a list-item.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @param {Node} parent - Parent of `node`.
* @return {Node} - HAST node.
*/
function listItem(h, node, parent) {
var children = node.children;
var head = children[0];
var single = (!parent || !parent.loose) && head.children && children.length === 1;
var result = all(h, single ? head : node);
var container;
var props = {};
if (typeof node.checked === 'boolean') {
if (!single && head.type !== 'paragraph') {
result.unshift(h(null, 'p', []));
}
container = single ? result : result[0].children;
if (container.length) {
container.unshift(u('text', ' '));
}
container.unshift(h(null, 'input', {
type: 'checkbox',
checked: node.checked,
disabled: true
}));
/* according to github-markdown-css, this class hides bullet. */
props.className = ['task-list-item'];
}
if (!single && result.length) {
result = wrap(result, true);
}
return h(node, 'li', props, result);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:list
* @fileoverview Handle `list`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = list;
/* Dependencies. */
var wrap = require('../wrap');
var all = require('../all');
/**
* Transform a list.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function list(h, node) {
var props = {};
var name = node.ordered ? 'ol' : 'ul';
if (typeof node.start === 'number' && node.start !== 1) {
props.start = node.start;
}
return h(node, name, props, wrap(all(h, node), true));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:paragraph
* @fileoverview Handle `paragraph`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = paragraph;
/* Dependencies. */
var all = require('../all');
/**
* Transform a paragraph.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function paragraph(h, node) {
return h(node, 'p', all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:root
* @fileoverview Handle `root`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = root;
/* Dependencies. */
var u = require('unist-builder');
var wrap = require('../wrap');
var all = require('../all');
/**
* Transform a `root`.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function root(h, node) {
return h.augment(node, u('root', wrap(all(h, node))));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:strong
* @fileoverview Handle `strong`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = strong;
/* Dependencies. */
var all = require('../all');
/**
* Transform importance.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function strong(h, node) {
return h(node, 'strong', all(h, node));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:table
* @fileoverview Handle `table`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = table;
/* Dependencies. */
var position = require('unist-util-position');
var wrap = require('../wrap');
var all = require('../all');
/**
* Transform a table.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function table(h, node) {
var rows = node.children;
var index = rows.length;
var align = node.align;
var alignLength = align.length;
var result = [];
var pos;
var row;
var out;
var name;
var cell;
while (index--) {
row = rows[index].children;
name = index === 0 ? 'th' : 'td';
pos = alignLength;
out = [];
while (pos--) {
cell = row[pos];
out[pos] = h(cell, name, {
align: align[pos]
}, cell ? wrap(all(h, cell)) : []);
}
result[index] = h(rows[index], 'tr', wrap(out, true));
}
return h(node, 'table', wrap([
h(result[0].position, 'thead', wrap([result[0]], true)),
h({
start: position.start(result[1]),
end: position.end(result[result.length - 1])
}, 'tbody', wrap(result.slice(1), true))
], true));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:text
* @fileoverview Handle `text`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = text;
/* Dependencies. */
var u = require('unist-builder');
var trimLines = require('trim-lines');
/**
* Transform text.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST text node.
*/
function text(h, node) {
return h.augment(node, u('text', trimLines(node.value)));
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:handlers:thematic-break
* @fileoverview Handle `thematicBreak`.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = thematicBreak;
/**
* Transform a thematic break / horizontal rule.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function thematicBreak(h, node) {
return h(node, 'hr');
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast
* @fileoverview Transform MDAST to HAST.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = toHAST;
/* Dependencies. */
var xtend = require('xtend');
var u = require('unist-builder');
var visit = require('unist-util-visit');
var position = require('unist-util-position');
var definitions = require('mdast-util-definitions');
var one = require('./one');
var footer = require('./footer');
/**
* Factory to transform.
*
* @param {Node} tree - MDAST tree.
* @param {Object?} options - Configuration.
* @return {Function} - Hyperscript-like DSL.
*/
function factory(tree, options) {
var dangerous = (options || {}).allowDangerousHTML;
/**
* Finalise the created `right`, a HAST node, from
* `left`, an MDAST node.
*
* @param {Node} left - MDAST node.
* @param {Node} right - HAST node.
*/
function augment(left, right) {
var data;
var ctx;
/* handle `data.hName`, `data.hProperties, `hChildren`. */
if (left && 'data' in left) {
data = left.data;
if (right.type === 'element' && data.hName) {
right.tagName = data.hName;
}
if (right.type === 'element' && data.hProperties) {
right.properties = xtend(right.properties, data.hProperties);
}
if (right.children && data.hChildren) {
right.children = data.hChildren;
}
}
ctx = left && left.position ? left : {position: left};
if (!position.generated(ctx)) {
right.position = {
start: position.start(ctx),
end: position.end(ctx)
};
}
return right;
}
/**
* Create an element for a `node`.
*
* @param {Node} node - MDAST node to compile for.
* @param {string} tagName - Proposed tag-name.
* @param {Object?} [props={}] - Properties.
* @param {Array.<Node>} children - HAST children.
*/
function h(node, tagName, props, children) {
if (
children == null &&
typeof props === 'object' &&
'length' in props
) {
children = props;
props = {};
}
return augment(node, {
type: 'element',
tagName: tagName,
properties: props || {},
children: children || []
});
}
h.dangerous = dangerous;
h.definition = definitions(tree);
h.footnotes = [];
h.augment = augment;
visit(tree, 'footnoteDefinition', function (definition) {
h.footnotes.push(definition);
});
return h;
}
/**
* Transform `tree`, which is an MDAST node, to a HAST node.
*
* @param {Node} tree - MDAST Node.
* @param {Object} [options] - Configuration.
* @return {Node} - HAST Node.
*/
function toHAST(tree, options) {
var h = factory(tree, options);
var node = one(h, tree);
var footnotes = footer(h);
if (node && node.children && footnotes) {
node.children = node.children.concat(u('text', '\n'), footnotes);
}
return node;
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:one
* @fileoverview Transform one MDAST node.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = one;
/* Dependencies. */
var u = require('unist-builder');
var has = require('has');
var all = require('./all');
var handlers = require('./handlers');
/**
* Transform an unknown node.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function unknown(h, node) {
if ('value' in node) {
return h.augment(node, u('text', node.value));
}
return h(node, 'div', all(h, node));
}
/**
* Visit a node.
*
* @param {Function} h - Hyperscript DSL.
* @param {Object} node - Node.
* @param {Object?} [parent] - `node`s parent.
* @return {Node} - HAST node.
* @throws {Error} - When `node` is not an MDAST node.
*/
function one(h, node, parent) {
var type = node && node.type;
var fn = has(handlers, type) ? handlers[type] : null;
/* Fail on non-nodes. */
if (!type) {
throw new Error('Expected node, got `' + node + '`');
}
return (typeof fn === 'function' ? fn : unknown)(h, node, parent);
}
/**
* @author Titus Wormer
* @copyright 2015 Titus Wormer
* @license MIT
* @module mdast:to-hast:wrap
* @fileoverview Wrap a list of nodes in white-space.
*/
'use strict';
/* eslint-env commonjs */
/* Expose. */
module.exports = wrap;
/* Dependencies. */
var u = require('unist-builder');
/**
* Wrap `nodes` with newlines between each entry.
* Optionally adds newlines at the start and end.
*
* @param {Array.<Node>} nodes - Nodes to wrap.
* @param {boolean} loose - Whether to inject newlines at
* the start, and end (in case nodes has entries).
* @return {Array.<Node>} - Wrapped nodes.
*/
function wrap(nodes, loose) {
var result = [];
var index = -1;
var length = nodes.length;
if (loose) {
result.push(u('text', '\n'));
}
while (++index < length) {
if (index) {
result.push(u('text', '\n'));
}
result.push(nodes[index]);
}
if (loose && nodes.length) {
result.push(u('text', '\n'));
}
return result;
}
+1
-745

@@ -13,747 +13,3 @@ /**

/* Dependencies. */
var visit = require('unist-util-visit');
var position = require('unist-util-position');
var definitions = require('mdast-util-definitions');
var collapse = require('collapse-white-space');
var normalize = require('normalize-uri');
var trimLines = require('trim-lines');
var detab = require('detab');
var trim = require('trim');
var xtend = require('xtend');
var u = require('unist-builder');
/* Compilers. */
var handlers = {};
/**
* Wrap `nodes` with newlines between each entry.
* Optionally adds newlines at the start and end.
*
* @param {Array.<Node>} nodes - Nodes to wrap.
* @param {boolean} loose - Whether to inject newlines at
* the start, and end (in case nodes has entries).
* @return {Array.<Node>} - Wrapped nodes.
*/
function wrapInLines(nodes, loose) {
var result = [];
var index = -1;
var length = nodes.length;
if (loose) {
result.push(u('text', '\n'));
}
while (++index < length) {
if (index) {
result.push(u('text', '\n'));
}
result.push(nodes[index]);
}
if (loose && nodes.length) {
result.push(u('text', '\n'));
}
return result;
}
/**
* Return the content of a reference without definition
* as markdown.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @param {Node?} [definition] - Definition node.
* @return {Array.<string>?} - Node, list of nodes, or nothing.
*/
function failsafe(h, node, definition) {
var subtype = node.referenceType;
if (subtype !== 'collapsed' && subtype !== 'full' && !definition) {
if (node.type === 'imageReference') {
return u('text', '![' + node.alt + ']');
}
return [u('text', '[')].concat(all(h, node), u('text', ']'));
}
}
/**
* Transform all footnote definitions, if any.
*
* @param {Function} h - Hyperscript DSL.
* @return {Node?} - Compiled footnotes, if any.
*/
function generateFootnotes(h) {
var footnotes = h.footnotes;
var length = footnotes.length;
var index = -1;
var listItems = [];
var def;
if (!length) {
return null;
}
while (++index < length) {
def = footnotes[index];
listItems[index] = {
type: 'listItem',
data: { hProperties: { id: 'fn-' + def.identifier } },
children: def.children.concat({
type: 'link',
url: '#fnref-' + def.identifier,
data: { hProperties: { className: ['footnote-backref'] } },
children: [{
type: 'text',
value: '↩'
}]
}),
position: def.position
};
}
return h(null, 'div', {
className: ['footnotes']
}, wrapInLines([
thematicBreak(h),
list(h, {
type: 'list',
ordered: true,
children: listItems
})
], true));
}
/**
* Transform an unknown node.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function unknown(h, node) {
if ('value' in node) {
return h.wrap(node, u('text', node.value));
}
return h(node, 'div', all(h, node));
}
/**
* Visit a node.
*
* @param {Function} h - Hyperscript DSL.
* @param {Object} node - Node.
* @param {Object?} [parent] - `node`s parent.
* @return {Node} - HAST node.
* @throws {Error} - When `node` is not an MDAST node.
*/
function one(h, node, parent) {
var type = node && node.type;
var fn = handlers[type];
/* Fail on non-nodes. */
if (!type) {
throw new Error('Expected node, got `' + node + '`');
}
return (typeof fn === 'function' ? fn : unknown)(h, node, parent);
}
/**
* Transform the children of `parent`.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} parent - Parent to visit.
* @return {Array.<Node>} - HAST nodes.
*/
function all(h, parent) {
var nodes = parent.children || [];
var length = nodes.length;
var values = [];
var index = -1;
var result;
var head;
while (++index < length) {
result = one(h, nodes[index], parent);
if (result) {
if (index && nodes[index - 1].type === 'break') {
if (result.value) {
result.value = trim.left(result.value);
}
head = result.children && result.children[0];
if (head && head.value) {
head.value = trim.left(head.value);
}
}
values = values.concat(result);
}
}
return values;
}
/**
* Transform a `root`.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function root(h, node) {
return h.wrap(node, u('root', wrapInLines(all(h, node))));
}
/**
* Transform a block quote.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function blockquote(h, node) {
return h(node, 'blockquote', wrapInLines(all(h, node), true));
}
/**
* Transform an inline footnote.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function footnote(h, node) {
var footnotes = h.footnotes;
var index = -1;
var length = footnotes.length;
var identifiers = [];
var identifier;
while (++index < length) {
identifiers[index] = footnotes[index].identifier;
}
identifier = 1;
while (identifiers.indexOf(String(identifier)) !== -1) {
identifier++;
}
identifier = String(identifier);
footnotes.push({
type: 'footnoteDefinition',
identifier: identifier,
children: node.children,
position: node.position
});
return footnoteReference(h, {
type: 'footnoteReference',
identifier: identifier,
position: node.position
});
}
/**
* Transform a list.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function list(h, node) {
var props = {};
if (typeof node.start === 'number' && node.start !== 1) {
props.start = node.start;
}
return h(
node,
node.ordered ? 'ol' : 'ul',
props,
wrapInLines(all(h, node), true)
);
}
/**
* Transform a list-item.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @param {Node} parent - Parent of `node`.
* @return {Node} - HAST node.
*/
function listItem(h, node, parent) {
var head = node.children[0];
var single;
var result;
var container;
single = (!parent || !parent.loose) &&
node.children.length === 1 &&
head.children;
result = all(h, single ? head : node);
if (typeof node.checked === 'boolean') {
if (!single && head.type !== 'paragraph') {
result.unshift(h(null, 'p', []));
}
container = single ? result : result[0].children;
if (container.length) {
container.unshift(u('text', ' '));
}
container.unshift(h(null, 'input', {
type: 'checkbox',
checked: node.checked,
disabled: true
}));
}
if (!single && result.length) {
result = wrapInLines(result, true);
}
return h(node, 'li', result);
}
/**
* Transform a heading.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function heading(h, node) {
return h(node, 'h' + node.depth, all(h, node));
}
/**
* Transform a paragraph.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function paragraph(h, node) {
return h(node, 'p', all(h, node));
}
/**
* Transform a code block.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function code(h, node) {
var value = node.value ? detab(node.value + '\n') : '';
var lang = node.lang && node.lang.match(/^[^\ \t]+(?=[\ \t]|$)/);
var props = {};
if (lang) {
props.className = ['language-' + lang];
}
return h(node.position, 'pre', [
h(node, 'code', props, [u('text', value)])
]);
}
/**
* Transform a table.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function table(h, node) {
var rows = node.children;
var index = rows.length;
var align = node.align;
var alignLength = align.length;
var pos;
var result = [];
var row;
var out;
var name;
var cell;
var head;
var rest;
while (index--) {
row = rows[index].children;
name = index === 0 ? 'th' : 'td';
pos = alignLength;
out = [];
while (pos--) {
cell = row[pos];
out[pos] = h(cell, name, {
align: align[pos]
}, cell ? wrapInLines(all(h, cell)) : []);
}
result[index] = h(rows[index], 'tr', wrapInLines(out, true));
}
head = result[0].position;
rest = {
start: position.start(result[1]),
end: position.end(result[result.length - 1])
};
return h(node, 'table', wrapInLines([
h(head, 'thead', wrapInLines([result[0]], true)),
h(rest, 'tbody', wrapInLines(result.slice(1), true))
], true));
}
/**
* Transform a thematic break / horizontal rule.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function thematicBreak(h, node) {
return h(node, 'hr');
}
/**
* Transform inline code.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function inlineCode(h, node) {
return h(node, 'code', [u('text', collapse(node.value))]);
}
/**
* Transform importance.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function strong(h, node) {
return h(node, 'strong', all(h, node));
}
/**
* Transform emphasis
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function emphasis(h, node) {
return h(node, 'em', all(h, node));
}
/**
* Transform deletions.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function strikethrough(h, node) {
return h(node, 'del', all(h, node));
}
/**
* Transform an inline break.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Array.<Node>} - HAST nodes.
*/
function hardBreak(h, node) {
return [h(node, 'br'), u('text', '\n')];
}
/**
* Transform a link.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function link(h, node) {
var props = {href: normalize(node.url)};
if (node.title != null) {
props.title = node.title
}
return h(node, 'a', props, all(h, node));
}
/**
* Transform an image.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function image(h, node) {
var props = {
src: normalize(node.url),
alt: node.alt
};
if (node.title != null) {
props.title = node.title
}
return h(node, 'img', props);
}
/**
* Transform a reference to a footnote.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function footnoteReference(h, node) {
var identifier = node.identifier;
return h(node.position, 'sup', { id: 'fnref-' + identifier }, [
h(node, 'a', {
href: '#fn-' + identifier,
className: ['footnote-ref']
}, [u('text', identifier)])
]);
}
/**
* Transform a reference to a link.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function linkReference(h, node) {
var def = h.definition(node.identifier);
var props = {
href: normalize((def && def.url) || '')
};
if (def && def.title != null) {
props.title = def.title;
}
return failsafe(h, node, def) || h(node, 'a', props, all(h, node));
}
/**
* Transform a reference to an image.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST node.
*/
function imageReference(h, node) {
var def = h.definition(node.identifier);
var props = {
src: normalize((def && def.url) || ''),
alt: node.alt
};
if (def && def.title != null) {
props.title = def.title;
}
return failsafe(h, node, def) || h(node, 'img', props);
}
/**
* Transform text.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node} - HAST text node.
*/
function text(h, node) {
return h.wrap(node, u('text', trimLines(node.value)));
}
/**
* Return either a `raw` node, in dangerous mode, or
* nothing.
*
* @param {Function} h - Hyperscript DSL.
* @param {Node} node - Node to compile.
* @return {Node|null} - Nothing.
*/
function html(h, node) {
if (h.dangerous) {
return h.wrap(node, u('raw', node.value));
}
return null;
}
/**
* Return nothing for nodes which are ignored.
*
* @return {null} - Nothing.
*/
function ignore() {
return null;
}
/* Handlers. */
handlers.root = root;
handlers.paragraph = paragraph;
handlers.blockquote = blockquote;
handlers.heading = heading;
handlers.code = code;
handlers.inlineCode = inlineCode;
handlers.yaml = ignore;
handlers.html = html;
handlers.list = list;
handlers.listItem = listItem;
handlers.table = table;
handlers.thematicBreak = thematicBreak;
handlers.break = hardBreak;
handlers.emphasis = emphasis;
handlers.strong = strong;
handlers.delete = strikethrough;
handlers.link = link;
handlers.image = image;
handlers.footnote = footnote;
handlers.linkReference = linkReference;
handlers.imageReference = imageReference;
handlers.footnoteReference = footnoteReference;
handlers.definition = ignore;
handlers.footnoteDefinition = ignore;
handlers.text = text;
/**
* Factory to transform.
*
* @param {Node} tree - MDAST tree.
* @param {Object?} options - Configuration.
* @return {Function} - Hyperscript-like DSL.
*/
function factory(tree, options) {
var dangerous = (options || {}).allowDangerousHTML;
/**
* Finalise the created of `right`, a HAST node, from
* `left`, an MDAST node.
*
* @param {Node} left - MDAST node.
* @param {Node} right - HAST node.
*/
function wrap(left, right) {
var data;
var ctx;
/* handle `data.hName`, `data.hProperties, `hChildren`. */
if (left && 'data' in left) {
data = left.data;
if (right.type === 'element' && data.hName) {
right.tagName = data.hName;
}
if (right.type === 'element' && data.hProperties) {
right.properties = xtend(right.properties, data.hProperties);
}
if (right.children && data.hChildren) {
right.children = data.hChildren;
}
}
ctx = left && left.position ? left : {position: left};
if (!position.generated(ctx)) {
right.position = {
start: position.start(ctx),
end: position.end(ctx)
};
}
return right;
}
/**
* Create an element for a `node`.
*
* @param {Node} node - MDAST node to compile for.
* @param {string} tagName - Proposed tag-name.
* @param {Object?} [props={}] - Properties.
* @param {Array.<Node>} children - HAST children.
*/
function h(node, tagName, props, children) {
if (
children == null &&
typeof props === 'object' &&
'length' in props
) {
children = props;
props = {};
}
return wrap(node, {
type: 'element',
tagName: tagName,
properties: props || {},
children: children || []
});
}
h.dangerous = dangerous;
h.definition = definitions(tree);
h.footnotes = [];
h.wrap = wrap;
visit(tree, 'footnoteDefinition', function (definition) {
h.footnotes.push(definition);
});
return h;
}
/**
* Transform `tree`, which is an MDAST node, to a HAST node.
*
* @param {Node} tree - MDAST Node.
* @param {Object} [options] - Configuration.
* @return {Node} - HAST Node.
*/
function toHAST(tree, options) {
var h = factory(tree, options)
var node = one(h, tree);
var footnotes = generateFootnotes(h);
if (node && node.children && footnotes) {
node.children = node.children.concat(u('text', '\n'), footnotes);
}
return node;
}
/* Expose. */
module.exports = toHAST;
module.exports = require('./lib/index.js');
{
"name": "mdast-util-to-hast",
"version": "1.0.0",
"version": "2.0.0",
"description": "Transform MDAST to HAST",

@@ -12,8 +12,6 @@ "license": "MIT",

"files": [
"lib",
"index.js"
],
"repository": {
"type": "git",
"url": "https://github.com/wooorm/mdast-util-to-hast.git"
},
"repository": "https://github.com/wooorm/mdast-util-to-hast",
"bugs": "https://github.com/wooorm/mdast-util-to-hast/issues",

@@ -26,3 +24,4 @@ "author": "Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)",

"collapse-white-space": "^1.0.0",
"detab": "^1.0.2",
"detab": "^2.0.0",
"has": "^1.0.1",
"mdast-util-definitions": "^1.1.1",

@@ -39,16 +38,8 @@ "normalize-uri": "^1.0.0",

"browserify": "^13.0.1",
"eslint": "^2.0.0",
"esmangle": "^1.0.1",
"istanbul": "^0.4.0",
"jscs": "^3.0.0",
"jscs-jsdoc": "^2.0.0",
"remark": "^5.0.1",
"remark-cli": "^1.0.0",
"remark-comment-config": "^4.0.0",
"remark-github": "^5.0.0",
"remark-lint": "^4.0.0",
"remark-usage": "^4.0.0",
"remark-validate-links": "^4.0.0",
"nyc": "^8.3.0",
"remark-cli": "^2.0.0",
"remark-preset-wooorm": "^1.0.0",
"tape": "^4.0.0",
"unist-util-inspect": "^4.0.0"
"xo": "^0.16.0"
},

@@ -60,9 +51,25 @@ "scripts": {

"build": "npm run build-md && npm run build-bundle && npm run build-mangle",
"lint-api": "eslint .",
"lint-style": "jscs --reporter inline .",
"lint": "npm run lint-api && npm run lint-style",
"test-api": "node test.js",
"test-coverage": "istanbul cover test.js",
"lint": "xo",
"test-api": "node test",
"test-coverage": "nyc --reporter lcov tape test/index.js",
"test": "npm run build && npm run lint && npm run test-coverage"
},
"xo": {
"space": true,
"rules": {
"guard-for-in": "off",
"eqeqeq": [
"off",
"allow-null"
],
"no-eq-null": "off"
},
"ignores": [
"mdast-util-to-hast.js"
]
},
"remarkConfig": {
"output": true,
"presets": "wooorm"
}
}
# mdast-util-to-hast [![Build Status][travis-badge]][travis] [![Coverage Status][codecov-badge]][codecov]
<!--lint disable heading-increment list-item-spacing-->
Transform [MDAST][] to [HAST][].

@@ -29,2 +27,3 @@

var hast = toHAST(remark().parse('## Hello **World**!'));
console.log(inspect(hast));
```

@@ -49,8 +48,7 @@

###### Parameters
###### `options.allowDangerousHTML`
* `node` ([`MDASTNode`][mdast]).
* `options.allowDangerousHTML` (`boolean`, default: `false`)
— Whether to allow `html` nodes and inject them as raw HTML.
Only do this when compiling later with `hast-util-to-html`.
Whether to allow `html` nodes and inject them as raw HTML (`boolean`,
default: `false`). Only do this when compiling later with
`hast-util-to-html`.

@@ -57,0 +55,0 @@ ###### Returns

<!--remark setext-->
<!--lint disable no-multiple-toplevel-headings -->
1.0.0 / 2016-06-18
==================