diff --git a/exec/textedit.js b/exec/textedit.js new file mode 100644 index 0000000000000000000000000000000000000000..5574112686a3d830060314e8c7821908dc6cde90 --- /dev/null +++ b/exec/textedit.js @@ -0,0 +1,369 @@ +require("key_defs.js", "KEY_UP"); + +const a = "\x01"; +var msg = 1; +var tnames = ["None"]; +var last_entry = 0; +var pos = 0; +var len = 0; +var msglens = []; +var displaywith = 0; + +var details = { + 'AutoMsg': { + 'displaywith': 1, + }, + 'DirLibOrAll': { + 'displaywith': 1, + }, + 'JoinWhichDir': { + 'displaywith': 1, + }, + 'JoinWhichGrp': { + 'displaywith': 1, + }, + 'JoinWhichLib': { + 'displaywith': 1, + }, + 'JoinWhichSub': { + 'displaywith': 1, + }, + 'MsgSubj': { + 'args': ['Example message subject (up to 70 characters).........................'], + }, + 'NodeToPrivateChat': { + 'displaywith': 1, + }, + 'NScanCfgWhichGrp': { + 'displaywith': 1, + }, + 'NScanCfgWhichSub': { + 'displaywith': 1, + }, + 'PrivateMsgPrompt': { + 'displaywith': 1, + }, + 'ProtocolBatchOrQuit': { + 'displaywith': 1, + }, + 'ProtocolBatchQuitOrNext': { + 'displaywith': 1, + }, + 'ProtocolOrQuit': { + 'displaywith': 1, + }, + 'QuitOrNext': { + 'displaywith': 1, + }, + 'RExemptRemoveFilePrompt': { + 'displaywith': 1, + }, + 'SetMsgPtrPrompt': { + 'displaywith': 1, + }, + 'SScanCfgWhichGrp': { + 'displaywith': 1, + }, + 'SScanCfgWhichSub': { + 'displaywith': 1, + }, + 'SubGroupOrAll': { + 'displaywith': 1, + }, + 'SysopRemoveFilePrompt': { + 'displaywith': 1, + }, + 'TelnetGatewayPrompt': { + 'displaywith': 1, + }, + 'UserRemoveFilePrompt': { + 'displaywith': 1, + }, + 'VoteInThisPollNow': { + 'displaywith': 1, + }, + 'VoteMsgUpDownOrQuit': { + 'displaywith': 1, + }, + 'WhichOrAll': { + 'displaywith': 1, + }, + 'WhichTextFile': { + 'displaywith': 1, + }, + 'WhichTextFileSysop': { + 'displaywith': 1, + }, + 'WhichTextSection': { + 'displaywith': 1, + }, +} + +console.cleartoeos = function(attr) +{ + if (attr !== undefined) + console.attributes = attr; + console.write("\x1b[J"); +} + +function format_entry(str) +{ + // bbs.command_str = '@'; + // .replace(/@/g, "@U+40:@@") + return str.replace(/[\x00-\x1F]/g, function(match) { + switch(match) { + case '\n': + return "\\n"; + case '\r': + return "\\r"; + case '\v': + return "\\v"; + case '\t': + return "\\v"; + case '\b': + return "\\b"; + case '\f': + return "\\f"; + default: + return '\x01'+'7\x01'+'B^' + String.fromCharCode(match.charCodeAt(0)+64) + "\x01"+'0\x01'+'w'; + } + }); +} + +function scanargs(str) +{ + var arg = 0; + var ret = []; + // No patchAll or iterators in for... *sigh* + var re = /%(?:([1-9][0-9]*)$)?([-#0 +]*)(\*|[0-9]+)?(?:.(\*|[0-9]+))?(hh|h|l|ll|j|t|z|L)?([diouxXDOUeEfFgGaAcCsSPnm%])/g; + var match; + + while ((match = re.exec(str)) !== null) { + if (arg >= ret.length) + ret.push(undefined); + if (match[1] != undefined) + arg = parseInt(m[1], 10) - 1; + if (match[3] == '*') { + ret[arg] = 'minwidth'; + arg++; + if (arg >= ret.length) + ret.push(undefined); + } + if (match[3] == '*') { + ret[arg] = 'precision'; + arg++; + if (arg >= ret.length) + ret.push(undefined); + } + ret[arg] = match[6]; + arg++; + } + return ret; +} + +function formatted(str, num) +{ + var args = [str]; + if (details[tnames[num]] !== undefined && details[tnames[num]].args !== undefined) + args.push.apply(args, details[tnames[num]].args); + else { + var types = scanargs(str); + var type; + var strs = 0; + for (type in types) { + switch (types[type]) { + case 'D': + case 'd': + case 'i': + args.push(-2147483648); + break; + case 'o': + case 'u': + case 'x': + case 'X': + case 'O': + case 'U': + args.push(4294967295); + break; + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + case 'a': + case 'A': + args.push("3.14159"); + break; + case 'c': + case 'C': + args.push(88); + break; + case 's': + case 'S': + strs++; + args.push("StringVal" + strs); + break; + case 'p': + args.push(0x6734531); + break; + case 'n': + break; + case 'm': + break; + case '%': + break; + case 'minwidth': + args.push(4); + break; + case 'precision': + args.push(5); + break; + } + } + } + return format.apply(js.global, args).replace(/\x07/g, ''); +} + +// TODO: Message 765 is too big +// TODO: Some way to "run" things like 559 (YesNoQuestion) +function redraw(str, num) +{ + var df = 'unknown'; + console.clear(); + console.gotoxy(0,0); + console.attributes = 7; + console.print("Example text\r\nbefore message.\r\n"); + console.question = "Example question"; + // TODO: mnemonics() vs. putmsg() vs. print() + // different messages have different requirements. + console.ungetkeys("\x03", true); + switch (displaywith) { + case 0: + console.putmsg(formatted(a + 'Q' + str, num)); + df = 'putmsg() '; + break; + case 1: + console.mnemonics(formatted(a + 'Q' + str, num)); + df = 'mnemonics()'; + break; + case 2: + console.print(formatted(a + 'Q' + str, num)); + df = 'print() '; + break; + } + console.inkey(); + console.print("Example text after message.\r\n"); + console.gotoxy(0,16); + console.print(a + "h" + a + "w" + a + "4" + " " + df + " ^^ As seen on BBS ^^" + " vv " + tnames[num] + " (" + num + ") vv" + a + ">"); + console.gotoxy(0,17); + console.cleartoeos(7); + console.print(format_entry(bbs.text(msg))); + place_cursor(); +} + +function get_tvals() { + var tvals = {}; + load(tvals, "text.js"); + var i; + for (i in tvals) { + tnames[tvals[i]] = i; + } + // TODO: Why is this one higher than the last? + last_entry = tvals.TOTAL_TEXT - 1; +} + +function newmsg() +{ + var rmsg = bbs.text(msg); + var tpos = 0; + var spos = 0; + var i; + msglens = []; + for (i = 0; i < rmsg.length; i++) { + msglens.push({'tpos': tpos, 'spos': spos}); + if (rmsg[i] < ' ') + tpos++; + tpos++; + spos++; + } + msglens.push({'tpos': tpos, 'spos': spos}); + len = msglens.length; + pos = len - 1; + displaywith = 0; + if (details[tnames[msg]] !== undefined) { + if (details[tnames[msg]].displaywith !== undefined) + displaywith = details[tnames[msg]].displaywith; + } +} + +function place_cursor() +{ + console.gotoxy(0, 17); + var np = msglens[pos].tpos; + while (np >= console.screen_columns) { + console.linefeed(); + np -= console.screen_columns; + } + console.right(np); + console.attributes = 15; +} + +function get_msgnum() +{ + console.gotoxy(42, 16); + console.attributes = 0x1F; + console.cleartoeol(); + var ret = console.getnum(last_entry, msg); + if (typeof ret === 'number') { + msg = ret; + newmsg(); + } + console.attributes = 7; +} + +get_tvals(); +newmsg(); +var done = false; +while (!done) { + redraw(bbs.text(msg), msg); + switch (console.getkey()) { + case KEY_UP: + if (msg > 1) { + msg--; + newmsg(); + } + break; + case KEY_DOWN: + if (bbs.text(msg + 1) != null) { + msg++; + newmsg(); + } + break; + case KEY_LEFT: + if (pos > 0) + pos--; + break; + case KEY_RIGHT: + if (pos < len - 1) + pos++; + break; + case KEY_PAGEUP: + displaywith--; + if (displaywith < 0) + displaywith = 2; + break; + case KEY_PAGEDN: + displaywith++; + if (displaywith > 2) + displaywith = 0; + break; + case ctrl('G'): + get_msgnum(); + break; + case 'q': + case 'Q': + done = true; + break; + } +}