Skip to content

Commit a1ad000

Browse files
author
Rose
authored
Merge pull request Rosey#112 from danielsnider/perserve-newline-off-by-one-fix
Off by one fix for preserveNewlines
2 parents f7b1f41 + edeb6bb commit a1ad000

5 files changed

Lines changed: 69 additions & 14 deletions

File tree

src/draft-to-markdown.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,11 @@ function renderBlock(block, index, rawDraftObject, options) {
462462
markdownString += '\n';
463463
} else if (rawDraftObject.blocks[index + 1]) {
464464
if (rawDraftObject.blocks[index].text) {
465-
if ((type === 'unstyled' || type === 'blockquote') && options.preserveNewlines
466-
|| SingleNewlineAfterBlock.indexOf(type) !== -1
465+
if (SingleNewlineAfterBlock.indexOf(type) !== -1
467466
&& SingleNewlineAfterBlock.indexOf(rawDraftObject.blocks[index + 1].type) === -1) {
468467
markdownString += '\n\n';
469-
} else if (!options.preserveNewlines
470-
|| (rawDraftObject.blocks[index + 1] && !rawDraftObject.blocks[index + 1].text && rawDraftObject.blocks[index + 1].type === 'unstyled' && options.preserveNewlines)) {
471-
// 2 newlines if not preserving OR if this block is styled but the next block is a blank newline
468+
} else if (!options.preserveNewlines) {
469+
// 2 newlines if not preserving
472470
markdownString += '\n\n';
473471
} else {
474472
markdownString += '\n';

src/markdown-to-draft.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ function markdownToDraft(string, options = {}) {
223223
var entityMap = {}; // entitymap will be returned as part of the final draftjs raw object
224224
var parsedData = md.parse(string, {}); // remarkable js takes markdown and makes it an array of style objects for us to easily parse
225225
var currentListType = null; // Because of how remarkable's data is formatted, we need to cache what kind of list we're currently dealing with
226-
var previousBlockEndingLine = 1;
226+
var previousBlockEndingLine = 0;
227227

228228
// Allow user to define custom BlockTypes and Entities if they so wish
229229
const BlockTypes = Object.assign({}, DefaultBlockTypes, options.blockTypes || {});
@@ -277,20 +277,18 @@ function markdownToDraft(string, options = {}) {
277277
if (block && options.preserveNewlines) {
278278
// Re: previousBlockEndingLine.... omg.
279279
// So remarkable strips out empty newlines and doesn't make any entities to parse to restore them
280-
// the only solution I could find is that there's a 2-value array on each block item called "lines" which is the start end line of the block element.
280+
// the only solution I could find is that there's a 2-value array on each block item called "lines" which is the start and end line of the block element.
281281
// by keeping track of the PREVIOUS block element ending line and the NEXT block element starting line, we can find the difference between the new lines and insert
282282
// an appropriate number of extra paragraphs to re-create those newlines in draftjs.
283283
// This is probably my least favourite thing in this file, but not sure what could be better.
284-
if (previousBlockEndingLine) {
285-
var totalEmptyParagraphsToCreate = item.lines[0] - previousBlockEndingLine;
286-
for (var i = 0; i < totalEmptyParagraphsToCreate; i++) {
287-
blocks.push(DefaultBlockTypes.paragraph_open());
288-
}
284+
var totalEmptyParagraphsToCreate = item.lines[0] - previousBlockEndingLine;
285+
for (var i = 0; i < totalEmptyParagraphsToCreate; i++) {
286+
blocks.push(DefaultBlockTypes.paragraph_open());
289287
}
290288
}
291289

292290
if (block) {
293-
previousBlockEndingLine = item.lines[1] + 1;
291+
previousBlockEndingLine = item.lines[1];
294292
blocks.push(block);
295293
}
296294
}

test/draft-to-markdown.spec.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ describe('draftToMarkdown', function () {
5252
expect(markdown).toEqual('**_bold/italic_** plain');
5353
});
5454

55+
it('handles unstyled blank lines', function () {
56+
// draft-js can have blank lines that have block styles.
57+
// This would result in double-application of markdown line prefixes.
58+
59+
/* eslint-disable */
60+
const rawObject = {"blocks":[{"key":"8i76c","text":"a","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"3htgs","text":"b","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"c46o4","text":"","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"l5v1","text":"c","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"cbsdo","text":"","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"9i2da","text":"","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"9mr0v","text":"d","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}}],"entityMap":{}}
61+
/* eslint-enable */
62+
63+
var markdown = draftToMarkdown(rawObject);
64+
expect(markdown).toEqual('a\n\nb\n\nc\n\nd');
65+
66+
markdown = draftToMarkdown(rawObject, {preserveNewlines: true});
67+
expect(markdown).toEqual('a\nb\n\nc\n\n\nd');
68+
});
69+
5570
it('handles blank lines with styled block types', function () {
5671
// draft-js can have blank lines that have block styles.
5772
// This would result in double-application of markdown line prefixes.
@@ -79,7 +94,7 @@ describe('draftToMarkdown', function () {
7994
expect(markdown).toEqual('> one\n> \n> blockquote\n\nHello :)');
8095

8196
markdown = draftToMarkdown(rawObject, {preserveNewlines: true});
82-
expect(markdown).toEqual('> one\n> \n> blockquote\n\nHello :)');
97+
expect(markdown).toEqual('> one\n> \n> blockquote\nHello :)');
8398
});
8499
});
85100

test/idempotency.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ describe('idempotency', function () {
2121
var markdownFromDraft = draftToMarkdown(draftJSObject, {preserveNewlines: true});
2222

2323
expect(markdownFromDraft).toEqual(markdownString);
24+
25+
markdownString = 'a\nb\n\nc\n\n\nd';
26+
draftJSObject = markdownToDraft(markdownString, {preserveNewlines: true});
27+
markdownFromDraft = draftToMarkdown(draftJSObject, {preserveNewlines: true});
28+
29+
expect(markdownFromDraft).toEqual(markdownString);
30+
31+
markdownString = '\n\na';
32+
draftJSObject = markdownToDraft(markdownString, {preserveNewlines: true});
33+
markdownFromDraft = draftToMarkdown(draftJSObject, {preserveNewlines: true});
34+
expect(markdownFromDraft).toEqual(markdownString);
35+
2436
});
2537

2638
it('renders new lines text correctly with styled blocks', function () {
@@ -31,6 +43,13 @@ describe('idempotency', function () {
3143
expect(markdownFromDraft).toEqual(markdownString);
3244
});
3345

46+
it('renders blockquotes correctly', function () {
47+
var markdownString = '> Hello I am Blockquote\n\nI am not\n\n> I am';
48+
var draftJSObject = markdownToDraft(markdownString, {preserveNewlines: true});
49+
var markdownFromDraft = draftToMarkdown(draftJSObject, {preserveNewlines: true});
50+
expect(markdownFromDraft).toEqual(markdownString);
51+
});
52+
3453
it('renders italic text correctly', function () {
3554
var markdownString = '_I am italic_ …I am not italic.';
3655
var draftJSObject = markdownToDraft(markdownString);

test/markdown-to-draft.spec.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,31 @@ describe('markdownToDraft', function () {
2323
expect(conversionResult.blocks[0].type).toEqual('unstyled');
2424
});
2525

26+
it('renders unstyled blank lines correctly', function () {
27+
var markdown = 'a\nb\n\nc\n\n\nd';
28+
var conversionResult = markdownToDraft(markdown);
29+
expect(conversionResult.blocks[0].text).toEqual('a\nb');
30+
expect(conversionResult.blocks[0].type).toEqual('unstyled');
31+
expect(conversionResult.blocks[1].text).toEqual('c');
32+
expect(conversionResult.blocks[1].type).toEqual('unstyled');
33+
expect(conversionResult.blocks[2].text).toEqual('d');
34+
expect(conversionResult.blocks[2].type).toEqual('unstyled');
35+
36+
conversionResult = markdownToDraft(markdown, {preserveNewlines: true});
37+
expect(conversionResult.blocks[0].text).toEqual('a\nb');
38+
expect(conversionResult.blocks[0].type).toEqual('unstyled');
39+
expect(conversionResult.blocks[1].text).toEqual('');
40+
expect(conversionResult.blocks[1].type).toEqual('unstyled');
41+
expect(conversionResult.blocks[2].text).toEqual('c');
42+
expect(conversionResult.blocks[2].type).toEqual('unstyled');
43+
expect(conversionResult.blocks[3].text).toEqual('');
44+
expect(conversionResult.blocks[3].type).toEqual('unstyled');
45+
expect(conversionResult.blocks[4].text).toEqual('');
46+
expect(conversionResult.blocks[4].type).toEqual('unstyled');
47+
expect(conversionResult.blocks[5].text).toEqual('d');
48+
expect(conversionResult.blocks[5].type).toEqual('unstyled');
49+
});
50+
2651
it('renders hardbreaks correctly', function () {
2752
var markdown = 'First line \nSecond line';
2853
var conversionResult = markdownToDraft(markdown);

0 commit comments

Comments
 (0)