From aec958249aa96012794fc631beafdf7be9e0cace Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Mar 2025 10:21:22 +1300 Subject: [PATCH 01/16] Add automatic pageNumber variable to globalVarsList --- shared/naturalcrit/markdown.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index bed109772..38397873c 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -902,7 +902,12 @@ let globalPageNumber = 0; const Markdown = { marked : Marked, render : (rawBrewText, pageNumber=0)=>{ - globalVarsList[pageNumber] = {}; //Reset global links for current page, to ensure values are parsed in order + globalVarsList[pageNumber] = { //Reset global links for current page, to ensure values are parsed in order + 'pageNumber' : { //Add document variables for this page + content : pageNumber + 1, + resolved : true + } + }; varsQueue = []; //Could move into MarkedVariables() globalPageNumber = pageNumber; if(pageNumber==0) { From edc4f8ec63f654a874e62fcdd496e764bd8071ca Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Wed, 12 Mar 2025 13:28:43 +1300 Subject: [PATCH 02/16] Change to increment previous --- shared/naturalcrit/markdown.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 38397873c..069d09dbd 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -902,9 +902,10 @@ let globalPageNumber = 0; const Markdown = { marked : Marked, render : (rawBrewText, pageNumber=0)=>{ + const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].pageNumber.content : 0; globalVarsList[pageNumber] = { //Reset global links for current page, to ensure values are parsed in order 'pageNumber' : { //Add document variables for this page - content : pageNumber + 1, + content : !isNaN(Number(lastPageNumber)) ? Number(lastPageNumber) + 1 : lastPageNumber, resolved : true } }; From e787a688598b0aa66cee5afcecfb115b2c0193fd Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 10:49:59 +1300 Subject: [PATCH 03/16] Add roman numeral package --- package-lock.json | 7 +++++++ package.json | 1 + 2 files changed, 8 insertions(+) diff --git a/package-lock.json b/package-lock.json index ac8ca11af..35bc0c147 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,6 +48,7 @@ "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", "react-router": "^7.3.0", + "romans": "^3.0.0", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" @@ -12058,6 +12059,12 @@ "inherits": "^2.0.1" } }, + "node_modules/romans": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/romans/-/romans-3.0.0.tgz", + "integrity": "sha512-7DDsAfhtpRr/ZFQXiHDrC3Pe00agcAsFiNt5nNx4ZAQlsc6yJG0mvXA5WAvO8YZyOg349twm2GYhHLw7rCXAzw==", + "license": "MIT" + }, "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", diff --git a/package.json b/package.json index 50dda84ce..43638d326 100644 --- a/package.json +++ b/package.json @@ -122,6 +122,7 @@ "react-dom": "^18.3.1", "react-frame-component": "^4.1.3", "react-router": "^7.3.0", + "romans": "^3.0.0", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" From b67eb59461e84df5d32f20241a4950c48f979148 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 10:50:18 +1300 Subject: [PATCH 04/16] Add Roman numerals function --- shared/naturalcrit/markdown.js | 39 ++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 069d09dbd..93567a4d7 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -8,6 +8,7 @@ import { markedSmartypantsLite as MarkedSmartypantsLite } import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHeadingIDs } from 'marked-gfm-heading-id'; import { markedEmoji as MarkedEmojis } from 'marked-emoji'; import MarkedSubSuperText from 'marked-subsuper-text'; +import { romanize } from 'romans'; //Icon fonts included so they can appear in emoji autosuggest dropdown import diceFont from '../../themes/fonts/iconFonts/diceFont.js'; @@ -59,6 +60,16 @@ mathParser.functions.signed = function (a) { if(a >= 0) return `+${a}`; return `${a}`; }; +// Add Roman numeral functions +mathParser.functions.toRomans = function (a) { + return romanize(a); +}; +mathParser.functions.toRomansUpper = function (a) { + return romanize(a).toUpperCase(); +}; +mathParser.functions.toRomansLower = function (a) { + return romanize(a).toLowerCase(); +}; //Processes the markdown within an HTML block if it's just a class-wrapper renderer.html = function (token) { @@ -86,8 +97,8 @@ renderer.paragraph = function(token){ //Fix local links in the Preview iFrame to link inside the frame renderer.link = function (token) { - let {href, title, tokens} = token; - const text = this.parser.parseInline(tokens) + let { href, title, tokens } = token; + const text = this.parser.parseInline(tokens); let self = false; if(href[0] == '#') { self = true; @@ -110,7 +121,7 @@ renderer.link = function (token) { // Expose `src` attribute as `--HB_src` to make the URL accessible via CSS renderer.image = function (token) { - let {href, title, text} = token; + const { href, title, text } = token; if(href === null) return text; @@ -776,7 +787,7 @@ Marked.use({ extensions : [justifiedParagraphs, definitionListsMultiLine, defini Marked.use(mustacheInjectBlock); Marked.use(MarkedSubSuperText()); Marked.use({ renderer: renderer, tokenizer: tokenizer, mangle: false }); -Marked.use(MarkedExtendedTables({interruptPatterns : tableTerminators}), MarkedGFMHeadingId({ globalSlugs: true }), +Marked.use(MarkedExtendedTables({ interruptPatterns: tableTerminators }), MarkedGFMHeadingId({ globalSlugs: true }), MarkedSmartypantsLite(), MarkedEmojis(MarkedEmojiOptions)); function cleanUrl(href) { @@ -841,12 +852,12 @@ const processStyleTags = (string)=>{ obj[key.trim()] = value.trim(); return obj; }, {}) || null; - const styles = tags?.length ? tags.reduce((styleObj, style) => { - const index = style.indexOf(':'); - const [key, value] = [style.substring(0, index), style.substring(index + 1)]; - styleObj[key.trim()] = value.replace(/"?([^"]*)"?/g, '$1').trim(); - return styleObj; - }, {}) : null; + const styles = tags?.length ? tags.reduce((styleObj, style)=>{ + const index = style.indexOf(':'); + const [key, value] = [style.substring(0, index), style.substring(index + 1)]; + styleObj[key.trim()] = value.replace(/"?([^"]*)"?/g, '$1').trim(); + return styleObj; + }, {}) : null; return { id : id, @@ -862,8 +873,8 @@ const extractHTMLStyleTags = (htmlString)=>{ const id = firstElementOnly.match(/id="([^"]*)"/)?.[1] || null; const classes = firstElementOnly.match(/class="([^"]*)"/)?.[1] || null; const styles = firstElementOnly.match(/style="([^"]*)"/)?.[1] - ?.split(';').reduce((styleObj, style) => { - if (style.trim() === '') return styleObj; + ?.split(';').reduce((styleObj, style)=>{ + if(style.trim() === '') return styleObj; const index = style.indexOf(':'); const [key, value] = [style.substring(0, index), style.substring(index + 1)]; styleObj[key.trim()] = value.trim(); @@ -873,7 +884,7 @@ const extractHTMLStyleTags = (htmlString)=>{ ?.filter((attr)=>!attr.startsWith('class="') && !attr.startsWith('style="') && !attr.startsWith('id="')) .reduce((obj, attr)=>{ const index = attr.indexOf('='); - let [key, value] = [attr.substring(0, index), attr.substring(index + 1)]; + const [key, value] = [attr.substring(0, index), attr.substring(index + 1)]; obj[key.trim()] = value.replace(/"/g, ''); return obj; }, {}) || null; @@ -886,7 +897,7 @@ const extractHTMLStyleTags = (htmlString)=>{ }; }; -const mergeHTMLTags = (originalTags, newTags) => { +const mergeHTMLTags = (originalTags, newTags)=>{ return { id : newTags.id || originalTags.id || null, classes : [originalTags.classes, newTags.classes].join(' ').trim() || null, From ee543b7090fd2d1cdd493041b3a0a8a642140923 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 11:59:12 +1300 Subject: [PATCH 05/16] Add int to char functions --- shared/naturalcrit/markdown.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 93567a4d7..de2a5aeec 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -70,6 +70,20 @@ mathParser.functions.toRomansUpper = function (a) { mathParser.functions.toRomansLower = function (a) { return romanize(a).toLowerCase(); }; +// Add character functions +mathParser.functions.toChar = function (a) { + if(a <= 0) return a; + const genChars = function (i) { + return (i > 26 ? genChars(Math.floor((i - 1) / 26)) : '') + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'[(i - 1) % 26]; + }; + return genChars(a); +}; +mathParser.functions.toCharUpper = function (a) { + return mathParser.functions.toChar(a).toUpperCase(); +}; +mathParser.functions.toCharLower = function (a) { + return mathParser.functions.toChar(a).toLowerCase(); +}; //Processes the markdown within an HTML block if it's just a class-wrapper renderer.html = function (token) { From 7371f57ded96ffba18a8e3824f4d5b79e46b5b58 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 12:21:53 +1300 Subject: [PATCH 06/16] Add written number package --- package-lock.json | 9 ++++++++- package.json | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35bc0c147..d9c8cbc7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,7 +51,8 @@ "romans": "^3.0.0", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", - "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" + "vitreum": "git+https://git@github.com/calculuschild/vitreum.git", + "written-number": "^0.11.1" }, "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", @@ -14848,6 +14849,12 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/written-number": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/written-number/-/written-number-0.11.1.tgz", + "integrity": "sha512-LhQ68uUnzHH0bwm/QiGA9JwqgadSDOwqB2AIs/LBsrOY6ScqVXKRN2slTCeKAhstDBJ/Of/Yxcjn0pnQmVlmtg==", + "license": "MIT" + }, "node_modules/ws": { "version": "7.5.10", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", diff --git a/package.json b/package.json index 43638d326..6d59138f6 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,8 @@ "romans": "^3.0.0", "sanitize-filename": "1.6.3", "superagent": "^10.1.1", - "vitreum": "git+https://git@github.com/calculuschild/vitreum.git" + "vitreum": "git+https://git@github.com/calculuschild/vitreum.git", + "written-number": "^0.11.1" }, "devDependencies": { "@stylistic/stylelint-plugin": "^3.1.2", From 543d18f9d942bf64fd45e41c1286d8489a2eb246 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 12:22:08 +1300 Subject: [PATCH 07/16] Add written number functions --- shared/naturalcrit/markdown.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index de2a5aeec..fda410c36 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -9,6 +9,7 @@ import { gfmHeadingId as MarkedGFMHeadingId, resetHeadings as MarkedGFMResetHead import { markedEmoji as MarkedEmojis } from 'marked-emoji'; import MarkedSubSuperText from 'marked-subsuper-text'; import { romanize } from 'romans'; +import writtenNumber from 'written-number'; //Icon fonts included so they can appear in emoji autosuggest dropdown import diceFont from '../../themes/fonts/iconFonts/diceFont.js'; @@ -84,6 +85,22 @@ mathParser.functions.toCharUpper = function (a) { mathParser.functions.toCharLower = function (a) { return mathParser.functions.toChar(a).toLowerCase(); }; +// Add word functions +mathParser.functions.toWords = function (a) { + return writtenNumber(a); +}; +mathParser.functions.toWordsUpper = function (a) { + return mathParser.functions.toWords(a).toUpperCase(); +}; +mathParser.functions.toWordsLower = function (a) { + return mathParser.functions.toWords(a).toLowerCase(); +}; +mathParser.functions.toWordsCamel = function (a) { + const words = mathParser.functions.toWords(a).split(' '); + return words.map((word)=>{ + return _.capitalize(word); + }).join(' '); +}; //Processes the markdown within an HTML block if it's just a class-wrapper renderer.html = function (token) { From 44a01f27fe48799fcab04a02a3e70fcf016cb6e0 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 13:58:06 +1300 Subject: [PATCH 08/16] Add tests for custom math functions --- tests/markdown/variables.test.js | 74 ++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index 41259da7e..96400d834 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -410,4 +410,78 @@ describe('Regression Tests', ()=>{ const rendered = Markdown.render(source).trimReturns(); expect(rendered).toBe('
title 1title 2title 3title 4
fooIpsum))
'); }); +}); + +describe('Custom Math Function Tests', ()=>{ + it('Sign Test', function() { + const source = `[a]: 13\n\n[b]: -11\n\nPositive: $[sign(a)]\n\nNegative: $[sign(b)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Positive: +

Negative: -

'); + }); + + it('Signed Test', function() { + const source = `[a]: 13\n\n[b]: -11\n\nPositive: $[signed(a)]\n\nNegative: $[signed(b)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Positive: +13

Negative: -11

'); + }); + + it('Roman Numerals Test', function() { + const source = `[a]: 18\n\nRoman Numeral: $[toRomans(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Roman Numeral: XVIII

'); + }); + + it('Roman Numerals Test - Uppercase', function() { + const source = `[a]: 18\n\nRoman Numeral: $[toRomansUpper(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Roman Numeral: XVIII

'); + }); + + it('Roman Numerals Test - Lowercase', function() { + const source = `[a]: 18\n\nRoman Numeral: $[toRomansLower(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Roman Numeral: xviii

'); + }); + + it('Number to Characters Test', function() { + const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toChar(a)] $[toChar(b)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Characters: R AM

'); + }); + + it('Number to Characters Test - Uppercase', function() { + const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toCharUpper(a)] $[toCharUpper(b)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Characters: R AM

'); + }); + + it('Number to Characters Test - Lowercase', function() { + const source = `[a]: 18\n\n[b]: 39\n\nCharacters: $[toCharLower(a)] $[toCharLower(b)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Characters: r am

'); + }); + + it('Number to Words Test', function() { + const source = `[a]: 80085\n\nWords: $[toWords(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Words: eighty thousand and eighty-five

'); + }); + + it('Number to Words Test - Uppercase', function() { + const source = `[a]: 80085\n\nWords: $[toWordsUpper(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Words: EIGHTY THOUSAND AND EIGHTY-FIVE

'); + }); + + it('Number to Words Test - Lowercase', function() { + const source = `[a]: 80085\n\nWords: $[toWordsLower(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Words: eighty thousand and eighty-five

'); + }); + + it('Number to Words Test - Camelcase', function() { + const source = `[a]: 80085\n\nWords: $[toWordsCamel(a)]`; + const rendered = Markdown.render(source).trimReturns(); + expect(rendered).toBe('

Words: Eighty Thousand And Eighty-five

'); + }); }); \ No newline at end of file From 8b9e084b17ab67a165c787b753ed46aa366946db Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 14:16:41 +1300 Subject: [PATCH 09/16] Add variable page numbering snippet --- themes/V3/Blank/snippets.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/themes/V3/Blank/snippets.js b/themes/V3/Blank/snippets.js index e92e757cf..16b18ef01 100644 --- a/themes/V3/Blank/snippets.js +++ b/themes/V3/Blank/snippets.js @@ -36,6 +36,11 @@ module.exports = [ icon : 'fas fa-sort-numeric-down', gen : '{{pageNumber,auto}}\n' }, + { + name : 'Variable Auto Page Number', + icon : 'fas fa-sort-numeric-down', + gen : '{{pageNumber $[pageNumber]}}\n' + }, { name : 'Skip Page Number Increment this Page', icon : 'fas fa-xmark', From baafb6d2f9dc350ee2ea571ff5ec5c0fa6fac8b8 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 13 Mar 2025 14:54:45 +1300 Subject: [PATCH 10/16] Tweak camelcase function --- shared/naturalcrit/markdown.js | 4 +++- tests/markdown/variables.test.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index fda410c36..f8b79e286 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -98,7 +98,9 @@ mathParser.functions.toWordsLower = function (a) { mathParser.functions.toWordsCamel = function (a) { const words = mathParser.functions.toWords(a).split(' '); return words.map((word)=>{ - return _.capitalize(word); + return word.replace(/(?:^|\b|\s)(\w)/g, function(w, index) { + return index === 0 ? w.toLowerCase() : w.toUpperCase(); + }); }).join(' '); }; diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index 96400d834..8c58f4925 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -482,6 +482,6 @@ describe('Custom Math Function Tests', ()=>{ it('Number to Words Test - Camelcase', function() { const source = `[a]: 80085\n\nWords: $[toWordsCamel(a)]`; const rendered = Markdown.render(source).trimReturns(); - expect(rendered).toBe('

Words: Eighty Thousand And Eighty-five

'); + expect(rendered).toBe('

Words: Eighty Thousand And Eighty-Five

'); }); }); \ No newline at end of file From f4afc91df71aaff9c7228afdf850abeff782337c Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Fri, 14 Mar 2025 08:08:30 +1300 Subject: [PATCH 11/16] Rename toWordsCamel to toWordsCaps --- shared/naturalcrit/markdown.js | 2 +- tests/markdown/variables.test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index f8b79e286..1ab70eac7 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -95,7 +95,7 @@ mathParser.functions.toWordsUpper = function (a) { mathParser.functions.toWordsLower = function (a) { return mathParser.functions.toWords(a).toLowerCase(); }; -mathParser.functions.toWordsCamel = function (a) { +mathParser.functions.toWordsCaps = function (a) { const words = mathParser.functions.toWords(a).split(' '); return words.map((word)=>{ return word.replace(/(?:^|\b|\s)(\w)/g, function(w, index) { diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index 8c58f4925..3773097ab 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -479,8 +479,8 @@ describe('Custom Math Function Tests', ()=>{ expect(rendered).toBe('

Words: eighty thousand and eighty-five

'); }); - it('Number to Words Test - Camelcase', function() { - const source = `[a]: 80085\n\nWords: $[toWordsCamel(a)]`; + it('Number to Words Test - Capitalized', function() { + const source = `[a]: 80085\n\nWords: $[toWordsCaps(a)]`; const rendered = Markdown.render(source).trimReturns(); expect(rendered).toBe('

Words: Eighty Thousand And Eighty-Five

'); }); From 9a26626412fbcfee06c0c3893a3faae8d1418bfe Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Fri, 14 Mar 2025 08:12:30 +1300 Subject: [PATCH 12/16] Change automatic var name to HB_PageNumber --- shared/naturalcrit/markdown.js | 2 +- themes/V3/Blank/snippets.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 1ab70eac7..92e063e5a 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -948,7 +948,7 @@ const Markdown = { render : (rawBrewText, pageNumber=0)=>{ const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].pageNumber.content : 0; globalVarsList[pageNumber] = { //Reset global links for current page, to ensure values are parsed in order - 'pageNumber' : { //Add document variables for this page + 'HB_PageNumber' : { //Add document variables for this page content : !isNaN(Number(lastPageNumber)) ? Number(lastPageNumber) + 1 : lastPageNumber, resolved : true } diff --git a/themes/V3/Blank/snippets.js b/themes/V3/Blank/snippets.js index 16b18ef01..067c35a83 100644 --- a/themes/V3/Blank/snippets.js +++ b/themes/V3/Blank/snippets.js @@ -39,7 +39,7 @@ module.exports = [ { name : 'Variable Auto Page Number', icon : 'fas fa-sort-numeric-down', - gen : '{{pageNumber $[pageNumber]}}\n' + gen : '{{pageNumber $[HB_PageNumber]}}\n' }, { name : 'Skip Page Number Increment this Page', From 20f0d16a58ed149c0a85051c85f4d996d7d31ccc Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Fri, 14 Mar 2025 08:18:30 +1300 Subject: [PATCH 13/16] Fix missed var name update --- shared/naturalcrit/markdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 92e063e5a..9c38487b6 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -946,7 +946,7 @@ let globalPageNumber = 0; const Markdown = { marked : Marked, render : (rawBrewText, pageNumber=0)=>{ - const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].pageNumber.content : 0; + const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].HB_PageNumber.content : 0; globalVarsList[pageNumber] = { //Reset global links for current page, to ensure values are parsed in order 'HB_PageNumber' : { //Add document variables for this page content : !isNaN(Number(lastPageNumber)) ? Number(lastPageNumber) + 1 : lastPageNumber, From 6ec37d3fa46451e8fbe2a5d155d60a06d88ad82a Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 27 Mar 2025 12:03:00 +1300 Subject: [PATCH 14/16] Rename HB_PageNumber to HB_pageNumber --- shared/naturalcrit/markdown.js | 4 ++-- themes/V3/Blank/snippets.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shared/naturalcrit/markdown.js b/shared/naturalcrit/markdown.js index 251c8d3bc..a0a5f3a00 100644 --- a/shared/naturalcrit/markdown.js +++ b/shared/naturalcrit/markdown.js @@ -951,9 +951,9 @@ let globalPageNumber = 0; const Markdown = { marked : Marked, render : (rawBrewText, pageNumber=0)=>{ - const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].HB_PageNumber.content : 0; + const lastPageNumber = pageNumber > 0 ? globalVarsList[pageNumber - 1].HB_pageNumber.content : 0; globalVarsList[pageNumber] = { //Reset global links for current page, to ensure values are parsed in order - 'HB_PageNumber' : { //Add document variables for this page + 'HB_pageNumber' : { //Add document variables for this page content : !isNaN(Number(lastPageNumber)) ? Number(lastPageNumber) + 1 : lastPageNumber, resolved : true } diff --git a/themes/V3/Blank/snippets.js b/themes/V3/Blank/snippets.js index 65af13aef..c5198fd87 100644 --- a/themes/V3/Blank/snippets.js +++ b/themes/V3/Blank/snippets.js @@ -41,7 +41,7 @@ module.exports = [ { name : 'Variable Auto Page Number', icon : 'fas fa-sort-numeric-down', - gen : '{{pageNumber $[HB_PageNumber]}}\n' + gen : '{{pageNumber $[HB_pageNumber]}}\n' }, { name : 'Skip Page Number Increment this Page', From 65001c44e6690b4afc35a0c12cf81b11ee5ecfff Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 27 Mar 2025 12:03:22 +1300 Subject: [PATCH 15/16] Add tests for variable page numbering --- tests/markdown/variables.test.js | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index bba1341e1..1f9d8b55a 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -370,6 +370,22 @@ describe('Cross-page variables', ()=>{ const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

two

one

\\page

two

'); }); + + it('Page numbering across pages', function() { + const source0 = `$[HB_pageNumber]\n\n`; + const source1 = `$[HB_pageNumber]\n\n`; + renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up + const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); + expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

1

\\page

2

'); + }); + + it('Page numbering across pages - custom page number', function() { + const source0 = `[HB_pageNumber]:100\n\n$[HB_pageNumber]\n\n`; + const source1 = `$[HB_pageNumber]\n\n`; + renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up + const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); + expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

100

\\page

101

'); + }); }); describe('Math function parameter handling', ()=>{ @@ -410,7 +426,7 @@ describe('Regression Tests', ()=>{ const rendered = Markdown.render(source).trimReturns(); expect(rendered).toBe('
title 1title 2title 3title 4
fooIpsum))
'); }); - + it('Handle Extra spaces in image alt-text 1', function(){ const source='![ where is my image??](http://i.imgur.com/hMna6G0.png)'; const rendered = Markdown.render(source).trimReturns(); @@ -433,7 +449,7 @@ describe('Regression Tests', ()=>{ const source='![where is my image??](http://i.imgur.com/hMna6G0.png){height=20%,width=20%}'; const rendered = Markdown.render(source).trimReturns(); expect(rendered).toBe('

\"where

'); - }); + }); }); describe('Custom Math Function Tests', ()=>{ From 848c68689d2741e23a4657bd3d4941fe631e2b32 Mon Sep 17 00:00:00 2001 From: "G.Ambatte" Date: Thu, 27 Mar 2025 12:09:58 +1300 Subject: [PATCH 16/16] Add NaN custom pageNumber test --- tests/markdown/variables.test.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index 1f9d8b55a..ea98fe56c 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -371,7 +371,7 @@ describe('Cross-page variables', ()=>{ expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

two

one

\\page

two

'); }); - it('Page numbering across pages', function() { + it('Page numbering across pages : default', function() { const source0 = `$[HB_pageNumber]\n\n`; const source1 = `$[HB_pageNumber]\n\n`; renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up @@ -379,13 +379,21 @@ describe('Cross-page variables', ()=>{ expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

1

\\page

2

'); }); - it('Page numbering across pages - custom page number', function() { + it('Page numbering across pages : custom page number (Number)', function() { const source0 = `[HB_pageNumber]:100\n\n$[HB_pageNumber]\n\n`; const source1 = `$[HB_pageNumber]\n\n`; renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

100

\\page

101

'); }); + + it('Page numbering across pages : custom page number (NaN)', function() { + const source0 = `[HB_pageNumber]:a\n\n$[HB_pageNumber]\n\n`; + const source1 = `$[HB_pageNumber]\n\n`; + renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); //Requires one full render of document before hoisting is picked up + const rendered = renderAllPages([source0, source1]).join('\n\\page\n').trimReturns(); + expect(rendered, `Input:\n${[source0, source1].join('\n\\page\n')}`, { showPrefix: false }).toBe('

a

\\page

a

'); + }); }); describe('Math function parameter handling', ()=>{