diff --git a/exec/SlyEdit.js b/exec/SlyEdit.js index 126b2fe3803bada0854a2f813d4c334ca1704a47..18cbea3cba4c49a6ab9e810fc6cdb9dffd7e61a7 100644 --- a/exec/SlyEdit.js +++ b/exec/SlyEdit.js @@ -53,6 +53,20 @@ * the sbbs/ctrl directory, and if they're not * found there, assume they're in the same * directory as the .js files. + * 2012-12-23 Eric Oulashin Version 1.17 BETA + * Started working on updating the quoting style, + * to add the "To" user's initials or first 2 + * letters of their username to the quote prefix. + * 2012-12-25 Eric Oulashin When reading quote lines, if a quote line + * contains only whitespace characters and/or > + * characters, it will make the line blank before + * adding it to gQuoteLines, to avoid weird + * issues when prefixing the quote lines. + * 2012-12-26 Eric Oulashin Updated printEditLine() to return the length of + * text actually written. Fixed a bug in + * displayMessageRectangle() that was causing some + * text lines not to be updated properly due to + * incorrectly calculating text lengths, etc. */ /* Command-line arguments: @@ -110,8 +124,8 @@ if (!console.term_supports(USER_ANSI)) } // Constants -const EDITOR_VERSION = "1.16"; -const EDITOR_VER_DATE = "2012-12-21"; +const EDITOR_VERSION = "1.17"; +const EDITOR_VER_DATE = "2012-12-26"; // Program variables @@ -131,7 +145,6 @@ if (console.screen_columns < 80) gEditLeft = 1; gEditRight = console.screen_columns; } -// Note: gQuotePrefix is declared in SlyEdit_Misc.js. // Colors var gQuoteWinTextColor = "n7k"; // Normal text color for the quote window (DCT default) @@ -139,6 +152,10 @@ var gQuoteLineHighlightColor = "nw"; // Highlighted text color for the quote w var gTextAttrs = "nw"; // The text color for edit mode var gQuoteLineColor = "nc"; // The text color for quote lines var gUseTextAttribs = false; // Will be set to true if text colors start to be used +// gQuotePrefix contains the text to prepend to quote lines. +// gQuotePrefix will later be updated to include the "To" user's +// initials or first 2 letters of their username. +var gQuotePrefix = " > "; // EDITOR_STYLE: Can be changed to mimic the look of DCT Edit or IceEdit. // The following are supported: @@ -270,6 +287,56 @@ console.ctrlkey_passthru = "+ACGKLOPQRTUVWXYZ_"; // Enable delete line in SyncTERM (Disabling ANSI Music in the process) console.write("\033[=1M"); console.clear(); + +// Read the message from name, to name, and subject from the drop file +// (msginf in the node directory). +var gMsgSubj = ""; +var gFromName = user.alias; +var gToName = gInputFilename; +var gMsgArea = ""; +var dropFileTime = -Infinity; +var dropFileName = file_getcase(system.node_dir + "msginf"); +if (dropFileName != undefined) +{ + if (file_date(dropFileName) >= dropFileTime) + { + var dropFile = new File(dropFileName); + if (dropFile.exists && dropFile.open("r")) + { + dropFileTime = dropFile.date; + info = dropFile.readAll(); + dropFile.close(); + + gFromName = info[0]; + gToName = info[1]; + gMsgSubj = info[2]; + gMsgArea = info[4]; + + // If specified in the configuration to use author's initials in + // the quote line prefix, then update gQuotePrefix to contain the + // initials or first 2 letters from gToName. + if (gConfigSettings.useQuoteLineInitials && (gToName.length > 0)) + { + // Make a copy of gToName and remove any leading, multiple, or + // trailing spaces that it might have. Then, use the initials + // or first 2 characters from it for gQuotePrefix. + var toName = trimSpaces(gToName, true, true, true); + var spaceIndex = toName.indexOf(" "); + if (spaceIndex > -1) // If a space exists, use the initials + { + gQuotePrefix = toName.charAt(0).toUpperCase(); + if (toName.length > spaceIndex+1) + gQuotePrefix += toName.charAt(spaceIndex+1).toUpperCase(); + gQuotePrefix += "> "; + } + else // A space doesn't exist; use the first 2 letters + gQuotePrefix = toName.substr(0, 2) + "> "; + } + } + } + file_remove(dropFileName); +} + // Open the quote file / message file var inputFile = new File(gInputFilename); if (inputFile.open("r", false)) @@ -286,12 +353,17 @@ if (inputFile.open("r", false)) if (typeof(textLine) == "string") { textLine = strip_ctrl(textLine); + // If the line has only whitespace and/or > characters, + // then make the line blank before putting it into + // gQuoteLines. + if (/^[\s>]+$/.test(textLine)) + textLine = ""; gQuoteLines.push(textLine); } } // If the setting to re-wrap quote lines is enabled, then do it. if (gConfigSettings.reWrapQuoteLines && (gQuoteLines.length > 0)) - wrapQuoteLines(); + wrapQuoteLines(gConfigSettings.useQuoteLineInitials); } else { @@ -328,34 +400,6 @@ if (inputFile.open("r", false)) inputFile.close(); } -// Read the message from name, to name, and subject from the drop file -// (msginf in the node directory). -var gMsgSubj = ""; -var gFromName = user.alias; -var gToName = gInputFilename; -var gMsgArea = ""; -var dropFileTime = -Infinity; -var dropFileName = file_getcase(system.node_dir + "msginf"); -if (dropFileName != undefined) -{ - if (file_date(dropFileName) >= dropFileTime) - { - var dropFile = new File(dropFileName); - if (dropFile.exists && dropFile.open("r")) - { - dropFileTime = dropFile.date; - info = dropFile.readAll(); - dropFile.close(); - - gFromName = info[0]; - gToName = info[1]; - gMsgSubj = info[2]; - gMsgArea = info[4]; - } - } - file_remove(dropFileName); -} - // If the subject is blank, set it to something. if (gMsgSubj == "") gMsgSubj = gToName.replace(/^.*[\\\/]/,''); @@ -2213,8 +2257,16 @@ function getQuoteTextLine(pIndex, pMaxWidth) var textLine = ""; if ((pIndex >= 0) && (pIndex < gQuoteLines.length)) { - if ((gQuoteLines[pIndex] != null) && (gQuoteLines[pIndex].length > 0)) - textLine = quote_msg(gQuoteLines[pIndex], pMaxWidth-1, gQuotePrefix); + if (gConfigSettings.useQuoteLineInitials) + { + if ((gQuoteLines[pIndex] != null) && (gQuoteLines[pIndex].length > 0)) + textLine = gQuoteLines[pIndex].substr(0, pMaxWidth-1); + } + else + { + if ((gQuoteLines[pIndex] != null) && (gQuoteLines[pIndex].length > 0)) + textLine = quote_msg(gQuoteLines[pIndex], pMaxWidth-1, gQuotePrefix); + } } return textLine; } @@ -2456,6 +2508,7 @@ function displayMessageRectangle(pX, pY, pWidth, pHeight, pEditLinesIndex, pClea var screenY = pY; var editLinesIndex = pEditLinesIndex; var formatStr = "%-" + pWidth + "s"; + var actualLenWritten = 0; // Actual length of text written for each line for (var rectangleLine = 0; rectangleLine < pHeight; ++rectangleLine) { // Output the correct color for the line @@ -2467,19 +2520,14 @@ function displayMessageRectangle(pX, pY, pWidth, pHeight, pEditLinesIndex, pClea // then print it; otherwise, just print spaces to blank out the line. if (typeof(gEditLines[editLinesIndex]) != "undefined") { - //printf(formatStr, gEditLines[editLinesIndex].text.substr(editLineIndex, pWidth)); - //printEditLine(pIndex, pUseColors, pStart, pLength) - // TODO: Change the false to the parameter for whether or not to allow - // message colors - printEditLine(editLinesIndex, false, editLineIndex, pWidth); + actualLenWritten = printEditLine(editLinesIndex, false, editLineIndex, pWidth); // If pClearExtraWidth is true, then if the box width is longer than // the text that was written, then output spaces to clear the rest // of the line to erase the rest of the box line. if (pClearExtraWidth) { - var displayedTextLen = gEditLines[editLinesIndex].text.length - editLineIndex; - if (pWidth > displayedTextLen) - printf("%" + (pWidth-displayedTextLen) + "s", ""); + if (pWidth > actualLenWritten) + printf("%" + +(pWidth-actualLenWritten) + "s", ""); } } else @@ -3496,10 +3544,12 @@ function doColorSelection(pCurpos, pCurrentWordLength) // pLength: Integer - The length to write. Optional. If // omitted, the entire line will be written. <= 0 can be // passed to write the entire string. +// +// Return value: The actual length of text written function printEditLine(pIndex, pUseColors, pStart, pLength) { if (typeof(pIndex) != "number") - return; + return 0; var useColors = true; var start = 0; var length = -1; @@ -3518,7 +3568,7 @@ function printEditLine(pIndex, pUseColors, pStart, pLength) // that the screen is updated correctly for (var i = 0; i < length; ++i) console.print(" "); - return; + return length; } if (start < 0) start = 0; @@ -3528,11 +3578,12 @@ function printEditLine(pIndex, pUseColors, pStart, pLength) // that the screen is updated correctly for (var i = 0; i < length; ++i) console.print(" "); - return; + return length; } //if (length > (gEditLines[pIndex].text.length - start)) // length = gEditLines[pIndex].text.length - start; + var lengthWritten = 0; if (useColors) { } @@ -3544,18 +3595,27 @@ function printEditLine(pIndex, pUseColors, pStart, pLength) { // Simplest case: start is 0 and length is negative - // Just print the entire line. + lengthWritten = gEditLines[pIndex].text.length; if (length <= 0) console.print(gEditLines[pIndex].text); else - console.print(gEditLines[pIndex].text.substr(start, length)); + { + var textToWrite = gEditLines[pIndex].text.substr(start, length); + console.print(textToWrite); + lengthWritten = textToWrite.length; + } } else { // Start is > 0 + var textToWrite = ""; if (length <= 0) - console.print(gEditLines[pIndex].text.substr(start)); + textToWrite = gEditLines[pIndex].text.substr(start); else - console.print(gEditLines[pIndex].text.substr(start, length)); + textToWrite = gEditLines[pIndex].text.substr(start, length); + console.print(textToWrite); + lengthWritten = textToWrite.length; } } + return lengthWritten; } \ No newline at end of file diff --git a/exec/SlyEdit_DCTStuff.js b/exec/SlyEdit_DCTStuff.js index f6cce88a99abbea393b15b65391329881bc5910a..76376cbd0b19ac42c673afe9ea3abd9034e3a916 100644 --- a/exec/SlyEdit_DCTStuff.js +++ b/exec/SlyEdit_DCTStuff.js @@ -1,5 +1,4 @@ -/* This contains some DCTEdit-specific functions for the Digital Distortion - * Editor which don't rely on any global variables. +/* This file contains DCTEdit-specific functions for SlyEdit. * * Author: Eric Oulashin (AKA Nightfox) * BBS: Digital Distortion @@ -880,7 +879,6 @@ function doDCTMenu(pEditLeft, pEditRight, pEditTop, pDisplayMessageRectangle, case KEY_DOWN: break; case KEY_ENTER: // Selected an item from the menu - //displayDebugText(1, 1, "Pressed Enter", null, false); // Temporary // Set userInput to the return code from the menu so that it will // be returned from this function. userInput = menuRetObj.returnVal; @@ -903,7 +901,6 @@ function doDCTMenu(pEditLeft, pEditRight, pEditTop, pDisplayMessageRectangle, continueOn = false; break; default: - //displayDebugText(1, 1, "Last key:" + userInput + ":", null, true); // Temporary break; } } diff --git a/exec/SlyEdit_IceStuff.js b/exec/SlyEdit_IceStuff.js index 7e193e987f29e47e6ec8c9496be243b71bb4b9ac..8d13550cee803f64b52a61f0b68f7470cee0a0cb 100644 --- a/exec/SlyEdit_IceStuff.js +++ b/exec/SlyEdit_IceStuff.js @@ -1,5 +1,4 @@ -/* This contains some IceEdit-specific functions for the Digital Distortion - * Editor which don't rely on any global variables. +/* This contains IceEdit-specific functions for SlyEdit. * * Author: Eric Oulashin (AKA Nightfox) * BBS: Digital Distortion diff --git a/exec/SlyEdit_Misc.js b/exec/SlyEdit_Misc.js index 0b832c524cc5bdc526a16df6939c862fa8fd89d9..c4e9d3dbe40847197c774c2ba9cbbf184981110b 100644 --- a/exec/SlyEdit_Misc.js +++ b/exec/SlyEdit_Misc.js @@ -1,5 +1,5 @@ -/* This file declares functions and variables that are used by Digital - * Distortion Editor for both DCTEdit and IceEdit modes. +/* This file declares some general helper functions and variables + * that are used by SlyEdit. * * Author: Eric Oulashin (AKA Nightfox) * BBS: Digital Distortion @@ -39,9 +39,16 @@ * was incorrectly dealing with quote lines that * were blank after the quote text. * 2012-12-21 Eric Oulashin Updated to check for the .cfg files in the - * /sbbs/ctrl directory first, and if they aren't + * sbbs/ctrl directory first, and if they aren't * there, assume they're in the same directory as * the .js file. + * 2012-12-23 Eric Oulashin Worked on updating wrapQuoteLines() and + * firstNonQuoteTxtIndex() to support putting the + * "To" user's initials before the > in quote lines. + * 2012-12-25 Eric Oulashin Updated wrapQuoteLines() to insert a > in quote + * lines right after the leading quote characters + * (if any), without a space afteward, to indicate + * an additional level of quoting. */ // Note: These variables are declared with "var" instead of "const" to avoid @@ -135,9 +142,6 @@ var CTRL_Y = "\x19"; var CTRL_Z = "\x1a"; var KEY_ESC = "\x1b"; -// gQuotePrefix contains the text to prepend to quote lines. -var gQuotePrefix = " > "; - /////////////////////////////////////////////////////////////////////////////////// // Object/class stuff @@ -309,6 +313,8 @@ function isPrintableChar(pText) // pLeading: Whether or not to trim leading spaces (optional, defaults to true) // pMultiple: Whether or not to trim multiple spaces (optional, defaults to true) // pTrailing: Whether or not to trim trailing spaces (optional, defaults to true) +// +// Return value: The trimmed string function trimSpaces(pString, pLeading, pMultiple, pTrailing) { // Make sure pString is a string. @@ -457,7 +463,7 @@ function displayGeneralHelp(pDisplayHeader, pClear, pPause) if (pDisplayHeader) displayHelpHeader(); - console.print("ncThis is a full-screen message editor that mimics the look & feel of\r\n"); + console.print("ncSlyEdit is a full-screen message editor that mimics the look & feel of\r\n"); console.print("IceEdit or DCT Edit, two popular editors. The editor is currently in " + (EDITOR_STYLE == "DCT" ? "DCT" : "Ice") + "\r\nmode.\r\n"); console.print("At the top of the screen, information about the message being written (or\r\n"); @@ -522,7 +528,7 @@ function displayProgramInfo(pDisplayHeader, pClear, pPause) EDITOR_VER_DATE + "w)"); console.center("ncby Eric Oulashin"); console.crlf(); - console.print("ncThis is a full-screen message editor written for Synchronet that mimics\r\n"); + console.print("ncSlyEdit is a full-screen message editor written for Synchronet that mimics\r\n"); console.print("the look & feel of IceEdit or DCT Edit."); console.crlf(); if (pPause) @@ -632,8 +638,9 @@ function promptYesNo(pQuestion, pDefaultYes, pBoxTitle) // Return value: An object containing the settings as properties. function ReadSlyEditConfigFile() { - // Create the configuration object - var cfgObj = new Object(); + var cfgObj = new Object(); // Configuration object + + // Default settings cfgObj.thirdPartyLoadOnStart = new Array(); cfgObj.runJSOnStart = new Array(); cfgObj.thirdPartyLoadOnExit = new Array(); @@ -643,7 +650,9 @@ function ReadSlyEditConfigFile() cfgObj.inputTimeoutMS = 300000; cfgObj.reWrapQuoteLines = true; cfgObj.allowColorSelection = true; - // Ice-style colors + cfgObj.useQuoteLineInitials = true; + + // Default Ice-style colors cfgObj.iceColors = new Object(); // Ice color theme file cfgObj.iceColors.ThemeFilename = system.ctrl_dir + "SlyIceColors_BlueIce.cfg"; @@ -676,7 +685,7 @@ function ReadSlyEditConfigFile() cfgObj.iceColors.EditMode = "ch"; cfgObj.iceColors.KeyInfoLabelColor = "ch"; - // DCT-style colors + // Default DCT-style colors cfgObj.DCTColors = new Object(); // DCT color theme file cfgObj.DCTColors.ThemeFilename = system.ctrl_dir + "SlyDCTColors_Default.cfg"; @@ -815,6 +824,8 @@ function ReadSlyEditConfigFile() cfgObj.reWrapQuoteLines = (valueUpper == "TRUE"); else if (settingUpper == "ALLOWCOLORSELECTION") cfgObj.allowColorSelection = (valueUpper == "TRUE"); + else if (settingUpper == "USEQUOTELINEINITIALS") + cfgObj.useQuoteLineInitials = (valueUpper == "TRUE"); else if (settingUpper == "ADD3RDPARTYSTARTUPSCRIPT") cfgObj.thirdPartyLoadOnStart.push(value); else if (settingUpper == "ADD3RDPARTYEXITSCRIPT") @@ -1455,6 +1466,7 @@ function firstNonQuoteTxtIndex(pStr) var retObj = new Object(); retObj.startIndex = -1; retObj.quoteLevel = 0; + retObj.begOfLine = ""; // Will store the beginning of the line, before the > // If pStr is not a valid positive-length string, then just return. if ((pStr == null) || (typeof(pStr) != "string") || (pStr.length == 0)) @@ -1465,7 +1477,7 @@ function firstNonQuoteTxtIndex(pStr) // & count the > characters from the >. var searchStartIndex = 0; // Regex notes: - // \w: Matches any alphanumerical character (word characters) including underscore (short for [a-zA-Z0-9_]) + // \w: Matches any alphanumeric character (word characters) including underscore (short for [a-zA-Z0-9_]) // ?: Supposed to match 0 or 1 occurance, but seems to match 1 or 2 var lineStartsWithQuoteText = /^ *\w?[^ ]>/.test(pStr); if (lineStartsWithQuoteText) @@ -1477,6 +1489,7 @@ function firstNonQuoteTxtIndex(pStr) // Look for the first non-quote text and quote level in the string. var strChar = ""; var j = 0; + var GTIndex = -1; // Index of a > character in the string for (var i = searchStartIndex; i < pStr.length; ++i) { strChar = pStr.charAt(i); @@ -1494,6 +1507,8 @@ function firstNonQuoteTxtIndex(pStr) ++retObj.quoteLevel; } } + // Store the beginning of the line in retObj.begOfLine + retObj.begOfLine = pStr.substr(0, retObj.startIndex); break; } } @@ -1510,15 +1525,19 @@ function firstNonQuoteTxtIndex(pStr) return retObj; } -function wrapQuoteLines() +function wrapQuoteLines(pUseAuthorInitials) { if (gQuoteLines.length == 0) return; + var useAuthorInitials = true; + if (typeof(pUseAuthorInitials) != "undefined") + useAuthorInitials = pUseAuthorInitials; + // This function checks if a string has only > characters separated by // whitespace and returns a version where the > characters are only separated - // by one space each, and if the line starts with " >", the leading space - // will be removed. + // by one space each. If the line starts with " >", the leading space will + // be removed. function normalizeGTChars(pStr) { if (/^\s*>\s*$/.test(pStr)) @@ -1532,6 +1551,8 @@ function wrapQuoteLines() return pStr; } + // Note: gQuotePrefix is declared in SlyEdit.js. + // Create an array for line information objects, and append the // first line's info to it. Also, store the first line's quote // level in the lastQuoteLevel variable. @@ -1543,23 +1564,25 @@ function wrapQuoteLines() // Loop through the array starting at the 2nd line and wrap the lines var startArrIndex = 0; var endArrIndex = 0; - var quoteStr = ""; + var quotePrefix = ""; var quoteLevel = 0; var retObj = null; var i = 0; // Index variable + var maxBegOfLineLen = 0; // For storing the length of the longest beginning of line that was removed for (var quoteLineIndex = 1; quoteLineIndex < gQuoteLines.length; ++quoteLineIndex) { retObj = firstNonQuoteTxtIndex(gQuoteLines[quoteLineIndex]); lineInfos.push(retObj); if (retObj.quoteLevel != lastQuoteLevel) { + maxBegOfLineLen = 0; endArrIndex = quoteLineIndex; // Remove the quote strings from the lines we're about to wrap for (i = startArrIndex; i < endArrIndex; ++i) { - // TODO - // Error on next line: !JavaScript TypeError: lineInfos[i] is undefined - // Fixed by checking that lineInfos[i] is not null.. but why would it be? + // lineInfos[i] is checked for null to avoid the error "!JavaScript + // TypeError: lineInfos[i] is undefined". But I'm not sure why it + // would be null.. if (lineInfos[i] != null) { if (lineInfos[i].startIndex > -1) @@ -1568,18 +1591,42 @@ function wrapQuoteLines() gQuoteLines[i] = normalizeGTChars(gQuoteLines[i]); // If the quote line now only consists of spaces after removing the quote // characters, then make it blank. - if (/^ +$/.test(gQuoteLines[i])) gQuoteLines[i] = ""; + if (/^ +$/.test(gQuoteLines[i])) + gQuoteLines[i] = ""; + // Remove leading spaces and change multiple spaces to single + // spaces in the beginning-of-line string. + lineInfos[i].begOfLine = trimSpaces(lineInfos[i].begOfLine, true, true, false); + // See if we need to update maxBegOfLineLen, and if so, do it. + if (lineInfos[i].begOfLine.length > maxBegOfLineLen) + maxBegOfLineLen = lineInfos[i].begOfLine.length; } } + // If maxBegOfLineLen is non-zero, then add 1 more to it because + // we'll be adding a > character to the quote lines to signify one + // more level of quoting. + if (maxBegOfLineLen > 0) + ++maxBegOfLineLen; + // Add gQuotePrefix's length to maxBegOfLineLen to account for that + // for wrapping the text. Note: In future versions, if we don't want + // to add the previous author's initials to all lines, then we might + // not automatically want to add this to every line. + maxBegOfLineLen += gQuotePrefix.length; // Wrap the text lines in the range we've seen // Note: 79 is assumed as the maximum line length because // that seems to be a commonly-accepted message width for - // BBSs. Also, the following length is subtracted from it: - // (2*(lastQuoteLevel+1) + gQuotePrefix.length) - // That is because we'll be prepending "> " to the quote lines, - // and then SlyEdit will prepend gQuotePrefix to them during quoting. + // BBSs. So, we need to subtract the maximum "beginning + // of line" length from 79 and use that as the wrapping + // length. var numLinesBefore = gQuoteLines.length; - wrapTextLines(gQuoteLines, startArrIndex, endArrIndex, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length)); + + // Wrap the text lines. If using new-style quote lines preservation, + // use maxBegOfLineLen as the basis of where to wrap. Otherwise (for + // older style without author initials), calculate the width based on + // the quote level and number of " > " strings we'll insert. + if (useAuthorInitials) + wrapTextLines(gQuoteLines, startArrIndex, endArrIndex, 79 - maxBegOfLineLen); + else + wrapTextLines(gQuoteLines, startArrIndex, endArrIndex, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length)); // If quote lines were added as a result of wrapping, then // determine the number of lines added, and update endArrIndex // and quoteLineIndex accordingly. @@ -1589,27 +1636,104 @@ function wrapQuoteLines() endArrIndex += numLinesAdded; quoteLineIndex += (numLinesAdded-1); // - 1 because quoteLineIndex will be incremented by the for loop } - // Put quote strings ("> ") back into the lines we just wrapped + // Put the beginnings of the wrapped lines back on them. if ((quoteLineIndex > 0) && (lastQuoteLevel > 0)) { - quoteStr = ""; - for (i = 0; i < lastQuoteLevel; ++i) - quoteStr += "> "; - for (i = startArrIndex; i < endArrIndex; ++i) - gQuoteLines[i] = quoteStr + gQuoteLines[i].replace(/^\s*>/, ">"); + // If using the author's initials in the quote lines, then + // do it the new way. Otherwise, do it the old way where + // we just insert "> " back in the beginning of the quote + // lines. + if (useAuthorInitials) + { + for (i = startArrIndex; i < endArrIndex; ++i) + { + if (lineInfos[i] != null) + { + // If the beginning of the line has a non-zero length, + // then add a > at the end to signify that this line is + // being quoted again. + var begOfLineLen = lineInfos[i].begOfLine.length; + if (begOfLineLen > 0) + { + if (lineInfos[i].begOfLine.charAt(begOfLineLen-1) == " ") + lineInfos[i].begOfLine = lineInfos[i].begOfLine.substr(0, begOfLineLen-1) + "> "; + else + lineInfos[i].begOfLine += ">"; + } + // Re-assemble the quote line + gQuoteLines[i] = lineInfos[i].begOfLine + gQuoteLines[i]; + } + else + { + // Old style: Put quote strings ("> ") back into the lines + // we just wrapped. + quotePrefix = ""; + for (i = 0; i < lastQuoteLevel; ++i) + quotePrefix += "> "; + gQuoteLines[i] = quotePrefix + gQuoteLines[i].replace(/^\s*>/, ">"); + } + } + } + else + { + // Not using author initials in the quote lines. + // Old style: Put quote strings ("> ") back into the lines + // we just wrapped. + quotePrefix = ""; + for (i = 0; i < lastQuoteLevel; ++i) + quotePrefix += "> "; + for (i = startArrIndex; i < endArrIndex; ++i) + gQuoteLines[i] = quotePrefix + gQuoteLines[i].replace(/^\s*>/, ">"); + } } + lastQuoteLevel = retObj.quoteLevel; startArrIndex = quoteLineIndex; + + if (useAuthorInitials) + { + // For quoting only the last author's lines: Insert gQuotePrefix + // to the front of the quote lines. gQuotePrefix contains the + // last message author's initials. + if (retObj.quoteLevel == 0) + { + if ((gQuoteLines[i].length > 0) && (gQuoteLines[i].indexOf(gQuotePrefix) != 0)) + gQuoteLines[i] = gQuotePrefix + gQuoteLines[i]; + } + } + } + } + + // Wrap the last block of lines: This is the block that contains + // (some of) the last message's author's reply to the quoted lines + // above it. + // Then, go through the quote lines again, and for ones that start with " >", + // remove the leading whitespace. This is because the quote string is " > ", + // so it would insert an extra space before the first > in the quote line. + // Also, if using author initials, quote the last author's lines by inserting + // gQuotePrefix to the front of the quote lines. gQuotePrefix contains the + // last message author's initials. + if (useAuthorInitials) + { + wrapTextLines(gQuoteLines, startArrIndex, gQuoteLines.length, 79 - gQuotePrefix.length); + for (i = 0; i < gQuoteLines.length; ++i) + { + // Remove leading whitespace from > characters + gQuoteLines[i] = gQuoteLines[i].replace(/^\s*>/, ">"); + // Quote the last author's lines with gQuotePrefix + if ((lineInfos[i] != null) && (lineInfos[i].quoteLevel == 0)) + { + if ((gQuoteLines[i].length > 0) && (gQuoteLines[i].indexOf(gQuotePrefix) != 0)) + gQuoteLines[i] = gQuotePrefix + gQuoteLines[i]; + } } } - // Wrap the last block of lines - wrapTextLines(gQuoteLines, startArrIndex, gQuoteLines.length, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length)); - - // Go through the quote lines again, and for ones that start with " >", remove - // the leading whitespace. This is because the quote string is " > ", so it - // would insert an extra space before the first > in the quote line. - for (i = 0; i < gQuoteLines.length; ++i) - gQuoteLines[i] = gQuoteLines[i].replace(/^\s*>/, ">"); + else + { + wrapTextLines(gQuoteLines, startArrIndex, gQuoteLines.length, 79 - (2*(lastQuoteLevel+1) + gQuotePrefix.length)); + for (i = 0; i < gQuoteLines.length; ++i) + gQuoteLines[i] = gQuoteLines[i].replace(/^\s*>/, ">"); + } } // This function displays debug text at a given location on the screen, then