diff --git a/.circleci/config.yml b/.circleci/config.yml index 2025e8fe7..c195df81c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -73,6 +73,9 @@ jobs: - run: name: Test - Non-Breaking Spaces command: npm run test:non-breaking-spaces + - run: + name: Test - Paragraph Justification + command: npm run test:paragraph-justification - run: name: Test - Variables command: npm run test:variables diff --git a/package.json b/package.json index a74dcf3e0..d70b05c61 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "test:definition-lists": "jest tests/markdown/definition-lists.test.js --verbose --noStackTrace", "test:hard-breaks": "jest tests/markdown/hard-breaks.test.js --verbose --noStackTrace", "test:non-breaking-spaces": "jest tests/markdown/non-breaking-spaces.test.js --verbose --noStackTrace", + "test:paragraph-justification": "jest tests/markdown/paragraph-justification.test.js --verbose --noStackTrace", "test:emojis": "jest tests/markdown/emojis.test.js --verbose --noStackTrace", "test:route": "jest tests/routes/static-pages.test.js --verbose", "test:safehtml": "jest tests/html/safeHTML.test.js --verbose", diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index ffd2395fa..16dc14440 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -371,6 +371,43 @@ const superSubScripts = { } }; + +const justifiedParagraphClasses = []; +justifiedParagraphClasses[2] = 'Left'; +justifiedParagraphClasses[4] = 'Right'; +justifiedParagraphClasses[6] = 'Center'; + +const justifiedParagraphs = { + name : 'justifiedParagraphs', + level : 'block', + start(src) { + return src.match(/\n(?:-:|:-|-:) {1}/m)?.index; + }, // Hint to Marked.js to stop and check for a match + tokenizer(src, tokens) { + const regex = /^(((:-))|((-:))|((:-:))) .+(\n(([^\n].*\n)*(\n|$))|$)/ygm; + const match = regex.exec(src); + if(match?.length) { + let whichJustify; + if(match[2]?.length) whichJustify = 2; + if(match[4]?.length) whichJustify = 4; + if(match[6]?.length) whichJustify = 6; + return { + type : 'justifiedParagraphs', // Should match "name" above + raw : match[0], // Text to consume from the source + length : match[whichJustify].length, + text : match[0].slice(match[whichJustify].length), + class : justifiedParagraphClasses[whichJustify], + tokens : this.lexer.inlineTokens(match[0].slice(match[whichJustify].length + 1)) + }; + } + }, + renderer(token) { + return `

${this.parser.parseInline(token.tokens)}

`; + } + +}; + + const forcedParagraphBreaks = { name : 'hardBreaks', level : 'block', @@ -768,7 +805,7 @@ const tableTerminators = [ ]; Marked.use(MarkedVariables()); -Marked.use({ extensions : [definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, +Marked.use({ extensions : [justifiedParagraphs, definitionListsMultiLine, definitionListsSingleLine, forcedParagraphBreaks, nonbreakingSpaces, superSubScripts, mustacheSpans, mustacheDivs, mustacheInjectInline] }); Marked.use(mustacheInjectBlock); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); diff --git a/tests/markdown/paragraph-justification.test.js b/tests/markdown/paragraph-justification.test.js new file mode 100644 index 000000000..48b311e85 --- /dev/null +++ b/tests/markdown/paragraph-justification.test.js @@ -0,0 +1,27 @@ +/* eslint-disable max-lines */ + +import Markdown from 'naturalcrit/markdown.js'; + +describe('Justification', ()=>{ + test('Left Justify', function() { + const source = ':- Hello'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Hello

`); + }); + test('Right Justify', function() { + const source = '-: Hello'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Hello

`); + }); + test('Center Justify', function() { + const source = ':-: Hello'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Hello

`); + }); + + test('Ignored inside a code block', function() { + const source = '```\n\n:- Hello\n\n```\n'; + const rendered = Markdown.render(source); + expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
\n:- Hello\n
\n`); + }); +}); diff --git a/themes/V3/Blank/style.less b/themes/V3/Blank/style.less index 4f838a5d1..65eeee683 100644 --- a/themes/V3/Blank/style.less +++ b/themes/V3/Blank/style.less @@ -505,4 +505,4 @@ body { counter-reset : page-numbers 0; } counter-increment : page-numbers; } -} \ No newline at end of file +}