-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Export the markdown-to-HTML utilities separately from the React components, so that they can be used by consumers that need to convert Zooniverse-flavoured markdown to HTML strings.
- Loading branch information
1 parent
a2da0a2
commit fd7ce1f
Showing
7 changed files
with
161 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
export { default as Markdown } from './components/markdown'; | ||
export { default as MarkdownEditor } from './components/markdown-editor'; | ||
export { default as MarkdownHelp } from './components/markdown-help'; | ||
export * as utils from './lib/utils'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import MarkdownIt from 'markdown-it'; | ||
import MarkdownItContainer from 'markdown-it-container'; | ||
import markdownEmoji from 'markdown-it-emoji'; | ||
import markdownSub from 'markdown-it-sub'; | ||
import markdownSup from 'markdown-it-sup'; | ||
import markdownFootnote from 'markdown-it-footnote'; | ||
import markdownImsize from 'markdown-it-imsize'; | ||
import markdownVideo from 'markdown-it-video'; | ||
import markdownTableOfContents from 'markdown-it-table-of-contents'; | ||
import markdownAnchor from 'markdown-it-anchor'; | ||
import html5Embed from 'markdown-it-html5-embed'; | ||
import twemoji from '@twemoji/api'; | ||
|
||
import markdownNewTab from '../lib/links-in-new-tabs'; | ||
import relNofollow from '../lib/links-rel-nofollow'; | ||
import replaceSymbols from '../lib/default-transformer'; | ||
|
||
let counter = 0; | ||
|
||
export function emojify(input) { | ||
return twemoji.parse(input); | ||
} | ||
|
||
export function markdownz() { | ||
return new MarkdownIt({ linkify: true, breaks: true }) | ||
.use(markdownEmoji) | ||
.use(markdownSub) | ||
.use(markdownSup) | ||
.use(markdownFootnote) | ||
.use(markdownImsize) | ||
.use(markdownNewTab) | ||
.use(markdownVideo) | ||
.use(markdownAnchor) | ||
.use(markdownTableOfContents) | ||
.use(MarkdownItContainer, 'partners') | ||
.use(MarkdownItContainer, 'attribution') | ||
.use(html5Embed, {}); | ||
} | ||
|
||
const baseRenderer = markdownz(); | ||
const noFollowRenderer = markdownz().use(relNofollow); | ||
|
||
export function renderer({ relNoFollow = false }) { | ||
return relNoFollow ? noFollowRenderer : baseRenderer; | ||
} | ||
|
||
export function markdownify({ | ||
idPrefix, | ||
inline = false, | ||
input, | ||
relNoFollow = false | ||
}) { | ||
counter += 1; | ||
const id = idPrefix || (Date.now().toString(16) + counter); | ||
const env = { docId: id }; | ||
if (inline) { | ||
return renderer({ relNoFollow }).renderInline(input, env); | ||
} | ||
|
||
return renderer({ relNoFollow }).render(input, env); | ||
} | ||
|
||
export function getHtml({ | ||
baseURI, | ||
content, | ||
idPrefix, | ||
inline = false, | ||
project, | ||
relNoFollow = false, | ||
transform = replaceSymbols | ||
}) { | ||
let input = content; | ||
try { | ||
if (typeof transform === 'function') { | ||
input = transform(content, { project, baseURI }); | ||
} | ||
|
||
const html = markdownify({ idPrefix, inline, input, relNoFollow }); | ||
return emojify(html); | ||
} catch (e) { | ||
return content; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import TestUtils from 'react-dom/test-utils'; | ||
import * as utils from '../src/lib/utils'; | ||
|
||
describe('Utilities', () => { | ||
describe('#markdownify', () => { | ||
it('renders markdown', () => { | ||
const md = utils.markdownify({ input: '# test header' }); | ||
expect(md).to.equal('<h1 id="test-header" tabindex="-1">test header</h1>\n'); | ||
}); | ||
|
||
it('opens links in a new tab when prefixed by +tab+', () => { | ||
const md = utils.markdownify({ input: '[A link](+tab+http://www.google.com)' }); | ||
expect(md).to.equal('<p><a href="http://www.google.com" target="_blank" rel="noopener nofollow noreferrer">A link</a></p>\n'); | ||
}); | ||
}); | ||
|
||
describe('#getHtml', () => { | ||
const errorTransform = () => { | ||
throw new Error('fail'); | ||
}; | ||
|
||
it('returns the formatted html', () => { | ||
let html = utils.getHtml({ content: 'Test text' }); | ||
expect(html).to.equal('<p>Test text</p>\n'); | ||
}); | ||
|
||
it('renders bare child content on error', () => { | ||
const html = utils.getHtml({ content: 'Test text', transform: errorTransform }); | ||
expect(html).to.equal('Test text'); | ||
}); | ||
|
||
it('uses relNofollow when passed as a prop', () => { | ||
expect(utils.getHtml({ content: '[Test](link)', relNoFollow: true })).to.equal('<p><a href="link" rel="nofollow noreferrer">Test</a></p>\n'); | ||
}); | ||
|
||
it('doesn\'t use relNofollow when not passed as a prop', () => { | ||
expect(utils.getHtml({ content: '[Test](link)' })).to.equal('<p><a href="link">Test</a></p>\n'); | ||
}); | ||
}); | ||
}); |