From b60062386f556f8e7f1cf35b2c3ecb5aa2c8e7b2 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 11 Jan 2019 09:24:15 -0800 Subject: [PATCH 1/3] [export-markdown] Support code fence --- .../src/stateToMarkdown.js | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/draft-js-export-markdown/src/stateToMarkdown.js b/packages/draft-js-export-markdown/src/stateToMarkdown.js index eef9de4f..e159cc81 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 = { + codeFence?: ?boolean; +}; + const {BOLD, CODE, ITALIC, STRIKETHROUGH, UNDERLINE} = INLINE_STYLE; const CODE_INDENT = ' '; +const defaultOptions: Options = { + codeFence: 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.codeFence) { + 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(); } From 76dce254c5358c5fcb7db336d8a7c391a7363c13 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 11 Jan 2019 09:48:23 -0800 Subject: [PATCH 2/3] Add tests --- .../src/__tests__/stateToMarkdown-test.js | 14 ++++++++------ .../test/test-cases.txt | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) 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/test/test-cases.txt b/packages/draft-js-export-markdown/test/test-cases.txt index b19e54fe..fad31cf7 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 | {"codeFence": 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! From c6b9f855cb8178d8291c680d54b1ca6fb9ac668b Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 13 Jan 2019 22:19:23 -0800 Subject: [PATCH 3/3] codeFence -> gfm --- packages/draft-js-export-markdown/src/stateToMarkdown.js | 6 +++--- packages/draft-js-export-markdown/test/test-cases.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/draft-js-export-markdown/src/stateToMarkdown.js b/packages/draft-js-export-markdown/src/stateToMarkdown.js index e159cc81..fafb3079 100644 --- a/packages/draft-js-export-markdown/src/stateToMarkdown.js +++ b/packages/draft-js-export-markdown/src/stateToMarkdown.js @@ -10,7 +10,7 @@ import { import type {ContentState, ContentBlock} from 'draft-js'; type Options = { - codeFence?: ?boolean; + gfm?: ?boolean; }; const {BOLD, CODE, ITALIC, STRIKETHROUGH, UNDERLINE} = INLINE_STYLE; @@ -18,7 +18,7 @@ const {BOLD, CODE, ITALIC, STRIKETHROUGH, UNDERLINE} = INLINE_STYLE; const CODE_INDENT = ' '; const defaultOptions: Options = { - codeFence: false, + gfm: false, }; class MarkupGenerator { @@ -130,7 +130,7 @@ class MarkupGenerator { } case BLOCK_TYPE.CODE: { this.insertLineBreaks(1); - if (this.options.codeFence) { + if (this.options.gfm) { this.output.push('```\n'); this.output.push(this.renderBlockContent(block) + '\n'); this.output.push('```\n'); diff --git a/packages/draft-js-export-markdown/test/test-cases.txt b/packages/draft-js-export-markdown/test/test-cases.txt index fad31cf7..6e1e6cf4 100644 --- a/packages/draft-js-export-markdown/test/test-cases.txt +++ b/packages/draft-js-export-markdown/test/test-cases.txt @@ -53,7 +53,7 @@ A code block: Great! ->> Code block with fence | {"codeFence": true} +>> 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: