babel-plugin-react-code-block
Version:
Display React functional examples with source code.
60 lines (47 loc) • 2.09 kB
JavaScript
;
var prettier = require('prettier'); // eslint-disable-next-line flowtype/no-weak-types
module.exports = function (_ref, options) {
var t = _ref.types,
template = _ref.template;
if (typeof options.component !== 'string') {
throw new TypeError('babel-plugin-react-code-block expects component option to be present and to be a string');
}
return {
visitor: {
JSXElement: function JSXElement(path, stats) {
var _path$node = path.node,
children = _path$node.children,
openingElement = _path$node.openingElement;
var attributes = openingElement.attributes;
var name = openingElement.name.name;
if (name === options.component) {
if (children.length) {
var start = children[0].start;
var end = children[children.length - 1].end;
var code = stats.file.code.slice(start, end); // eslint-disable-next-line flowtype/no-weak-types
var _options = {
parser: 'babylon'
};
var maxLineLengthAttribute = attributes.find(function (attr) {
return attr.name.name === 'maxLineLength';
});
if (maxLineLengthAttribute) {
_options.printWidth = maxLineLengthAttribute.value.expression.value;
}
var lines = prettier.format("<div>" + code + "</div>", _options).split('\n'); // Remove wrapping div that we added to keep prettier from breaking
lines.pop(); // Remove empty newline
lines.pop(); // Remove </div>
lines.shift(); // Remove <div>
// Trim two spaces from each line so everything is at the correct
// indentation. The join is an escaped newline character so newlines
// end up in the final DOM.
var finalCode = lines.map(function (line) {
return line.substr(2);
}).join('\\n');
attributes.push(t.jSXAttribute(t.jSXIdentifier('code'), t.stringLiteral(finalCode)));
}
}
}
}
};
};