Skip to content

Commit

Permalink
Accept options as direct props
Browse files Browse the repository at this point in the history
  • Loading branch information
sibiraj-s committed Oct 28, 2021
1 parent de512f1 commit 5b8b370
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 59 deletions.
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ ReactDom.render(<Markdown># Hello world!</Markdown>, rootEl);
### Component Props

- **value** - A markdown string(markdown).
- **options** - See [Options](#Options)

### Options

- **baseURL** [`string`] - A prefix url for any relative link.
- **openLinksInNewTab** [`boolean`] - Attribute `target=_blank` will be added to link elements
- **langPrefix** [`string`] - A string to prefix the className in a `<code>` block. Useful for syntax highlighting. Defaults to `language-`.
Expand Down
30 changes: 8 additions & 22 deletions src/Markdown.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
import { createElement, Fragment } from 'react';
import { lexer } from 'marked';

import ReactParser, { defaultParserOptions } from './ReactParser';

const defaultLexerOptions = {
breaks: false,
gfm: true,
};

const defaultOptions = {
...defaultLexerOptions,
...defaultParserOptions,
};
import defaults from './defaults';
import ReactParser from './ReactParser';

const validateComponentProps = (props) => {
if (props.value && typeof props.value !== 'string') {
Expand All @@ -26,32 +17,27 @@ const validateComponentProps = (props) => {
const Markdown = (props) => {
validateComponentProps(props);

// assign default options
const options = { ...defaultOptions, ...props.options };

// lexer options
const lexerOptions = {
breaks: options.breaks,
gfm: options.gfm,
breaks: props.breaks,
gfm: props.gfm,
};

// convert input markdown into tokens
const tokens = lexer(props.value ?? props.children ?? '', lexerOptions);

// parser options
const parserOptions = {
baseURL: options.baseURL,
openLinksInNewTab: options.openLinksInNewTab,
langPrefix: options.langPrefix,
baseURL: props.baseURL,
openLinksInNewTab: props.openLinksInNewTab,
langPrefix: props.langPrefix,
};

const children = new ReactParser(parserOptions).parse(tokens);

return createElement(Fragment, null, children);
};

Markdown.defaultProps = {
options: defaultOptions,
};
Markdown.defaultProps = defaults;

export default Markdown;
8 changes: 2 additions & 6 deletions src/ReactParser.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import ReactRenderer from './ReactRenderer';
import { unescape, joinBase } from './helpers';

export const defaultParserOptions = {
baseURL: null,
openLinksInNewTab: true,
langPrefix: 'language-',
};
import defaults from './defaults';

class ReactParser {
constructor(options = defaultParserOptions) {
constructor(options = defaults) {
this.options = options;
this.renderer = new ReactRenderer();
}
Expand Down
9 changes: 9 additions & 0 deletions src/defaults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const defaults = {
breaks: false,
gfm: true,
baseURL: null,
openLinksInNewTab: true,
langPrefix: 'language-',
};

export default defaults;
7 changes: 3 additions & 4 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ declare module 'marked-react' {
import React from 'react';

export interface MarkdownOptions {
breaks?: boolean;
gfm?: boolean;
baseURL?: string;
openLinksInNewTab?: boolean;
langPrefix?: string;
breaks?: boolean;
gfm?: boolean;
}

interface Props {
interface Props extends MarkdownOptions {
value: string;
options: MarkdownOptions;
}

const Markdown: React.FC<Props>;
Expand Down
32 changes: 9 additions & 23 deletions tests/markdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,24 @@ const cases = [
markdown: '[Google](https://google.com)',
html: '<p><a href="https://google.com" target="_blank">Google</a></p>',
props: {
options: {
openLinksInNewTab: true,
},
openLinksInNewTab: true,
},
},
{
title: 'render links without target=_blank',
markdown: '[Google](https://google.com)',
html: '<p><a href="https://google.com">Google</a></p>',
props: {
options: {
openLinksInNewTab: false,
},
openLinksInNewTab: false,
},
},
{
title: 'add base url to the links for relative paths',
markdown: '[Google](file)',
html: '<p><a href="https://google.com/file">Google</a></p>',
props: {
options: {
baseURL: 'https://google.com',
openLinksInNewTab: false,
},
baseURL: 'https://google.com',
openLinksInNewTab: false,
},
},
{
Expand All @@ -80,9 +74,7 @@ const cases = [
markdown: '![Random Image](pic.png)',
html: '<p><img src="https://placeholder.com/pic.png" alt="Random Image"/></p>',
props: {
options: {
baseURL: 'https://placeholder.com',
},
baseURL: 'https://placeholder.com',
},
},
{
Expand Down Expand Up @@ -110,9 +102,7 @@ const cases = [
markdown: '```js\nconsole.log("Hello world!")\n```',
html: '<pre><code class="lang-js">console.log(&quot;Hello world!&quot;)</code></pre>',
props: {
options: {
langPrefix: 'lang-',
},
langPrefix: 'lang-',
},
},
{
Expand Down Expand Up @@ -155,10 +145,8 @@ const cases = [
markdown: 'Hello\nWorld!\n',
html: '<p>Hello<br/>World!</p>',
props: {
options: {
breaks: true,
gfm: true,
},
breaks: true,
gfm: true,
},
},
{
Expand All @@ -181,9 +169,7 @@ const cases = [
markdown: '- [x] checked\n- [ ] unchecked',
html: '<ul><li>[x] checked</li><li>[ ] unchecked</li></ul>',
props: {
options: {
gfm: false,
},
gfm: false,
},
},
];
Expand Down

0 comments on commit 5b8b370

Please sign in to comment.