Commit 043a8f97 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch 'setup-initial-parser' into 'master'

Set up initial GFM parser

See merge request gitlab-org/gitlab!83294
parents 6510991f 5fc15f3a
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeRaw from 'rehype-raw';
const createParser = () => {
return unified().use(remarkParse).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeRaw);
};
const compilerFactory = (renderer) =>
function compiler() {
Object.assign(this, {
Compiler(tree) {
return renderer(tree);
},
});
};
/**
* Parses a Markdown string and provides the result Abstract
* Syntax Tree (AST) to a renderer function to convert the
* tree in any desired representation
*
* @param {String} params.markdown Markdown to parse
* @param {(tree: MDast -> any)} params.renderer A function that accepts mdast
* AST tree and returns an object of any type that represents the result of
* rendering the tree. See the references below to for more information
* about MDast.
*
* MDastTree documentation https://github.com/syntax-tree/mdast
* @returns {Promise<any>} Returns a promise with the result of rendering
* the MDast tree
*/
export const render = async ({ markdown, renderer }) => {
const { value } = await createParser().use(compilerFactory(renderer)).process(markdown);
return value;
};
...@@ -106,6 +106,45 @@ module.exports = (path, options = {}) => { ...@@ -106,6 +106,45 @@ module.exports = (path, options = {}) => {
return '<rootDir>/coverage-frontend/'; return '<rootDir>/coverage-frontend/';
}; };
const gfmParserDependencies = [
'rehype-.*',
'remark-.*',
'hast*',
'unist.*',
'mdast-util-.*',
'micromark.*',
'vfile.*',
'bail',
'trough',
'unified',
'is-plain-obj',
'decode-named-character-reference',
'character-entities*',
'property-information',
'space-separated-tokens',
'comma-separated-tokens',
'web-namespaces',
'zwitch',
'html-void-elements',
'ccount',
'escape-string-regexp',
];
const transformIgnoreNodeModules = [
'@gitlab/ui',
'@gitlab/favicon-overlay',
'bootstrap-vue',
'three',
'monaco-editor',
'monaco-yaml',
'fast-mersenne-twister',
'prosemirror-markdown',
'fault',
'dateformat',
'lowlight',
...gfmParserDependencies,
];
return { return {
clearMocks: true, clearMocks: true,
testMatch, testMatch,
...@@ -130,9 +169,7 @@ module.exports = (path, options = {}) => { ...@@ -130,9 +169,7 @@ module.exports = (path, options = {}) => {
'^.+\\.yml$': './spec/frontend/__helpers__/yaml_transformer.js', '^.+\\.yml$': './spec/frontend/__helpers__/yaml_transformer.js',
'^.+\\.(md|zip|png)$': 'jest-raw-loader', '^.+\\.(md|zip|png)$': 'jest-raw-loader',
}, },
transformIgnorePatterns: [ transformIgnorePatterns: [`node_modules/(?!(${transformIgnoreNodeModules.join('|')}))`],
'node_modules/(?!(@gitlab/ui|@gitlab/favicon-overlay|bootstrap-vue|three|monaco-editor|monaco-yaml|fast-mersenne-twister|prosemirror-markdown|dateformat|lowlight|fault)/)',
],
timers: 'fake', timers: 'fake',
testEnvironment: '<rootDir>/spec/frontend/environment.js', testEnvironment: '<rootDir>/spec/frontend/environment.js',
testEnvironmentOptions: { testEnvironmentOptions: {
......
import { render } from '~/lib/gfm';
describe('gfm', () => {
describe('render', () => {
it('processes Commonmark and provides an ast to the renderer function', async () => {
let result;
await render({
markdown: 'This is text',
renderer: (tree) => {
result = tree;
},
});
expect(result.type).toBe('root');
});
it('transforms raw HTML into individual nodes in the AST', async () => {
let result;
await render({
markdown: '<strong>This is bold text</strong>',
renderer: (tree) => {
result = tree;
},
});
expect(result.children[0].children[0]).toMatchObject({
type: 'element',
tagName: 'strong',
properties: {},
});
});
it('returns the result of executing the renderer function', async () => {
const result = await render({
markdown: '<strong>This is bold text</strong>',
renderer: () => {
return 'rendered tree';
},
});
expect(result).toBe('rendered tree');
});
});
});
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment