From 4bbf18aeb7bb0b7055b7fbf5b995fb2a5c86e4ca Mon Sep 17 00:00:00 2001 From: Carolina lucini Date: Tue, 15 Jun 2021 15:44:33 -0300 Subject: [PATCH] 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 e4bffea3c..8eda2f5d4 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 2be283d0c..d41f533e0 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;