diff --git a/WHATSNEW.md b/WHATSNEW.md index 79ec152d..b457806d 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -18,6 +18,7 @@ This document attempts to track **major** changes and additions in ENiGMA½. For * Default hash tags can now be set in file areas. Simply supply an array or list of values in a file area block via `hashTags`. * Added ability to pass an `env` value (map) to `abracadabra` doors. See [Local Doors](./docs/modding/local-doors.md]). * `dropFileType` is now optional when launching doors with `abracadabra`. It can also be explicitly set to `none`. +* FSE in *view* mode can now stylize quote indicators. Supply `quoteStyleLevel1` in the `config` block. This can be a single string or an array of two strings (one to style the quotee's initials and the next for the '>' character). See the `messageAreaViewPost` menu `config` block in the default `luciano_blocktronics` `theme.hjson` file for an example. An additional level style (e.g. for nested quotes) may be added in the future. ## 0.0.11-beta * Upgraded from `alpha` to `beta` -- The software is far along and mature enough at this point! diff --git a/art/themes/luciano_blocktronics/theme.hjson b/art/themes/luciano_blocktronics/theme.hjson index 407e8a1b..a6b6e6b3 100644 --- a/art/themes/luciano_blocktronics/theme.hjson +++ b/art/themes/luciano_blocktronics/theme.hjson @@ -538,6 +538,13 @@ // The 'msg_list' module looks for this entry by default messageAreaViewPost: { + config: { + quoteStyleLevel1: [ + "|00|11", + "|00|08", + ] + } + 0: { mci: { TL1: { diff --git a/core/fse.js b/core/fse.js index ba278a01..3237a713 100644 --- a/core/fse.js +++ b/core/fse.js @@ -21,7 +21,10 @@ const { isAnsi, stripAnsiControlCodes, insert } = require('./string_util.js'); -const { stripMciColorCodes } = require('./color_codes.js'); +const { + stripMciColorCodes, + pipeToAnsi, +} = require('./color_codes.js'); const Config = require('./config.js').get; const { getAddressedToInfo } = require('./mail_util.js'); const Events = require('./events.js'); @@ -418,7 +421,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul // // Find tearline - we want to color it differently. // - const tearLinePos = this.message.getTearLinePosition(msg); + const tearLinePos = Message.getTearLinePosition(msg); if(tearLinePos > -1) { msg = insert(msg, tearLinePos, bodyMessageView.getSGRFor('text')); @@ -432,7 +435,33 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul } ); } else { - bodyMessageView.setText(stripAnsiControlCodes(msg)); + msg = stripAnsiControlCodes(msg); // start clean + + // + // In *View* mode, if enabled, do a little prep work so we can stylize: + // - Quote indicators + // - Tear lines + // - Origins + // + if (this.menuConfig.config.quoteStyleLevel1) { + let quoteStyleLevel1 = this.menuConfig.config.quoteStyleLevel1; + // can be a single style to cover XX> or an array to cover XX and > + if (!Array.isArray(quoteStyleLevel1)) { + quoteStyleLevel1 = [ quoteStyleLevel1 ]; + } + if (quoteStyleLevel1.length < 2) { + quoteStyleLevel1.push(quoteStyleLevel1); + } + + const QuoteRegex = /^ ([A-Za-z0-9]{1,2})>([ ]+)/gm; + msg = msg.replace(QuoteRegex, (m, initials, spc) => { + return pipeToAnsi( + ` ${quoteStyleLevel1[0]}${initials}${quoteStyleLevel1[1]}>${bodyMessageView.styleSGR1}${spc}` + ); + }); + } + + bodyMessageView.setText(msg); } } } diff --git a/core/message.js b/core/message.js index c5ad490b..e98baec2 100644 --- a/core/message.js +++ b/core/message.js @@ -790,7 +790,7 @@ module.exports = class Message { return ftnUtil.getQuotePrefix(this[source]); } - getTearLinePosition(input) { + static getTearLinePosition(input) { const m = input.match(/^--- .+$(?![\s\S]*^--- .+$)/m); return m ? m.index : -1; } @@ -886,12 +886,12 @@ module.exports = class Message { } ); } else { - const QUOTE_RE = /^ ((?:[A-Za-z0-9]{2}> )+(?:[A-Za-z0-9]{2}>)*) */; + const QUOTE_RE = /^ ((?:[A-Za-z0-9]{1,2}> )+(?:[A-Za-z0-9]{1,2}>)*) */; const quoted = []; const input = _.trimEnd(this.message).replace(/\x08/g, ''); // eslint-disable-line no-control-regex // find *last* tearline - let tearLinePos = this.getTearLinePosition(input); + let tearLinePos = Message.getTearLinePosition(input); tearLinePos = -1 === tearLinePos ? input.length : tearLinePos; // we just want the index or the entire string input.slice(0, tearLinePos).split(/\r\n\r\n|\n\n/).forEach(paragraph => { @@ -910,7 +910,7 @@ module.exports = class Message { if(quoted.length > 0) { // - // Preserve paragraph seperation. + // Preserve paragraph separation. // // FSC-0032 states something about leaving blank lines fully blank // (without a prefix) but it seems nicer (and more consistent with other systems) diff --git a/core/multi_line_edit_text_view.js b/core/multi_line_edit_text_view.js index 9f099b16..99100c71 100644 --- a/core/multi_line_edit_text_view.js +++ b/core/multi_line_edit_text_view.js @@ -265,11 +265,10 @@ function MultiLineEditTextView(options) { this.getRenderText = function(index) { let text = self.getVisibleText(index); - const remain = self.dimens.width - text.length; + const remain = self.dimens.width - strUtil.renderStringLength(text); if(remain > 0) { - text += ' '.repeat(remain + 1); - // text += new Array(remain + 1).join(' '); + text += ' '.repeat(remain);// + 1); } return text;