diff --git a/packages/draft-js-export-markdown/src/__tests__/stateToMarkdown-test.js b/packages/draft-js-export-markdown/src/__tests__/stateToMarkdown-test.js index 0e30c77f..cd92cdff 100644 --- a/packages/draft-js-export-markdown/src/__tests__/stateToMarkdown-test.js +++ b/packages/draft-js-export-markdown/src/__tests__/stateToMarkdown-test.js @@ -20,18 +20,20 @@ let testCases = testCasesRaw .split(SEP) .map((text) => { let lines = text.split('\n'); - let description = lines.shift().trim(); - let state = JSON.parse(lines[0]); - let markdown = lines.slice(1).join('\n'); - return {description, state, markdown}; + let [description, config] = lines.shift().split('|'); + description = description.trim(); + let options = config ? JSON.parse(config.trim()) : undefined; + let state = JSON.parse(lines.shift()); + let markdown = lines.join('\n'); + return {description, state, markdown, options}; }); describe('stateToMarkdown', () => { testCases.forEach((testCase) => { - let {description, state, markdown} = testCase; + let {description, state, markdown, options} = testCase; it(`should render ${description}`, () => { let contentState = convertFromRaw(state); - expect(stateToMarkdown(contentState)).toBe(markdown + '\n'); + expect(stateToMarkdown(contentState, options)).toBe(markdown + '\n'); }); }); }); diff --git a/packages/draft-js-export-markdown/src/stateToMarkdown.js b/packages/draft-js-export-markdown/src/stateToMarkdown.js index eef9de4f..fafb3079 100644 --- a/packages/draft-js-export-markdown/src/stateToMarkdown.js +++ b/packages/draft-js-export-markdown/src/stateToMarkdown.js @@ -9,10 +9,18 @@ import { import type {ContentState, ContentBlock} from 'draft-js'; +type Options = { + gfm?: ?boolean; +}; + const {BOLD, CODE, ITALIC, STRIKETHROUGH, UNDERLINE} = INLINE_STYLE; const CODE_INDENT = ' '; +const defaultOptions: Options = { + gfm: false, +}; + class MarkupGenerator { blocks: Array; contentState: ContentState; @@ -20,9 +28,11 @@ class MarkupGenerator { output: Array; totalBlocks: number; listItemCounts: Object; + options: Options; - constructor(contentState: ContentState) { + constructor(contentState: ContentState, options?: Options) { this.contentState = contentState; + this.options = options || defaultOptions; } generate(): string { @@ -120,7 +130,13 @@ class MarkupGenerator { } case BLOCK_TYPE.CODE: { this.insertLineBreaks(1); - this.output.push(CODE_INDENT + this.renderBlockContent(block) + '\n'); + if (this.options.gfm) { + this.output.push('```\n'); + this.output.push(this.renderBlockContent(block) + '\n'); + this.output.push('```\n'); + } else { + this.output.push(CODE_INDENT + this.renderBlockContent(block) + '\n'); + } break; } default: { @@ -257,6 +273,9 @@ function escapeTitle(text) { return text.replace(/"/g, '\\"'); } -export default function stateToMarkdown(content: ContentState): string { - return new MarkupGenerator(content).generate(); +export default function stateToMarkdown( + content: ContentState, + options?: Options, +): string { + return new MarkupGenerator(content, options).generate(); } diff --git a/packages/draft-js-export-markdown/test/test-cases.txt b/packages/draft-js-export-markdown/test/test-cases.txt index b19e54fe..6e1e6cf4 100644 --- a/packages/draft-js-export-markdown/test/test-cases.txt +++ b/packages/draft-js-export-markdown/test/test-cases.txt @@ -44,3 +44,21 @@ An ordered list: 1. One 2. Two + +>> Code block +{"entityMap":{},"blocks":[{"text":"A code block:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"text":"let x = 1;","type":"code-block","depth":0,"inlineStyleRanges":[{"offset":0,"length":10,"style":"CODE"}],"entityRanges":[],"data":{}},{"text":"Great!","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}]} +A code block: + + let x = 1; + +Great! + +>> Code block with fence | {"gfm": true} +{"entityMap":{},"blocks":[{"text":"A code block:","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"text":"let x = 1;","type":"code-block","depth":0,"inlineStyleRanges":[{"offset":0,"length":10,"style":"CODE"}],"entityRanges":[],"data":{}},{"text":"Great!","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}]} +A code block: + +``` +let x = 1; +``` + +Great!