all files / react-showdown/ index.js

100% Statements 28/28
100% Branches 13/13
100% Functions 6/6
100% Lines 28/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53                10×   10×   10× 10×     10× 31× 15× 15× 16× 15×         10× 22× 31×   31×       10×          
 
var React = require('react');
var showdown  = require('showdown');
var cheerio = require('cheerio');
 
/**
 * ReactShowdown can converts markdown to react elements.
 *
 * Example: new ReactShowdown().convert(markdown)
 */
module.exports = function ReactShowdown(options) {
	'use strict';
	var self = this;
 
	this._converter = new showdown.Converter(options && options.converter);
 
	this._components = {};
	for (var key in (options && options.components || {})) {
		this._components[key.toLowerCase()] = options.components[key];
	}
 
	this._mapElement = function(element) {
		if (element.type === 'tag') {
			var component = this._components[element.name] || element.name;
			return React.createElement(component, element.attribs, this._mapElements(element.children));
		} else if (element.type === 'text') {
			return element.data;
		} else {
			console.warn('Warning: Could not map element with type ' + element.type + ' yet.');
			return null;
		}
	};
 
	this._mapElements = function(elements) {
		return React.Children.toArray(elements.map(function(element) {
			return self._mapElement(element);
		}).filter(function(element) {
			return element;
		}));
	}
 
	this.convert = function(markdown) {
		var html = this._converter.makeHtml(markdown);
		var root = cheerio.load(html).root()[0];
		var reactElements = this._mapElements(root.children);
		if (reactElements.length === 1) {
			return reactElements[0];
		} else {
			return React.createElement('div', null, reactElements);
		}
	};
}