From 0b157ddd1bb12df42baa1525237271f1e85fb2e9 Mon Sep 17 00:00:00 2001 From: Nathan Byrd Date: Thu, 24 Aug 2023 18:00:02 -0500 Subject: [PATCH 1/5] Changed ansi parser to use SAUCE width when available --- core/art.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core/art.js b/core/art.js index 5e46591c..6a4da757 100644 --- a/core/art.js +++ b/core/art.js @@ -46,6 +46,16 @@ function getFontNameFromSAUCE(sauce) { } } +function getWidthFromSAUCE(sauce) { + if (sauce.Character) { + let sauceWidth = _.toNumber(sauce.Character.characterWidth); + if(!(_.isNaN(sauceWidth) && sauceWidth > 0)) { + return sauceWidth; + } + } + return null; +} + function sliceAtEOF(data, eofMarker) { let eof = data.length; const stopPos = Math.max(data.length - 256, 0); // 256 = 2 * sizeof(SAUCE) @@ -270,10 +280,18 @@ function display(client, art, options, cb) { } } + // Use width from SAUCE if available - if the width is less than the term width, + // we need to set that as the width for the parser so that wide terminals + // display correctly + let parseWidth = getWidthFromSAUCE(options.sauce); + if(_.isNil(parseWidth) || parseWidth > client.term.termWidth) { + parseWidth = client.term.termWidth; + } + const ansiParser = new aep.ANSIEscapeParser({ mciReplaceChar: options.mciReplaceChar, termHeight: client.term.termHeight, - termWidth: client.term.termWidth, + termWidth: parseWidth, trailingLF: options.trailingLF, startRow: options.startRow, }); From ccaaa71e2367176e8a481acb47e33c0dc0450398 Mon Sep 17 00:00:00 2001 From: Nathan Byrd Date: Fri, 25 Aug 2023 14:24:47 -0500 Subject: [PATCH 2/5] Make the terminal go to new line if the width of the term is greater than the art width --- core/ansi_escape_parser.js | 21 ++++++++++++++------- core/art.js | 11 ++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/core/ansi_escape_parser.js b/core/ansi_escape_parser.js index 27d5490d..76dc15b5 100644 --- a/core/ansi_escape_parser.js +++ b/core/ansi_escape_parser.js @@ -37,6 +37,10 @@ function ANSIEscapeParser(options) { this.mciReplaceChar = miscUtil.valueWithDefault(options.mciReplaceChar, ''); this.termHeight = miscUtil.valueWithDefault(options.termHeight, 25); this.termWidth = miscUtil.valueWithDefault(options.termWidth, 80); + this.breakWidth = this.termWidth; + if(!(_.isNil(options.artWidth)) && options.artWidth > 0 && options.artWidth < this.breakWidth) { + this.breakWidth = options.artWidth; + } this.trailingLF = miscUtil.valueWithDefault(options.trailingLF, 'default'); this.row = Math.min(options?.startRow ?? 1, this.termHeight); @@ -90,8 +94,8 @@ function ANSIEscapeParser(options) { switch (charCode) { case CR: - self.emit('literal', text.slice(start, pos)); - start = pos; + self.emit('literal', text.slice(start, pos + 1)); + start = pos + 1; self.column = 1; @@ -105,8 +109,8 @@ function ANSIEscapeParser(options) { self.column = 1; } - self.emit('literal', text.slice(start, pos)); - start = pos; + self.emit('literal', text.slice(start, pos + 1)); + start = pos + 1; self.row += 1; @@ -114,13 +118,16 @@ function ANSIEscapeParser(options) { break; default: - if (self.column === self.termWidth) { + if (self.column === self.breakWidth) { self.emit('literal', text.slice(start, pos + 1)); start = pos + 1; + // If the art is terminal, then we need to force the terminal to go to the next line. + if(self.column < self.termWidth) { + self.emit('literal', '\r\n'); + } self.column = 1; self.row += 1; - self.positionUpdated(); } else { self.column += 1; @@ -135,7 +142,7 @@ function ANSIEscapeParser(options) { // // Finalize this chunk // - if (self.column > self.termWidth) { + if (self.column > self.breakWidth) { self.column = 1; self.row += 1; diff --git a/core/art.js b/core/art.js index 6a4da757..100f2404 100644 --- a/core/art.js +++ b/core/art.js @@ -280,18 +280,11 @@ function display(client, art, options, cb) { } } - // Use width from SAUCE if available - if the width is less than the term width, - // we need to set that as the width for the parser so that wide terminals - // display correctly - let parseWidth = getWidthFromSAUCE(options.sauce); - if(_.isNil(parseWidth) || parseWidth > client.term.termWidth) { - parseWidth = client.term.termWidth; - } - const ansiParser = new aep.ANSIEscapeParser({ mciReplaceChar: options.mciReplaceChar, termHeight: client.term.termHeight, - termWidth: parseWidth, + termWidth: client.term.termWidth, + artWidth: getWidthFromSAUCE(options.sauce), trailingLF: options.trailingLF, startRow: options.startRow, }); From 7d46607ddc0150adf962664e3bca5fe21b61b731 Mon Sep 17 00:00:00 2001 From: Nathan Byrd Date: Fri, 25 Aug 2023 14:33:28 -0500 Subject: [PATCH 3/5] Updated the WHATSNEW to include info about the art change. --- WHATSNEW.md | 1 + 1 file changed, 1 insertion(+) diff --git a/WHATSNEW.md b/WHATSNEW.md index 060bf502..107bd533 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -9,6 +9,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For * Finally, the system will search for `index.html` and `index.htm` in that order, if another suitable route cannot be established. * CombatNet has shut down, so the module (`combatnet.js`) has been removed. * The Menu Flag `popParent` has been removed and `noHistory` has been updated to work as expected. In general things should "Just Work", but check your `menu.hjson` entries if you see menu stack issues. +* Art handling has been changed to respect the art width contained in SAUCE when present in the case where the terminal width is greater than the art width. This fixes art files that assume wrapping at 80 columns on wide (mostly new utf8) terminals. ## 0.0.13-beta * **Note for contributors**: ENiGMA has switched to [Prettier](https://prettier.io) for formatting/style. Please see [CONTRIBUTING](CONTRIBUTING.md) and the Prettier website for more information. From bf0bf830535c13aff64fbf556e54ad1f062d271f Mon Sep 17 00:00:00 2001 From: Nathan Byrd Date: Fri, 25 Aug 2023 14:38:32 -0500 Subject: [PATCH 4/5] Small logic change to improve SAUCE handling --- core/art.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/art.js b/core/art.js index 100f2404..2261585f 100644 --- a/core/art.js +++ b/core/art.js @@ -49,7 +49,7 @@ function getFontNameFromSAUCE(sauce) { function getWidthFromSAUCE(sauce) { if (sauce.Character) { let sauceWidth = _.toNumber(sauce.Character.characterWidth); - if(!(_.isNaN(sauceWidth) && sauceWidth > 0)) { + if(!(_.isNaN(sauceWidth)) && sauceWidth > 0) { return sauceWidth; } } From 8758722b6b7b3ebc1956031ec9eefcd2c6c2c73b Mon Sep 17 00:00:00 2001 From: Nathan Byrd Date: Fri, 25 Aug 2023 18:34:45 -0500 Subject: [PATCH 5/5] Fixed PR review comments --- core/ansi_escape_parser.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/ansi_escape_parser.js b/core/ansi_escape_parser.js index 76dc15b5..99411102 100644 --- a/core/ansi_escape_parser.js +++ b/core/ansi_escape_parser.js @@ -38,7 +38,9 @@ function ANSIEscapeParser(options) { this.termHeight = miscUtil.valueWithDefault(options.termHeight, 25); this.termWidth = miscUtil.valueWithDefault(options.termWidth, 80); this.breakWidth = this.termWidth; - if(!(_.isNil(options.artWidth)) && options.artWidth > 0 && options.artWidth < this.breakWidth) { + // toNumber takes care of null, undefined etc as well. + let artWidth = _.toNumber(options.artWidth); + if(!(_.isNaN(artWidth)) && artWidth > 0 && artWidth < this.breakWidth) { this.breakWidth = options.artWidth; } this.trailingLF = miscUtil.valueWithDefault(options.trailingLF, 'default'); @@ -122,7 +124,7 @@ function ANSIEscapeParser(options) { self.emit('literal', text.slice(start, pos + 1)); start = pos + 1; - // If the art is terminal, then we need to force the terminal to go to the next line. + // If we hit breakWidth before termWidth then we need to force the terminal to go to the next line. if(self.column < self.termWidth) { self.emit('literal', '\r\n'); }