diff --git a/src/__snapshots__/index.test.js.snap b/src/__snapshots__/index.test.js.snap index a46d0a0..609c6a7 100644 --- a/src/__snapshots__/index.test.js.snap +++ b/src/__snapshots__/index.test.js.snap @@ -3,9 +3,7 @@ exports[`should allow injecting context to components 1`] = `
-
- bar -
+ bar
`; @@ -18,7 +16,38 @@ exports[`should allow injecting context to elements 1`] = ` `; -exports[`should allow overriding code element with components version 1`] = ` +exports[`should allow overriding block code element 1`] = ` +
+
+ js + : + code +
+
+`; + +exports[`should allow overriding block code element with components version 1`] = ` +
+
+ js + : + code +
+
+`; + +exports[`should allow overriding inline code element 1`] = ` +
+

+ Hello +

+ code +
+

+
+`; + +exports[`should allow overriding inline code element with components version 1`] = `

Hello @@ -61,9 +90,7 @@ exports[`should be able to compile codespans 1`] = ` exports[`should be able to compile components 1`] = `

-
- mip -
+ mip
`; @@ -71,9 +98,7 @@ exports[`should be able to compile components 1`] = ` exports[`should be able to compile components using marksy language 1`] = `
-
- mip -
+ mip
`; @@ -118,9 +143,7 @@ exports[`should be able to compile html 1`] = ` exports[`should be able to compile html as components 1`] = `
-
- hello -
+ hello
`; @@ -326,14 +349,12 @@ exports[`should be able to compile text 1`] = ` exports[`should be able to inline components 1`] = `
-
-

- Hello there -

- Wuuut -
-

-
+

+ Hello there +

+ Wuuut +
+

`; diff --git a/src/components.js b/src/components.js index 073c726..bc6100c 100644 --- a/src/components.js +++ b/src/components.js @@ -1,17 +1,10 @@ -import createRenderer from './createRenderer'; +import createRenderer, {codeRenderer} from './createRenderer'; import marked from 'marked'; import {transform} from 'babel-standalone'; export function marksy (options = {}) { options.components = options.components || {}; - function CodeComponent (props) { - return options.createElement('pre', null, options.createElement('code', { - className: `language-${props.language}`, - dangerouslySetInnerHTML: {__html: options.highlight ? options.highlight(props.language, props.code) : props.code} - })) - } - const tracker = { tree: null, elements: null, @@ -41,13 +34,7 @@ export function marksy (options = {}) { if (language === 'marksy') { return renderer.html(code) } else { - const elementId = tracker.nextElementId++; - - tracker.elements[elementId] = options.createElement((options.elements && options.elements.code) || CodeComponent, {key: elementId, code, language}); - - tracker.tree.push(tracker.elements[elementId]); - - return `{{${elementId}}}`; + return codeRenderer(tracker, options)(code, language); } } }) diff --git a/src/createRenderer.js b/src/createRenderer.js index b1460ad..b1bc1c7 100644 --- a/src/createRenderer.js +++ b/src/createRenderer.js @@ -1,6 +1,28 @@ import marked from 'marked'; import he from 'he'; +export function codeRenderer(tracker, options) { + function CodeComponent (props) { + return options.createElement('pre', null, options.createElement('code', { + className: `language-${props.language}`, + dangerouslySetInnerHTML: {__html: options.highlight ? options.highlight(props.language, props.code) : props.code} + })) + } + + return function(code, language) { + const elementId = tracker.nextElementId++; + + tracker.elements[elementId] = options.createElement( + (options.elements && options.elements.code) || CodeComponent, + {key: elementId, code, language} + ); + + tracker.tree.push(tracker.elements[elementId]); + + return `{{${elementId}}}`; + } +} + export default function createRenderer (tracker, options, overrides = {}) { const renderer = new marked.Renderer(); @@ -32,39 +54,26 @@ export default function createRenderer (tracker, options, overrides = {}) { return extractedElements; } - function addElement (tag, props = {}, children) { + function addElement (tag, props = {}, children, type = tag) { const elementId = tracker.nextElementId++; let inlineContent = null; + const elementType = options.elements && (options.elements[type] || options.elements[tag]) + if (children) { inlineContent = Array.isArray(children) ? children.map(populateInlineContent) : populateInlineContent(children) } - tracker.elements[elementId] = options.createElement((options.elements && options.elements[tag]) || tag, Object.assign({ + tracker.elements[elementId] = options.createElement(elementType || tag, Object.assign({ key: elementId, - }, props, options.elements && options.elements[tag] ? {context: tracker.context} : {}), inlineContent); + }, props, elementType ? {context: tracker.context} : {}), inlineContent); tracker.tree.push(tracker.elements[elementId]); return `{{${elementId}}}`; } - renderer.code = overrides.code || function (code, language) { - const elementId = tracker.nextElementId++; - - function CodeComponent () { - return options.createElement('pre', null, options.createElement('code', { - className: `language-${language}`, - dangerouslySetInnerHTML: {__html: options.highlight ? options.highlight(language, code) : code} - })) - } - - tracker.elements[elementId] = options.createElement(CodeComponent, {key: elementId}); - - tracker.tree.push(tracker.elements[elementId]); - - return `{{${elementId}}}`; - }; + renderer.code = overrides.code || codeRenderer(tracker, options); renderer.html = overrides.html || function (html) { const elementId = tracker.nextElementId++; @@ -172,7 +181,7 @@ export default function createRenderer (tracker, options, overrides = {}) { } renderer.codespan = overrides.codespan || function (text) { - return addElement('code', null, text) + return addElement('code', null, text, 'codespan') } renderer.image = overrides.image || function (href, title, text) { diff --git a/src/index.test.js b/src/index.test.js index 835711f..e71cfb4 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -380,12 +380,30 @@ it('should be able to inline components', () => { expect(tree).toMatchSnapshot(); }); -it('should allow overriding code element with components version', () => { +it('should allow overriding inline code element', () => { + const compile = marksy({ + createElement, + elements: { + codespan({children}) { + return
{children}
+ } + } + }); + const compiled = compile('Hello `code`'); + + const tree = renderer.create( + {compiled.tree} + ).toJSON(); + + expect(tree).toMatchSnapshot(); +}); + +it('should allow overriding inline code element with components version', () => { const compile = marksyComponents({ createElement, elements: { - code() { - return
code
+ codespan({children}) { + return
{children}
} } }); @@ -398,6 +416,43 @@ it('should allow overriding code element with components version', () => { expect(tree).toMatchSnapshot(); }); +it('should allow overriding block code element', () => { + const compile = marksy({ + createElement, + elements: { + code({language, code}) { + console.log(language, code) + return
{language}: {code}
+ } + } + }); + const compiled = compile('```js\ncode\n```'); + + const tree = renderer.create( + {compiled.tree} + ).toJSON(); + + expect(tree).toMatchSnapshot(); +}); + +it('should allow overriding block code element with components version', () => { + const compile = marksyComponents({ + createElement, + elements: { + code({language, code}) { + return
{language}: {code}
+ } + } + }); + const compiled = compile('```js\ncode\n```'); + + const tree = renderer.create( + {compiled.tree} + ).toJSON(); + + expect(tree).toMatchSnapshot(); +}); + it('should highlight code with highlight.js', () => { const compile = marksy({ createElement,