From c918a79957bc9f34cc1be7e9f2b42184f5fd945a Mon Sep 17 00:00:00 2001 From: David Bolack Date: Wed, 5 Jun 2024 12:44:46 -0500 Subject: [PATCH 1/3] Integrates corrections for Document level unique Header IDs in tandum with marked-gfm-header-id updates. Requries https://github.com/markedjs/marked-gfm-heading-id/issues/542 and an assumed version bump to work. Validated locally. --- package-lock.json | 50 ++++++++++++++++++++++++---------- package.json | 2 +- shared/naturalcrit/markdown.js | 13 +++++---- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index e18ca8ac7..2662f3bea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "marked": "11.2.0", "marked-emoji": "^1.4.0", "marked-extended-tables": "^1.0.8", - "marked-gfm-heading-id": "^3.1.3", + "marked-gfm-heading-id": "file:../marked-gfm-heading-id", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", @@ -67,6 +67,38 @@ "npm": "^10.2.x" } }, + "../marked-gfm-heading-id": { + "version": "3.1.3", + "license": "MIT", + "dependencies": { + "github-slugger": "^2.0.0" + }, + "devDependencies": { + "@babel/core": "^7.24.6", + "@babel/preset-env": "^7.24.6", + "@rollup/plugin-node-resolve": "^15.2.3", + "@semantic-release/changelog": "^6.0.3", + "@semantic-release/commit-analyzer": "^13.0.0", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^10.0.5", + "@semantic-release/npm": "^12.0.1", + "@semantic-release/release-notes-generator": "^14.0.0", + "babel-jest": "^29.7.0", + "eslint": "^8.57.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-n": "^16.6.2", + "eslint-plugin-promise": "^6.2.0", + "jest-cli": "^29.7.0", + "marked": "^12.0.2", + "rollup": "^4.18.0", + "semantic-release": "^24.0.0", + "tsd": "^0.31.0" + }, + "peerDependencies": { + "marked": ">=4 <13" + } + }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -6739,11 +6771,6 @@ "node": ">=0.10.0" } }, - "node_modules/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -10168,15 +10195,8 @@ } }, "node_modules/marked-gfm-heading-id": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/marked-gfm-heading-id/-/marked-gfm-heading-id-3.1.3.tgz", - "integrity": "sha512-A0cRU4PCueX/5m8VE4mT8uTQ36l3xMYRojz3Eqnk4BmUFZ0T+9Xhn2KvHcANP4qbhfOeuMrWJCTQbASIBR5xeg==", - "dependencies": { - "github-slugger": "^2.0.0" - }, - "peerDependencies": { - "marked": ">=4 <13" - } + "resolved": "../marked-gfm-heading-id", + "link": true }, "node_modules/marked-smartypants-lite": { "version": "1.0.2", diff --git a/package.json b/package.json index c98c42817..36589eae9 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "marked": "11.2.0", "marked-emoji": "^1.4.0", "marked-extended-tables": "^1.0.8", - "marked-gfm-heading-id": "^3.1.3", + "marked-gfm-heading-id": "^3.1.4", "marked-smartypants-lite": "^1.0.2", "markedLegacy": "npm:marked@^0.3.19", "moment": "^2.30.1", diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 95431487d..0ff32b007 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -3,7 +3,7 @@ const _ = require('lodash'); const Marked = require('marked'); const MarkedExtendedTables = require('marked-extended-tables'); const { markedSmartypantsLite: MarkedSmartypantsLite } = require('marked-smartypants-lite'); -const { gfmHeadingId: MarkedGFMHeadingId } = require('marked-gfm-heading-id'); +const { gfmHeadingId: MarkedGFMHeadingId, resetHeadings: MarkedGFMResetHeadingIDs } = require('marked-gfm-heading-id'); const { markedEmoji: MarkedEmojis } = require('marked-emoji'); //Icon fonts included so they can appear in emoji autosuggest dropdown @@ -699,7 +699,7 @@ Marked.use(MarkedVariables()); Marked.use({ extensions: [definitionListsMultiLine, definitionListsSingleLine, superSubScripts, mustacheSpans, mustacheDivs, mustacheInjectInline] }); Marked.use(mustacheInjectBlock); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); -Marked.use(MarkedExtendedTables(), MarkedGFMHeadingId(), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions)); +Marked.use(MarkedExtendedTables(), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions)); const nonWordAndColonTest = /[^\w:]/g; const cleanUrl = function (sanitize, base, href) { @@ -814,9 +814,12 @@ let globalPageNumber = 0; module.exports = { marked : Marked, render : (rawBrewText, pageNumber=1)=>{ - globalVarsList[pageNumber] = {}; //Reset global links for current page, to ensure values are parsed in order - varsQueue = []; //Could move into MarkedVariables() - globalPageNumber = pageNumber; + globalVarsList[pageNumber] = {}; //Reset global links for current page, to ensure values are parsed in order + varsQueue = []; //Could move into MarkedVariables() + globalPageNumber = pageNumber; + if(pageNumber==0) { + MarkedGFMResetHeadingIDs(); + } rawBrewText = rawBrewText.replace(/^\\column$/gm, `\n
\n`) .replace(/^(:+)$/gm, (match)=>`${`
`.repeat(match.length)}\n`); From cba57d1033f5359f455b40071ccc2d62980175b9 Mon Sep 17 00:00:00 2001 From: David Bolack Date: Tue, 11 Jun 2024 20:06:20 -0500 Subject: [PATCH 2/3] Fix and future-proof tests to use page 0 where necessary in markdown.render() calls. --- tests/markdown/basic.test.js | 4 +- tests/markdown/definition-lists.test.js | 28 +++--- tests/markdown/emojis.test.js | 14 +-- tests/markdown/mustache-syntax.test.js | 126 ++++++++++++------------ tests/markdown/variables.test.js | 56 +++++------ 5 files changed, 114 insertions(+), 114 deletions(-) diff --git a/tests/markdown/basic.test.js b/tests/markdown/basic.test.js index 80f5520e7..6df19b6e0 100644 --- a/tests/markdown/basic.test.js +++ b/tests/markdown/basic.test.js @@ -4,12 +4,12 @@ const Markdown = require('naturalcrit/markdown.js'); test('Processes the markdown within an HTML block if its just a class wrapper', function() { const source = '
*Bold text*
'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered).toBe('

Bold text

\n
'); }); test('Check markdown is using the custom renderer; specifically that it adds target=_self attribute to internal links in HTML blocks', function() { const source = '
[Has _self Attribute?](#p1)
'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered).toBe('

Has _self Attribute?

\n
'); }); diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js index 9f5025d73..d3d9f4b32 100644 --- a/tests/markdown/definition-lists.test.js +++ b/tests/markdown/definition-lists.test.js @@ -5,19 +5,19 @@ const Markdown = require('naturalcrit/markdown.js'); describe('Inline Definition Lists', ()=>{ test('No Term 1 Definition', function() { const source = ':: My First Definition\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
My First Definition
\n
'); }); test('Single Definition Term', function() { const source = 'My term :: My First Definition\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
My term
My First Definition
\n
'); }); test('Multiple Definition Terms', function() { const source = 'Term 1::Definition of Term 1\nTerm 2::Definition of Term 2\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
Definition of Term 1
\n
Term 2
Definition of Term 2
\n
'); }); }); @@ -25,67 +25,67 @@ describe('Inline Definition Lists', ()=>{ describe('Multiline Definition Lists', ()=>{ test('Single Term, Single Definition', function() { const source = 'Term 1\n::Definition 1\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
'); }); test('Single Term, Plural Definitions', function() { const source = 'Term 1\n::Definition 1\n::Definition 2\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
\n
Definition 2
'); }); test('Multiple Term, Single Definitions', function() { const source = 'Term 1\n::Definition 1\n\nTerm 2\n::Definition 1\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
\n
Term 2
\n
Definition 1
'); }); test('Multiple Term, Plural Definitions', function() { const source = 'Term 1\n::Definition 1\n::Definition 2\n\nTerm 2\n::Definition 1\n::Definition 2\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1
\n
Definition 2
\n
Term 2
\n
Definition 1
\n
Definition 2
'); }); test('Single Term, Single multi-line definition', function() { const source = 'Term 1\n::Definition 1\nand more and\nmore and more\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more and more
'); }); test('Single Term, Plural multi-line definitions', function() { const source = 'Term 1\n::Definition 1\nand more and more\n::Definition 2\nand more\nand more\n::Definition 3\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Definition 2 and more and more
\n
Definition 3
'); }); test('Multiple Term, Single multi-line definition', function() { const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\n'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Term 2
\n
Definition 1
\n
Definition 2
'); }); test('Multiple Term, Single multi-line definition, followed by an inline dl', function() { const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\n::Inline Definition (no term)'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Term 2
\n
Definition 1
\n
Definition 2
Inline Definition (no term)
\n
'); }); test('Multiple Term, Single multi-line definition, followed by paragraph', function() { const source = 'Term 1\n::Definition 1\nand more and more\n\nTerm 2\n::Definition 1\n::Definition 2\n\nParagraph'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
\n
Definition 1 and more and more
\n
Term 2
\n
Definition 1
\n
Definition 2

Paragraph

'); }); test('Block Token cannot be the Term of a multi-line definition', function() { const source = '## Header\n::Definition 1 of a single-line DL\n::Definition 1 of another single-line DL'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('\n
Definition 1 of a single-line DL
\n
Definition 1 of another single-line DL
\n
'); }); test('Inline DL has priority over Multiline', function() { const source = 'Term 1 :: Inline definition 1\n:: Inline definition 2 (no DT)'; - const rendered = Markdown.render(source).trim(); + const rendered = Markdown.render(source, 0).trim(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('
Term 1
Inline definition 1
\n
Inline definition 2 (no DT)
\n
'); }); }); diff --git a/tests/markdown/emojis.test.js b/tests/markdown/emojis.test.js index a4abbc6a4..a3de0dab1 100644 --- a/tests/markdown/emojis.test.js +++ b/tests/markdown/emojis.test.js @@ -12,37 +12,37 @@ const emoji = 'df_d12_2'; describe(`When emojis/icons are active`, ()=>{ it('when a word is between two colons (:word:), and a matching emoji exists, it is rendered as an emoji', function() { const source = `:${emoji}:`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

`); }); it('when a word is between two colons (:word:), and no matching emoji exists, it is not parsed', function() { const source = `:invalid:`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

:invalid:

`); }); it('two valid emojis with no whitespace are prioritized over definition lists', function() { const source = `:${emoji}::${emoji}:`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

`); }); it('definition lists that are not also part of an emoji can coexist with normal emojis', function() { const source = `definition :: term ${emoji}::${emoji}:`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
definition
term df_d12_2:
`); }); it('A valid emoji is compatible with curly injectors', function() { const source = `:${emoji}:{color:blue,myClass}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

`); }); it('Emojis are not parsed inside of curly span CSS blocks', function() { const source = `{{color:${emoji} text}}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`text`); }); @@ -50,7 +50,7 @@ describe(`When emojis/icons are active`, ()=>{ const source = dedent`{{color:${emoji} text }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); }); diff --git a/tests/markdown/mustache-syntax.test.js b/tests/markdown/mustache-syntax.test.js index b32876353..cb34fa697 100644 --- a/tests/markdown/mustache-syntax.test.js +++ b/tests/markdown/mustache-syntax.test.js @@ -15,112 +15,112 @@ String.prototype.trimReturns = function(){ describe('Inline: When using the Inline syntax {{ }}', ()=>{ it('Renders a mustache span with text only', function() { const source = '{{ text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text only, but with spaces', function() { const source = '{{ this is a text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('this is a text'); }); it('Renders an empty mustache span', function() { const source = '{{}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(''); }); it('Renders a mustache span with just a space', function() { const source = '{{ }}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(''); }); it('Renders a mustache span with a few spaces only', function() { const source = '{{ }}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(''); }); it('Renders a mustache span with text and class', function() { const source = '{{my-class text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text and two classes', function() { const source = '{{my-class,my-class2 text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text with spaces and class', function() { const source = '{{my-class this is a text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('this is a text'); }); it('Renders a mustache span with text and id', function() { const source = '{{#my-span text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text and two ids', function() { const source = '{{#my-span,#my-favorite-span text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text and css property', function() { const source = '{{color:red text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text and two css properties', function() { const source = '{{color:red,padding:5px text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text and css property which contains quotes', function() { const source = '{{font-family:"trebuchet ms" text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text and two css properties which contains quotes', function() { const source = '{{font-family:"trebuchet ms",padding:"5px 10px" text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a mustache span with text with quotes and css property which contains double quotes', function() { const source = '{{font-family:"trebuchet ms" text "with quotes"}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text “with quotes”'); }); it('Renders a mustache span with text with quotes and css property which contains double and simple quotes', function() { const source = `{{--stringVariable:"'string'" text "with quotes"}}`; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`text “with quotes”`); }); it('Renders a mustache span with text, id, class and a couple of css properties', function() { const source = '{{pen,#author,color:orange,font-family:"trebuchet ms" text}}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span with added attributes', function() { const source = 'Text and {{pen,#author,color:orange,font-family:"trebuchet ms",a="b and c",d=e, text}} and more text!'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

Text and text and more text!

\n'); }); }); @@ -132,7 +132,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{ text }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); }); @@ -140,14 +140,14 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{ }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); }); it('Renders a single paragraph with opening and closing brackets', function() { const source = dedent`{{ }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

{{}}

`); }); @@ -155,7 +155,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{cat }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
`); }); @@ -163,7 +163,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{cat Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -171,7 +171,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{cat,dog Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -179,7 +179,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{color:red Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -187,7 +187,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{--stringVariable:"'string'" Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -195,7 +195,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{--stringVariable:"'string'" Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -203,7 +203,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{cat,color:red Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -211,7 +211,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{color:red,cat,#dog Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -219,7 +219,7 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{#cat,#dog Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); @@ -227,13 +227,13 @@ describe(`Block: When using the Block syntax {{tags\\ntext\\n}}`, ()=>{ const source = dedent`{{color:red,cat,#dog,a="b and c",d="e" Sample text. }}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

Sample text.

`); }); it('Renders a div with added attributes', function() { const source = '{{pen,#author,color:orange,font-family:"trebuchet ms",a="b and c",d=e\nText and text and more text!\n}}\n'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

Text and text and more text!

\n
'); }); }); @@ -245,97 +245,97 @@ describe('Injection: When an injection tag follows an element', ()=>{ describe('and that element is an inline-block', ()=>{ it('Renders a span "text" with no injection', function() { const source = '{{ text}}{}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with injected Class name', function() { const source = '{{ text}}{ClassName}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with injected attribute', function() { const source = '{{ text}}{a="b and c"}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with injected style', function() { const source = '{{ text}}{color:red}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with injected style using a string variable', function() { const source = `{{ text}}{--stringVariable:"'string'"}`; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`text`); }); it('Renders a span "text" with two injected styles', function() { const source = '{{ text}}{color:red,background:blue}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with its own ID, overwritten with an injected ID', function() { const source = '{{#oldId text}}{#newId}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with its own attributes, overwritten with an injected attribute, plus a new one', function() { const source = '{{attrA="old",attrB="old" text}}{attrA="new",attrC="new"}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with its own attributes, overwritten with an injected attribute, ignoring "class", "style", and "id"', function() { const source = '{{attrA="old",attrB="old" text}}{attrA="new",attrC="new",class="new",style="new",id="new"}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with its own styles, appended with injected styles', function() { const source = '{{color:blue,height:10px text}}{width:10px,color:red}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders a span "text" with its own classes, appended with injected classes', function() { const source = '{{classA,classB text}}{classA,classC}'; - const rendered = Markdown.render(source); + const rendered = Markdown.render(source, 0); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('text'); }); it('Renders an emphasis element with injected Class name', function() { const source = '*emphasis*{big}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

emphasis

'); }); it('Renders a code element with injected style', function() { const source = '`code`{background:gray}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

code

'); }); it('Renders an image element with injected style', function() { const source = '![alt text](http://i.imgur.com/hMna6G0.png){position:absolute}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

alt text

'); }); it('Renders an element modified by only the first of two consecutive injections', function() { const source = '{{ text}}{color:red}{background:blue}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text{background:blue}

'); }); it('Renders an image with added attributes', function() { const source = `![homebrew mug](https://i.imgur.com/hMna6G0.png) {position:absolute,bottom:20px,left:130px,width:220px,a="b and c",d=e}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

homebrew mug

`); }); }); @@ -343,19 +343,19 @@ describe('Injection: When an injection tag follows an element', ()=>{ describe('and that element is a block', ()=>{ it('renders a div "text" with no injection', function() { const source = '{{\ntext\n}}\n{}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); it('renders a div "text" with injected Class name', function() { const source = '{{\ntext\n}}\n{ClassName}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); it('renders a div "text" with injected style', function() { const source = '{{\ntext\n}}\n{color:red}'; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); @@ -364,7 +364,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {color:red,background:blue}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); }); @@ -373,7 +373,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {--stringVariable:"'string'"}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`

text

`); }); @@ -382,7 +382,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {#newId}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); @@ -391,7 +391,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {attrA="new",attrC="new"}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); @@ -400,7 +400,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {attrA="new",attrC="new",class="new",style="new",id="new"}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); @@ -409,7 +409,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {width:10px,color:red}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); @@ -418,14 +418,14 @@ describe('Injection: When an injection tag follows an element', ()=>{ text }} {classA,classC}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); it('renders an h2 header "text" with injected class name', function() { const source = dedent`## text {ClassName}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe('

text

'); }); @@ -436,7 +436,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ | 300 | 2 | {ClassName}`; - const rendered = Markdown.render(source).trimReturns(); + const rendered = Markdown.render(source, 0).trimReturns(); expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`
Experience PointsLevel
01
3002
`); }); @@ -447,7 +447,7 @@ describe('Injection: When an injection tag follows an element', ()=>{ // - Dark Chant of the Dentists // - Divine Spell of Crossdressing // {color:red}`; - // const rendered = Markdown.render(source).trimReturns(); + // const rendered = Markdown.render(source, 0).trimReturns(); // expect(rendered, `Input:\n${source}`, { showPrefix: false }).toBe(`...`); // FIXME: expect this to be injected into