From 1d73a40426bc976d2b176c75978daab9d65a4374 Mon Sep 17 00:00:00 2001 From: mateusbra <56851391+mateusbra@users.noreply.github.com> Date: Fri, 4 Jun 2021 15:34:06 -0300 Subject: [PATCH 1/9] Changes in quotes --- lib/ExpensiMark.js | 84 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 78d1ff7c..10c72546 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -148,8 +148,13 @@ export default class ExpensiMark { // We also want to capture a blank line before or after the quote so that we do not add extra spaces. // block quotes naturally appear on their own line. Blockquotes should not appear in code fences or // inline code blocks. A single prepending space should be stripped if it exists - regex: /\n?^> ?(?![^<]*(?:<\/pre>|<\/code>))([^\v\n\r]+)\n?/gm, - replacement: '
$1
' + process: (textToProcess, replacement) => { + const regex = new RegExp( + `((\n?^> ?(?![^<]*(?:<\/pre>|<\/code>))([^\v\n\r]+))+)`, + 'gm' + ); + return this.modifyTextForQuote(regex, textToProcess); + }, }, { name: 'newline', @@ -250,4 +255,79 @@ export default class ExpensiMark { return replacedText; } + + /** + * Modify text for Quotes replacing chevrons with html elements + * + * @param {RegExp} regex + * @param {String} textToCheck + * + * @returns {String} + */ + + modifyTextForQuote(regex, textToCheck) { + let replacedText = ""; + let TextToFormat = ""; + match = textToCheck.match(regex); + + //if there's matches we need to modify the quotes + if (match !== null) { + //split the textToCheck in lines + let textSplitted = textToCheck.split('\n'); + for (let i = 0; i < textSplitted.length; i++) { + + //we only want to modify lines starting with > + if (textSplitted[i].substr(0, 4) == ">") { + + //avoid blank lines starting with > + if (textSplitted[i].trim() !== ">") { + textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length); + textSplitted[i] = textSplitted[i].trim(); + TextToFormat += textSplitted[i] + '\n'; + + } else { + + //we need ensure that index i-1 >= 0 + if (i > 0) { + + //certificate that we will have only one blank row + if (textSplitted[i - 1].trim() !== "") { + textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length); + textSplitted[i] = textSplitted[i].trim(); + TextToFormat += textSplitted[i] + '\n'; + } else { + + //doesnt append to textToFormat if current index row and current index row -1 was blank + textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length); + textSplitted[i] = textSplitted[i].trim(); + } + } + } + } else { + + //make sure we will only modify if we have Text needed to be formatted for quote + if (TextToFormat != "") { + TextToFormat = TextToFormat.replace(/\n$/, ""); + replacedText += "
" + TextToFormat + "
"; + TextToFormat = ""; + } + replacedText += textSplitted[i] + '\n'; + } + } + + //when loop ends we need the last quote to be formatted if we have quotes at last rows + if (TextToFormat != "") { + TextToFormat = TextToFormat.replace(/\n$/, ""); + replacedText += "
" + TextToFormat + "
"; + } + + //replace all the blank lines between quotes, if there are only blank lines between them + replacedText = replacedText.replace(/(<\/blockquote>((\s*)+)
)/g, "
"); + + } else { + //if we doesnt have matches make sure the function will return the same textToCheck + replacedText = textToCheck; + } + return replacedText; + } } From 041f0be2e14585629ee2b0262cccf348d5f245f6 Mon Sep 17 00:00:00 2001 From: mateusbra <56851391+mateusbra@users.noreply.github.com> Date: Mon, 7 Jun 2021 19:50:47 -0300 Subject: [PATCH 2/9] changes on quotes --- lib/ExpensiMark.js | 72 +++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 10c72546..dd39331b 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -148,9 +148,9 @@ export default class ExpensiMark { // We also want to capture a blank line before or after the quote so that we do not add extra spaces. // block quotes naturally appear on their own line. Blockquotes should not appear in code fences or // inline code blocks. A single prepending space should be stripped if it exists - process: (textToProcess, replacement) => { + process: (textToProcess) => { const regex = new RegExp( - `((\n?^> ?(?![^<]*(?:<\/pre>|<\/code>))([^\v\n\r]+))+)`, + '((\n?^> ?(?![^<]*(?:|))([^\v\n\r]+))+)', 'gm' ); return this.modifyTextForQuote(regex, textToProcess); @@ -265,67 +265,59 @@ export default class ExpensiMark { * @returns {String} */ - modifyTextForQuote(regex, textToCheck) { - let replacedText = ""; - let TextToFormat = ""; - match = textToCheck.match(regex); + modifyTextForQuote(regex, textToCheck) { + let replacedText = ''; + let TextToFormat = ''; + const match = textToCheck.match(regex); - //if there's matches we need to modify the quotes + // if there's matches we need to modify the quotes if (match !== null) { - //split the textToCheck in lines - let textSplitted = textToCheck.split('\n'); + // split the textToCheck in lines + const textSplitted = textToCheck.split('\n'); for (let i = 0; i < textSplitted.length; i++) { - - //we only want to modify lines starting with > - if (textSplitted[i].substr(0, 4) == ">") { - - //avoid blank lines starting with > - if (textSplitted[i].trim() !== ">") { + // we only want to modify lines starting with > + if (textSplitted[i].substr(0, 4) === '>') { + // avoid blank lines starting with > + if (textSplitted[i].trim() !== '>') { textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length); textSplitted[i] = textSplitted[i].trim(); - TextToFormat += textSplitted[i] + '\n'; - + TextToFormat += `${textSplitted[i]}\n`; } else { - - //we need ensure that index i-1 >= 0 + // we need ensure that index i-1 >= 0 if (i > 0) { - - //certificate that we will have only one blank row - if (textSplitted[i - 1].trim() !== "") { + // certificate that we will have only one blank row + if (textSplitted[i - 1].trim() !== '') { textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length); textSplitted[i] = textSplitted[i].trim(); - TextToFormat += textSplitted[i] + '\n'; + TextToFormat += `${textSplitted[i]}\n`; } else { - - //doesnt append to textToFormat if current index row and current index row -1 was blank + // doesnt append to textToFormat if current index row and current index row -1 was blank textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length); textSplitted[i] = textSplitted[i].trim(); } } } } else { - - //make sure we will only modify if we have Text needed to be formatted for quote - if (TextToFormat != "") { - TextToFormat = TextToFormat.replace(/\n$/, ""); - replacedText += "
" + TextToFormat + "
"; - TextToFormat = ""; + // make sure we will only modify if we have Text needed to be formatted for quote + if (TextToFormat !== '') { + TextToFormat = TextToFormat.replace(/\n$/, ''); + replacedText += `
${TextToFormat}
`; + TextToFormat = ''; } - replacedText += textSplitted[i] + '\n'; + replacedText += `${textSplitted[i]}\n`; } } - //when loop ends we need the last quote to be formatted if we have quotes at last rows - if (TextToFormat != "") { - TextToFormat = TextToFormat.replace(/\n$/, ""); - replacedText += "
" + TextToFormat + "
"; + // when loop ends we need the last quote to be formatted if we have quotes at last rows + if (TextToFormat !== '') { + TextToFormat = TextToFormat.replace(/\n$/, ''); + replacedText += `
${TextToFormat}
`; } - //replace all the blank lines between quotes, if there are only blank lines between them - replacedText = replacedText.replace(/(<\/blockquote>((\s*)+)
)/g, "
"); - + // replace all the blank lines between quotes, if there are only blank lines between them + replacedText = replacedText.replace(/(<\/blockquote>((\s*)+)
)/g, '
'); } else { - //if we doesnt have matches make sure the function will return the same textToCheck + // if we doesnt have matches make sure the function will return the same textToCheck replacedText = textToCheck; } return replacedText; From 53b78439ce18119dd4f423020af34369d8d16113 Mon Sep 17 00:00:00 2001 From: mateusbra <56851391+mateusbra@users.noreply.github.com> Date: Wed, 9 Jun 2021 13:46:05 -0300 Subject: [PATCH 3/9] Changes in quotes --- lib/ExpensiMark.js | 60 +++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index dd39331b..91c496ee 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -150,8 +150,7 @@ export default class ExpensiMark { // inline code blocks. A single prepending space should be stripped if it exists process: (textToProcess) => { const regex = new RegExp( - '((\n?^> ?(?![^<]*(?:|))([^\v\n\r]+))+)', - 'gm' + /\n?^> ?(?![^<]*(?:<\/pre>|<\/code>))([^\v\n\r]+)\n?/gm ); return this.modifyTextForQuote(regex, textToProcess); }, @@ -266,37 +265,66 @@ export default class ExpensiMark { */ modifyTextForQuote(regex, textToCheck) { + console.log('tetxttocheck =', textToCheck); let replacedText = ''; let TextToFormat = ''; + let isCodeFence; + const codefenceSplitted = []; const match = textToCheck.match(regex); + const match_codefence = textToCheck.match(/
(\s|\S)+<\/pre>/gm);
 
         // if there's matches we need to modify the quotes
         if (match !== null) {
+            // split all the codefences in lines
+            for (let i = 0; i < match_codefence.length; i++) {
+                codefenceSplitted[i] = match_codefence[i].split('\n');
+            }
+
             // split the textToCheck in lines
             const textSplitted = textToCheck.split('\n');
+
             for (let i = 0; i < textSplitted.length; i++) {
-                // we only want to modify lines starting with >
-                if (textSplitted[i].substr(0, 4) === '>') {
+                isCodeFence = false;
+                for (let j = 0; j < codefenceSplitted.length; j++) {
+                    for (let k = 0; k < codefenceSplitted[j].length; k++) {
+                    // we need to know when is codefenced
+                        if (textSplitted[i] === codefenceSplitted[j][k]) {
+                            isCodeFence = true;
+                        }
+                    }
+                }
+
+                // we only want to modify lines starting with > that is not codefence;
+                if (textSplitted[i].substr(0, 4) === '>' && !isCodeFence) {
                     // avoid blank lines starting with >
                     if (textSplitted[i].trim() !== '>') {
                         textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
                         textSplitted[i] = textSplitted[i].trim();
                         TextToFormat += `${textSplitted[i]}\n`;
-                    } else {
+
                         // we need ensure that index i-1 >= 0
-                        if (i > 0) {
-                            // certificate that we will have only one blank row
-                            if (textSplitted[i - 1].trim() !== '') {
-                                textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
-                                textSplitted[i] = textSplitted[i].trim();
-                                TextToFormat += `${textSplitted[i]}\n`;
-                            } else {
-                                // doesnt append to textToFormat if current index row and current index row -1 was blank
-                                textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
-                                textSplitted[i] = textSplitted[i].trim();
-                            }
+                    } else if (i > 0) {
+                        // certificate that we will have only one blank row
+                        if (textSplitted[i - 1].trim() !== '') {
+                            textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
+                            textSplitted[i] = textSplitted[i].trim();
+                            TextToFormat += `${textSplitted[i]}\n`;
+                        } else {
+                            // doesnt append to textToFormat if current index row and current index row -1 was blank
+                            textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
+                            textSplitted[i] = textSplitted[i].trim();
                         }
                     }
+
+                // we dont want a \n after the textSplitted if it is an end of codefence(it will do the same as the else, but without \n)
+                } else if (isCodeFence && textSplitted[i].substr(textSplitted[i].length - 6, textSplitted[i].length) === '
') { + // make sure we will only modify if we have Text needed to be formatted for quote + if (TextToFormat !== '') { + TextToFormat = TextToFormat.replace(/\n$/, ''); + replacedText += `
${TextToFormat}
`; + TextToFormat = ''; + } + replacedText += `${textSplitted[i]}`; } else { // make sure we will only modify if we have Text needed to be formatted for quote if (TextToFormat !== '') { From f6263c1ed288b396ede51f94698520d0cf0cbede Mon Sep 17 00:00:00 2001 From: mateusbra <56851391+mateusbra@users.noreply.github.com> Date: Fri, 11 Jun 2021 15:13:30 -0300 Subject: [PATCH 4/9] Changes on quote --- lib/ExpensiMark.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 91c496ee..2be283d0 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -265,10 +265,8 @@ export default class ExpensiMark { */ modifyTextForQuote(regex, textToCheck) { - console.log('tetxttocheck =', textToCheck); let replacedText = ''; let TextToFormat = ''; - let isCodeFence; const codefenceSplitted = []; const match = textToCheck.match(regex); const match_codefence = textToCheck.match(/
(\s|\S)+<\/pre>/gm);
@@ -284,7 +282,7 @@ export default class ExpensiMark {
             const textSplitted = textToCheck.split('\n');
 
             for (let i = 0; i < textSplitted.length; i++) {
-                isCodeFence = false;
+                let isCodeFence = false;
                 for (let j = 0; j < codefenceSplitted.length; j++) {
                     for (let k = 0; k < codefenceSplitted[j].length; k++) {
                     // we need to know when is codefenced

From 185c346d76548aedd97c91b6186ac297dec95a1c Mon Sep 17 00:00:00 2001
From: mateusbra 
Date: Tue, 15 Jun 2021 15:44:33 -0300
Subject: [PATCH 5/9] Changes in quotes and added tests for quotes

---
 __tests__/ExpensiMark-test.js | 32 +++++++++++++
 lib/ExpensiMark.js            | 86 ++++++++++++++++-------------------
 2 files changed, 71 insertions(+), 47 deletions(-)

diff --git a/__tests__/ExpensiMark-test.js b/__tests__/ExpensiMark-test.js
index e4bffea3..8eda2f5d 100644
--- a/__tests__/ExpensiMark-test.js
+++ b/__tests__/ExpensiMark-test.js
@@ -338,3 +338,35 @@ test('Test markdown and url links with inconsistent starting and closing parens'
 
     expect(parser.replace(testString)).toBe(resultString);
 });
+
+test('Test quotes markdown replacement with text matching inside and outside codefence without spaces', () => {
+    const testString = 'The next line should be quoted\n>Hello,I’mtext\n```\nThe next line should not be quoted\n>Hello,I’mtext\nsince its inside a codefence```';
+
+    const resultString = 'The next line should be quoted
Hello,I’mtext
The next line should not be quoted
>Hello,I’mtext
since its inside a codefence
'; + + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test quotes markdown replacement with text matching inside and outside codefence at the same line', () => { + const testString = 'The next line should be quoted\n>Hello,I’mtext\nThe next line should not be quoted\n```>Hello,I’mtext```\nsince its inside a codefence'; + + const resultString = 'The next line should be quoted
Hello,I’mtext
The next line should not be quoted
>Hello,I’mtext

since its inside a codefence'; + + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test quotes markdown replacement with text matching inside and outside codefence at the end of the text', () => { + const testString = 'The next line should be quoted\n>Hello,I’mtext\nThe next line should not be quoted\n```>Hello,I’mtext```'; + + const resultString = 'The next line should be quoted
Hello,I’mtext
The next line should not be quoted
>Hello,I’mtext
'; + + expect(parser.replace(testString)).toBe(resultString); +}); + +test('Test quotes markdown replacement with text matching inside and outside codefence with quotes at the end of the text', () => { + const testString = 'The next line should be quoted\n```>Hello,I’mtext```\nThe next line should not be quoted\n>Hello,I’mtext'; + + const resultString = 'The next line should be quoted
>Hello,I’mtext

The next line should not be quoted
Hello,I’mtext
'; + + expect(parser.replace(testString)).toBe(resultString); +}); diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 2be283d0..d41f533e 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -148,12 +148,15 @@ export default class ExpensiMark { // We also want to capture a blank line before or after the quote so that we do not add extra spaces. // block quotes naturally appear on their own line. Blockquotes should not appear in code fences or // inline code blocks. A single prepending space should be stripped if it exists - process: (textToProcess) => { + process: (textToProcess, replacement) => { const regex = new RegExp( /\n?^> ?(?![^<]*(?:<\/pre>|<\/code>))([^\v\n\r]+)\n?/gm ); - return this.modifyTextForQuote(regex, textToProcess); + return this.modifyTextForQuote(regex, textToProcess, replacement); }, + replacement: g1 => ( + `
${g1}
` + ), }, { name: 'newline', @@ -260,90 +263,79 @@ export default class ExpensiMark { * * @param {RegExp} regex * @param {String} textToCheck + * @param {Function} replacement * * @returns {String} */ - modifyTextForQuote(regex, textToCheck) { + modifyTextForQuote(regex, textToCheck, replacement) { let replacedText = ''; - let TextToFormat = ''; - const codefenceSplitted = []; + let textToFormat = ''; const match = textToCheck.match(regex); - const match_codefence = textToCheck.match(/
(\s|\S)+<\/pre>/gm);
 
         // if there's matches we need to modify the quotes
         if (match !== null) {
-            // split all the codefences in lines
-            for (let i = 0; i < match_codefence.length; i++) {
-                codefenceSplitted[i] = match_codefence[i].split('\n');
-            }
+            let insideCodefence = false;
 
             // split the textToCheck in lines
             const textSplitted = textToCheck.split('\n');
 
             for (let i = 0; i < textSplitted.length; i++) {
-                let isCodeFence = false;
-                for (let j = 0; j < codefenceSplitted.length; j++) {
-                    for (let k = 0; k < codefenceSplitted[j].length; k++) {
-                    // we need to know when is codefenced
-                        if (textSplitted[i] === codefenceSplitted[j][k]) {
-                            isCodeFence = true;
-                        }
-                    }
+                if (!insideCodefence) {
+                    // we need to know when there is a start of codefence so we dont quote
+                    insideCodefence = Str.contains(textSplitted[i], '
');
                 }
 
-                // we only want to modify lines starting with > that is not codefence;
-                if (textSplitted[i].substr(0, 4) === '>' && !isCodeFence) {
+                // we only want to modify lines starting with > that is not codefence
+                if (Str.startsWith(textSplitted[i], '>') && !insideCodefence) {
                     // avoid blank lines starting with >
                     if (textSplitted[i].trim() !== '>') {
-                        textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
+                        textSplitted[i] = textSplitted[i].substr(4).trim();
                         textSplitted[i] = textSplitted[i].trim();
-                        TextToFormat += `${textSplitted[i]}\n`;
+                        textToFormat += `${textSplitted[i]}\n`;
 
                         // we need ensure that index i-1 >= 0
                     } else if (i > 0) {
                         // certificate that we will have only one blank row
                         if (textSplitted[i - 1].trim() !== '') {
-                            textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
-                            textSplitted[i] = textSplitted[i].trim();
-                            TextToFormat += `${textSplitted[i]}\n`;
-                        } else {
-                            // doesnt append to textToFormat if current index row and current index row -1 was blank
-                            textSplitted[i] = textSplitted[i].substr(4, textSplitted[i].length);
+                            textSplitted[i] = textSplitted[i].substr(4).trim();
                             textSplitted[i] = textSplitted[i].trim();
+                            textToFormat += `${textSplitted[i]}\n`;
                         }
                     }
-
-                // we dont want a \n after the textSplitted if it is an end of codefence(it will do the same as the else, but without \n)
-                } else if (isCodeFence && textSplitted[i].substr(textSplitted[i].length - 6, textSplitted[i].length) === '
') { - // make sure we will only modify if we have Text needed to be formatted for quote - if (TextToFormat !== '') { - TextToFormat = TextToFormat.replace(/\n$/, ''); - replacedText += `
${TextToFormat}
`; - TextToFormat = ''; - } - replacedText += `${textSplitted[i]}`; } else { // make sure we will only modify if we have Text needed to be formatted for quote - if (TextToFormat !== '') { - TextToFormat = TextToFormat.replace(/\n$/, ''); - replacedText += `
${TextToFormat}
`; - TextToFormat = ''; + if (textToFormat !== '') { + textToFormat = textToFormat.replace(/\n$/, ''); + replacedText += replacement(textToFormat); + textToFormat = ''; + } + + // if index === last row + if (i === textSplitted.length - 1) { + // we dont want a \n after the textSplitted if it is the last row + replacedText += `${textSplitted[i]}`; + } else { + replacedText += `${textSplitted[i]}\n`; + } + + // we need to know when we are not inside codefence anymore + if (insideCodefence) { + insideCodefence = !Str.contains(textSplitted[i], '
'); } - replacedText += `${textSplitted[i]}\n`; } } // when loop ends we need the last quote to be formatted if we have quotes at last rows - if (TextToFormat !== '') { - TextToFormat = TextToFormat.replace(/\n$/, ''); - replacedText += `
${TextToFormat}
`; + if (textToFormat !== '') { + textToFormat = textToFormat.replace(/\n$/, ''); + replacedText += replacement(textToFormat); } // replace all the blank lines between quotes, if there are only blank lines between them replacedText = replacedText.replace(/(<\/blockquote>((\s*)+)
)/g, '
'); } else { - // if we doesnt have matches make sure the function will return the same textToCheck + // if we doesnt have matches make sure the function will return the same textToCheck replacedText = textToCheck; } return replacedText; From ebd4a62c6383301aa91d333ff0f10d1e836953d1 Mon Sep 17 00:00:00 2001 From: mateusbra Date: Thu, 17 Jun 2021 21:20:12 -0300 Subject: [PATCH 6/9] up to date with branch master --- __tests__/ExpensiMark-test.js | 27 +++++++++++++++++++++++++++ lib/ExpensiMark.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/__tests__/ExpensiMark-test.js b/__tests__/ExpensiMark-test.js index 8eda2f5d..b4cb96d1 100644 --- a/__tests__/ExpensiMark-test.js +++ b/__tests__/ExpensiMark-test.js @@ -339,6 +339,33 @@ test('Test markdown and url links with inconsistent starting and closing parens' expect(parser.replace(testString)).toBe(resultString); }); +test('Test HTML string with
tags to markdown ', () => { + const testString = 'Hello
World,
Welcome
To
Expensify'; + const resultString = 'Hello\nWorld,\nWelcome\nTo\nExpensify'; + + expect(parser.htmlToMarkdown(testString)).toBe(resultString); +}); + +test('Test HTML string with inconsistent
closing tags to markdown ', () => { + const testString = 'Hello
World,
Welcome
To
Expensify'; + const resultString = 'Hello\nWorld,\nWelcome\nTo\nExpensify'; + + expect(parser.htmlToMarkdown(testString)).toBe(resultString); +}); + +test('Test HTML string with seperate closing tags (

) to markdown ', () => { + const testString = 'Hello
World,

Welcome
To
Expensify'; + const resultString = 'Hello\nWorld,\nWelcome\nTo\nExpensify'; + + expect(parser.htmlToMarkdown(testString)).toBe(resultString); +}); + +test('Test HTML string with seperate closing tags (

) to markdown ', () => { + const testString = 'Hello
World,

Welcome
To
Expensify'; + const resultString = 'Hello\nWorld,\nWelcome\nTo\nExpensify'; + expect(parser.htmlToMarkdown(testString)).toBe(resultString); +}); + test('Test quotes markdown replacement with text matching inside and outside codefence without spaces', () => { const testString = 'The next line should be quoted\n>Hello,I’mtext\n```\nThe next line should not be quoted\n>Hello,I’mtext\nsince its inside a codefence```'; diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index d41f533e..ff43c522 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -164,6 +164,22 @@ export default class ExpensiMark { replacement: '
', }, ]; + + /** + * The list of regex replacements to do on a HTML comment for converting it to markdown. + * + * @type {Object[]} + */ + this.htmlToMarkdownRules = [ + { + name: 'newline', + + // Replaces open and closing

tags with a single
+ pre: inputString => inputString.replace('

', '
').replace('

', '
'), + regex: //gi, + replacement: '\n' + }, + ]; } /** @@ -258,6 +274,25 @@ export default class ExpensiMark { return replacedText; } + /** + * Replaces HTML with markdown + * + * @param {String} htmlString + * + * @returns {String} + */ + htmlToMarkdown(htmlString) { + let generatedMarkdown = htmlString; + this.htmlToMarkdownRules.forEach((rule) => { + // Pre-processes input HTML before applying regex + if (rule.pre) { + generatedMarkdown = rule.pre(generatedMarkdown); + } + generatedMarkdown = generatedMarkdown.replace(rule.regex, rule.replacement); + }); + return generatedMarkdown; + } + /** * Modify text for Quotes replacing chevrons with html elements * From 0f318836229b7dd04ccef977ddcbc4d02cca275e Mon Sep 17 00:00:00 2001 From: mateusbra Date: Mon, 21 Jun 2021 17:02:44 -0300 Subject: [PATCH 7/9] Changes in quotes --- lib/ExpensiMark.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index ff43c522..3e6bc534 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -154,9 +154,7 @@ export default class ExpensiMark { ); return this.modifyTextForQuote(regex, textToProcess, replacement); }, - replacement: g1 => ( - `
${g1}
` - ), + replacement: g1 => `
${g1}
`, }, { name: 'newline', From c3e6dd0976b1a215a8d806f2f470e0597a98a825 Mon Sep 17 00:00:00 2001 From: mateusbra Date: Tue, 22 Jun 2021 22:21:27 -0300 Subject: [PATCH 8/9] Changes in quotes --- lib/ExpensiMark.js | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 3e6bc534..77991cd3 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -306,30 +306,30 @@ export default class ExpensiMark { let textToFormat = ''; const match = textToCheck.match(regex); - // if there's matches we need to modify the quotes + // If there's matches we need to modify the quotes if (match !== null) { let insideCodefence = false; - // split the textToCheck in lines + // Split the textToCheck in lines const textSplitted = textToCheck.split('\n'); for (let i = 0; i < textSplitted.length; i++) { if (!insideCodefence) { - // we need to know when there is a start of codefence so we dont quote + // We need to know when there is a start of codefence so we dont quote insideCodefence = Str.contains(textSplitted[i], '
');
                 }
 
-                // we only want to modify lines starting with > that is not codefence
+                // We only want to modify lines starting with > that is not codefence
                 if (Str.startsWith(textSplitted[i], '>') && !insideCodefence) {
-                    // avoid blank lines starting with >
+                    // Avoid blank lines starting with >
                     if (textSplitted[i].trim() !== '>') {
                         textSplitted[i] = textSplitted[i].substr(4).trim();
                         textSplitted[i] = textSplitted[i].trim();
                         textToFormat += `${textSplitted[i]}\n`;
 
-                        // we need ensure that index i-1 >= 0
+                        // We need ensure that index i-1 >= 0
                     } else if (i > 0) {
-                        // certificate that we will have only one blank row
+                        // Certificate that we will have only one blank row
                         if (textSplitted[i - 1].trim() !== '') {
                             textSplitted[i] = textSplitted[i].substr(4).trim();
                             textSplitted[i] = textSplitted[i].trim();
@@ -337,38 +337,37 @@ export default class ExpensiMark {
                         }
                     }
                 } else {
-                    // make sure we will only modify if we have Text needed to be formatted for quote
+                    // Make sure we will only modify if we have Text needed to be formatted for quote
                     if (textToFormat !== '') {
                         textToFormat = textToFormat.replace(/\n$/, '');
                         replacedText += replacement(textToFormat);
                         textToFormat = '';
                     }
 
-                    // if index === last row
+                    // We dont want a \n after the textSplitted if it is the last row
                     if (i === textSplitted.length - 1) {
-                        // we dont want a \n after the textSplitted if it is the last row
                         replacedText += `${textSplitted[i]}`;
                     } else {
                         replacedText += `${textSplitted[i]}\n`;
                     }
 
-                    // we need to know when we are not inside codefence anymore
+                    // We need to know when we are not inside codefence anymore
                     if (insideCodefence) {
                         insideCodefence = !Str.contains(textSplitted[i], '
'); } } } - // when loop ends we need the last quote to be formatted if we have quotes at last rows + // When loop ends we need the last quote to be formatted if we have quotes at last rows if (textToFormat !== '') { textToFormat = textToFormat.replace(/\n$/, ''); replacedText += replacement(textToFormat); } - // replace all the blank lines between quotes, if there are only blank lines between them + // Replace all the blank lines between quotes, if there are only blank lines between them replacedText = replacedText.replace(/(<\/blockquote>((\s*)+)
)/g, '
'); } else { - // if we doesnt have matches make sure the function will return the same textToCheck + // If we doesnt have matches make sure the function will return the same textToCheck replacedText = textToCheck; } return replacedText; From 5ed6ab8fd119fea5d4807a515a6004cebef2be1e Mon Sep 17 00:00:00 2001 From: mateusbra Date: Wed, 23 Jun 2021 23:46:05 -0300 Subject: [PATCH 9/9] Changes in quotes --- lib/ExpensiMark.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ExpensiMark.js b/lib/ExpensiMark.js index 77991cd3..677196cd 100644 --- a/lib/ExpensiMark.js +++ b/lib/ExpensiMark.js @@ -367,7 +367,7 @@ export default class ExpensiMark { // Replace all the blank lines between quotes, if there are only blank lines between them replacedText = replacedText.replace(/(<\/blockquote>((\s*)+)
)/g, '
'); } else { - // If we doesnt have matches make sure the function will return the same textToCheck + // If we doesn't have matches make sure the function will return the same textToCheck replacedText = textToCheck; } return replacedText;