ANSI replies are now importing to Mysgic correctly!
* Removed XX> prefix when in ANSI reply mode -- this borks Mystic/others * Hard code CRLF in text lines in ANSI replies - no longer try to "flow" the text (no other systems support this)
This commit is contained in:
parent
d132f3932a
commit
f6f3f8d80e
|
@ -212,9 +212,12 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
appendQuoteEntry: function(formData, extraArgs, cb) {
|
||||
// :TODO: Dont' use magic # ID's here
|
||||
const quoteMsgView = self.viewControllers.quoteBuilder.getView(1);
|
||||
|
||||
|
||||
if(self.newQuoteBlock) {
|
||||
self.newQuoteBlock = false;
|
||||
|
||||
// :TODO: If replying to ANSI, add a blank sepration line here
|
||||
|
||||
quoteMsgView.addText(self.getQuoteByHeader());
|
||||
}
|
||||
|
||||
|
@ -325,7 +328,8 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
toUserName : headerValues.to,
|
||||
fromUserName : this.client.user.username,
|
||||
subject : headerValues.subject,
|
||||
message : this.viewControllers.body.getFormData().value.message,
|
||||
// :TODO: don't hard code 1 here:
|
||||
message : this.viewControllers.body.getView(1).getData( { forceLineTerms : this.replyIsAnsi } ),
|
||||
};
|
||||
|
||||
if(this.isReply()) {
|
||||
|
@ -382,7 +386,6 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
|
|||
{
|
||||
prepped : false,
|
||||
forceLineTerm : true,
|
||||
preserveTextLines : this.message.replyToMsgId ? true : false,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -668,17 +668,12 @@ function Packet(options) {
|
|||
const dateTimeBuffer = new Buffer(ftn.getDateTimeString(message.modTimestamp) + '\0');
|
||||
dateTimeBuffer.copy(basicHeader, 14);
|
||||
|
||||
// toUserName & fromUserName: up to 36 bytes in length, NULL term'd
|
||||
// :TODO: DRY...
|
||||
let toUserNameBuf = iconv.encode(message.toUserName + '\0', 'CP437').slice(0, 36);
|
||||
toUserNameBuf[toUserNameBuf.length - 1] = '\0'; // ensure it's null term'd
|
||||
|
||||
let fromUserNameBuf = iconv.encode(message.fromUserName + '\0', 'CP437').slice(0, 36);
|
||||
fromUserNameBuf[fromUserNameBuf.length - 1] = '\0'; // ensure it's null term'd
|
||||
|
||||
// subject: up to 72 bytes in length, NULL term'd
|
||||
let subjectBuf = iconv.encode(message.subject + '\0', 'CP437').slice(0, 72);
|
||||
subjectBuf[subjectBuf.length - 1] = '\0'; // ensure it's null term'd
|
||||
//
|
||||
// To, from, and subject must be NULL term'd and have max lengths as per spec.
|
||||
//
|
||||
const toUserNameBuf = strUtil.stringToNullTermBuffer(message.toUserName, { encoding : 'cp437', maxBufLen : 36 } );
|
||||
const fromUserNameBuf = strUtil.stringToNullTermBuffer(message.fromUserName, { encoding : 'cp437', maxBufLen : 36 } );
|
||||
const subjectBuf = strUtil.stringToNullTermBuffer(message.subject, { encoding : 'cp437', maxBufLen : 72 } );
|
||||
|
||||
//
|
||||
// message: unbound length, NULL term'd
|
||||
|
@ -686,7 +681,6 @@ function Packet(options) {
|
|||
// We need to build in various special lines - kludges, area,
|
||||
// seen-by, etc.
|
||||
//
|
||||
// :TODO: Put this in it's own method
|
||||
let msgBody = '';
|
||||
|
||||
//
|
||||
|
@ -717,7 +711,6 @@ function Packet(options) {
|
|||
{
|
||||
cols : 80,
|
||||
rows : 'auto',
|
||||
preserveTextLines : true,
|
||||
forceLineTerm : true,
|
||||
exportMode : true,
|
||||
},
|
||||
|
|
|
@ -163,7 +163,10 @@ function getUTCTimeZoneOffset() {
|
|||
return moment().format('ZZ').replace(/\+/, '');
|
||||
}
|
||||
|
||||
// Get a FSC-0032 style quote prefixes
|
||||
//
|
||||
// Get a FSC-0032 style quote prefix
|
||||
// http://ftsc.org/docs/fsc-0032.001
|
||||
//
|
||||
function getQuotePrefix(name) {
|
||||
let initials;
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ const ANSI = require('./ansi_term.js');
|
|||
|
||||
const {
|
||||
prepAnsi, isAnsi,
|
||||
splitTextAtTerms
|
||||
splitTextAtTerms,
|
||||
renderSubstr
|
||||
} = require('./string_util.js');
|
||||
|
||||
// deps
|
||||
|
@ -486,7 +487,7 @@ Message.prototype.getQuoteLines = function(options, cb) {
|
|||
{
|
||||
termWidth : options.termWidth,
|
||||
termHeight : options.termHeight,
|
||||
cols : options.cols - quotePrefix.length,
|
||||
cols : options.cols,
|
||||
rows : 'auto',
|
||||
startCol : options.startCol,
|
||||
forceLineTerm : true,
|
||||
|
@ -501,14 +502,17 @@ Message.prototype.getQuoteLines = function(options, cb) {
|
|||
const focusQuoteLines = [];
|
||||
|
||||
//
|
||||
// Create items (standard) and inverted items for focus views
|
||||
// Do not include quote prefixes (e.g. XX> ) on ANSI replies (and therefor quote builder)
|
||||
// as while this works in ENiGMA, other boards such as Mystic, WWIV, etc. will try to
|
||||
// strip colors, colorize the lines, etc. If we exclude the prefixes, this seems to do
|
||||
// the trick and allow them to leave them alone!
|
||||
//
|
||||
split.forEach(l => {
|
||||
quoteLines.push(`${options.ansiResetSgr}${quotePrefix}${lastSgr}${l}`);
|
||||
focusQuoteLines.push(`${options.ansiFocusPrefixSgr}${quotePrefix}${lastSgr}${l}`);
|
||||
|
||||
quoteLines.push(`${lastSgr}${l}`);
|
||||
|
||||
focusQuoteLines.push(`${options.ansiFocusPrefixSgr}>${lastSgr}${renderSubstr(l, 0, l.length - 2)}`);
|
||||
lastSgr = (l.match(/(?:\x1b\x5b)[\?=;0-9]*m(?!.*(?:\x1b\x5b)[\?=;0-9]*m)/) || [])[0] || ''; // eslint-disable-line no-control-regex
|
||||
});
|
||||
});
|
||||
|
||||
quoteLines[quoteLines.length - 1] += options.ansiResetSgr;
|
||||
|
||||
|
|
|
@ -283,14 +283,15 @@ function MultiLineEditTextView(options) {
|
|||
return lines;
|
||||
};
|
||||
|
||||
this.getOutputText = function(startIndex, endIndex, eolMarker) {
|
||||
let lines = self.getTextLines(startIndex, endIndex);
|
||||
let text = '';
|
||||
var re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
|
||||
this.getOutputText = function(startIndex, endIndex, eolMarker, options) {
|
||||
const lines = self.getTextLines(startIndex, endIndex);
|
||||
let text = '';
|
||||
const re = new RegExp('\\t{1,' + (self.tabWidth) + '}', 'g');
|
||||
|
||||
lines.forEach(line => {
|
||||
text += line.text.replace(re, '\t');
|
||||
if(eolMarker && line.eol) {
|
||||
|
||||
if(options.forceLineTerms || (eolMarker && line.eol)) {
|
||||
text += eolMarker;
|
||||
}
|
||||
});
|
||||
|
@ -598,7 +599,6 @@ function MultiLineEditTextView(options) {
|
|||
rows : 'auto',
|
||||
startCol : this.position.col,
|
||||
forceLineTerm : options.forceLineTerm,
|
||||
preserveTextLines : options.preserveTextLines,
|
||||
},
|
||||
(err, preppedAnsi) => {
|
||||
return setLines(err ? ansi : preppedAnsi);
|
||||
|
@ -651,21 +651,6 @@ function MultiLineEditTextView(options) {
|
|||
self.setTextLines(wrapped, index, true); // true=termWithEol
|
||||
index += wrapped.length;
|
||||
});
|
||||
/*
|
||||
for(let i = 0; i < text.length; ++i) {
|
||||
wrapped = self.wordWrapSingleLine(
|
||||
text[i], // input
|
||||
'expand', // tabHandling
|
||||
self.dimens.width
|
||||
).wrapped;
|
||||
|
||||
for(let j = 0; j < wrapped.length - 1; ++j) {
|
||||
self.textLines.splice(index++, 0, { text : wrapped[j] } );
|
||||
}
|
||||
|
||||
self.textLines.splice(index++, 0, { text : wrapped[wrapped.length - 1], eol : true } );
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
this.getAbsolutePosition = function(row, col) {
|
||||
|
@ -1129,8 +1114,8 @@ MultiLineEditTextView.prototype.addText = function(text) {
|
|||
}
|
||||
};
|
||||
|
||||
MultiLineEditTextView.prototype.getData = function() {
|
||||
return this.getOutputText(0, this.textLines.length, '\r\n');
|
||||
MultiLineEditTextView.prototype.getData = function(options = { forceLineTerms : false } ) {
|
||||
return this.getOutputText(0, this.textLines.length, '\r\n', options);
|
||||
};
|
||||
|
||||
MultiLineEditTextView.prototype.setPropertyValue = function(propName, value) {
|
||||
|
|
|
@ -18,6 +18,7 @@ exports.isPrintable = isPrintable;
|
|||
exports.stripAllLineFeeds = stripAllLineFeeds;
|
||||
exports.debugEscapedString = debugEscapedString;
|
||||
exports.stringFromNullTermBuffer = stringFromNullTermBuffer;
|
||||
exports.stringToNullTermBuffer = stringToNullTermBuffer;
|
||||
exports.renderSubstr = renderSubstr;
|
||||
exports.renderStringLength = renderStringLength;
|
||||
exports.formatByteSizeAbbr = formatByteSizeAbbr;
|
||||
|
@ -216,6 +217,12 @@ function stringFromNullTermBuffer(buf, encoding) {
|
|||
return iconv.decode(buf.slice(0, nullPos), encoding || 'utf-8');
|
||||
}
|
||||
|
||||
function stringToNullTermBuffer(s, options = { encoding : 'utf8', maxBufLen : -1 } ) {
|
||||
let buf = iconv.encode( `${s}\0`, options.encoding ).slice(0, options.maxBufLen);
|
||||
buf[buf.length - 1] = '\0'; // make abs sure we null term even if truncated
|
||||
return buf;
|
||||
}
|
||||
|
||||
const PIPE_REGEXP = /(\|[A-Z\d]{2})/g;
|
||||
//const ANSI_REGEXP = /[\u001b\u009b][[()#;?]*([0-9]{1,4}(?:;[0-9]{0,4})*)?([0-9A-ORZcf-npqrsuy=><])/g;
|
||||
//const ANSI_OR_PIPE_REGEXP = new RegExp(PIPE_REGEXP.source + '|' + ANSI_REGEXP.source, 'g');
|
||||
|
@ -393,7 +400,6 @@ function prepAnsi(input, options, cb) {
|
|||
options.cols = options.cols || options.termWidth || 80;
|
||||
options.rows = options.rows || options.termHeight || 'auto';
|
||||
options.startCol = options.startCol || 1;
|
||||
options.preserveTextLines = options.preserveTextLines || false;
|
||||
options.exportMode = options.exportMode || false;
|
||||
|
||||
const canvas = Array.from( { length : 'auto' === options.rows ? 25 : options.rows }, () => Array.from( { length : options.cols}, () => new Object() ) );
|
||||
|
@ -472,7 +478,7 @@ function prepAnsi(input, options, cb) {
|
|||
let output = '';
|
||||
let lastSgr = '';
|
||||
let line;
|
||||
let textState = 'new';
|
||||
|
||||
canvas.slice(0, lastRow + 1).forEach(row => {
|
||||
const lastCol = getLastPopulatedColumn(row) + 1;
|
||||
|
||||
|
@ -486,42 +492,15 @@ function prepAnsi(input, options, cb) {
|
|||
line += `${col.sgr || ''}${col.char || ' '}`;
|
||||
}
|
||||
|
||||
if(options.preserveTextLines && !isAnsiLine(line)) {
|
||||
switch(textState) {
|
||||
case 'new' :
|
||||
line = _.trimStart(line);
|
||||
if(line) {
|
||||
if(output) {
|
||||
output += '\r\n';
|
||||
}
|
||||
|
||||
textState = 'cont';
|
||||
}
|
||||
break;
|
||||
output += line;
|
||||
|
||||
case 'cont' :
|
||||
line = ' ' + line;
|
||||
break;
|
||||
}
|
||||
if(i < row.length) {
|
||||
output += `${ANSI.blackBG()}${row.slice(i).map( () => ' ').join('')}${lastSgr}`;
|
||||
}
|
||||
|
||||
output += line;
|
||||
} else {
|
||||
if('cont' === textState) {
|
||||
output += '\r\n';
|
||||
}
|
||||
|
||||
textState = 'new';
|
||||
|
||||
output += line;
|
||||
|
||||
if(i < row.length) {
|
||||
output += `${ANSI.blackBG()}${row.slice(i).map( () => ' ').join('')}${lastSgr}`;
|
||||
}
|
||||
|
||||
//if(options.startCol + options.cols < options.termWidth || options.forceLineTerm) {
|
||||
if(options.startCol + i < options.termWidth || options.forceLineTerm) {
|
||||
output += '\r\n';
|
||||
}
|
||||
//if(options.startCol + options.cols < options.termWidth || options.forceLineTerm) {
|
||||
if(options.startCol + i < options.termWidth || options.forceLineTerm) {
|
||||
output += '\r\n';
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue