Move load(), parse() into the object. Edit frame now saves.
This commit is contained in:
parent
bfa0853d75
commit
2b5ecf6c75
546
load/defs.js
546
load/defs.js
@ -96,9 +96,9 @@ function TexFrame() {
|
||||
}
|
||||
|
||||
if ((this.type == FRAME_TYPE_LOGIN) || (this.type == FRAME_TYPE_RESPONSE)) {
|
||||
return header+this.parse(this.content);
|
||||
return header+this.parse(base64_decode(this.content));
|
||||
} else {
|
||||
return header+this.content;
|
||||
return header+base64_decode(this.content);
|
||||
}
|
||||
};
|
||||
|
||||
@ -113,6 +113,284 @@ function TexFrame() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Load a frame from disk (.tex file)
|
||||
this.load = function(filename) {
|
||||
log(LOG_DEBUG,'Loading frame from: '+filename);
|
||||
|
||||
f = new File(system.mods_dir+'ansitex/text/'+filename+'.tex');
|
||||
if (! f.exists || ! f.open('r')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var load = JSON.parse(f.read());
|
||||
|
||||
for (property in load) {
|
||||
this[property] = load[property];
|
||||
}
|
||||
|
||||
//this.content = base64_decode(this.content);
|
||||
|
||||
} catch (error) {
|
||||
log(LOG_ERROR,'Frame error: '+error);
|
||||
return null;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,'Loaded frame: ['+this.frame+']['+this.index+'] ('+this.page+')');
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the page text, and return the frame as 2 arrays:
|
||||
* + First array is all the characters and the position on the frame
|
||||
* + Second array is the array of the control codes that changes the color of the character
|
||||
*
|
||||
* The purpose of this function is to convert any special char sequences there are interpreted directly by Ansitex
|
||||
* Currently they are:
|
||||
* + ESC _ <value>[;value] ESC \
|
||||
*
|
||||
* Additionally, for response frames, if the cursor is moved to a field, its to determine what attributes (eg: color)
|
||||
* should apply for that field.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
this.parse = function(text) {
|
||||
var c = 1; // column
|
||||
var r = 2; // row (row 1 is the header)
|
||||
var output = '';
|
||||
this.frame_fields = [];
|
||||
|
||||
// Default Attributes
|
||||
f = 39;
|
||||
b = 49;
|
||||
i = 0;
|
||||
|
||||
for(p=0;p<text.length;p++) {
|
||||
// Look for a special character until the end of the frame width
|
||||
cte = (r*FRAME_WIDTH - ((r-1)*FRAME_WIDTH+c));
|
||||
match = text.substr(p,cte).match(/[\r\n\x1b]/);
|
||||
//log(LOG_DEBUG,'SPECIAL CHAR ['+r+'x'+c+'] ['+p+'-'+cte+'] for: '+match);
|
||||
|
||||
if (match == null || match.index) {
|
||||
advance = match ? match.index : cte;
|
||||
//log(LOG_DEBUG,'INCLUDE: '+text.substr(p,advance));
|
||||
|
||||
output += text.substr(p,advance);
|
||||
p += advance;
|
||||
c += advance;
|
||||
advance = 0;
|
||||
}
|
||||
|
||||
// If the frame is not big enough, fill it with spaces.
|
||||
byte = text.charAt(p);
|
||||
advance = 0;
|
||||
|
||||
switch (byte) {
|
||||
// Carriage Return
|
||||
case '\r':
|
||||
// log(LOG_DEBUG,'CR');
|
||||
c=1;
|
||||
break;
|
||||
|
||||
// New line
|
||||
case '\n':
|
||||
// log(LOG_DEBUG,'LF');
|
||||
r++;
|
||||
break;
|
||||
|
||||
// ESC
|
||||
case KEY_ESC:
|
||||
advance = 1;
|
||||
// Is the next byte something we know about
|
||||
nextbyte = text.charAt(p+advance);
|
||||
//log(LOG_DEBUG,'ESC ['+r+'x'+c+'] NEXT: '+nextbyte);
|
||||
|
||||
switch (nextbyte) {
|
||||
// CSI
|
||||
case '[':
|
||||
advance++;
|
||||
chars = '';
|
||||
|
||||
// Find our end CSI param in the next 50 chars
|
||||
matches = text.substr(p+advance,50).match(/([0-9]+[;]?)+([a-zA-Z])/);
|
||||
//log(LOG_DEBUG,'CSI ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', STRING: '+text.substr(p+advance,50));
|
||||
|
||||
if (! matches) {
|
||||
chars += nextbyte;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
advance += matches[0].length-1;
|
||||
chars += nextbyte+matches[0];
|
||||
//log(LOG_DEBUG,'CSI ['+r+'x'+c+'] ADVANCE: '+advance+', CHARS: '+chars+', CHARSLEN: '+chars.length);
|
||||
|
||||
switch (matches[2]) {
|
||||
// Color CSIs
|
||||
case 'm':
|
||||
//log(LOG_DEBUG,'CSI m ['+r+'x'+c+'] MATCHES: '+matches[0]+', LENGTH : '+matches[0].length);
|
||||
|
||||
csi = matches[0].substr(0,matches[0].length-1).split(';');
|
||||
var num = null;
|
||||
for (num in csi) {
|
||||
//log(LOG_DEBUG,'CSI m ['+r+'x'+c+'] NUM: '+num+', CSI: '+csi[num]);
|
||||
// Intensity
|
||||
if (csi[num] >= 0 && csi[num] <= 8) {
|
||||
i = csi[num];
|
||||
f = 39;
|
||||
b = 49;
|
||||
|
||||
// Forground Color
|
||||
} else if (csi[num] >= 30 && csi[num] <= 39) {
|
||||
f = csi[num];
|
||||
|
||||
// Background Color
|
||||
} else if (csi[num] >= 40 && csi[num] <= 49) {
|
||||
b = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Advance characters
|
||||
case 'C':
|
||||
//log(LOG_DEBUG,'CSI C ['+r+'x'+c+'] CHARS: '+matches[1]);
|
||||
c += parseInt(matches[1]); // Advance our position
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_DEBUG,'? CSI: '.matches[2]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
log(LOG_DEBUG,'LOOSE ESC? ['+r+'x'+c+'] '+advance);
|
||||
|
||||
break;
|
||||
|
||||
// SOS
|
||||
case '_':
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] '+advance);
|
||||
advance++;
|
||||
|
||||
// Find our end ST param in the next 50 chars
|
||||
matches = text.substr(p+advance,50).match(/(([A-Z]+;[0-9a-z]+)([;]?.+)?)\x1b\\/);
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', LENGTH: '+matches[0].length+', STRING: '+text.substr(p+advance,50));
|
||||
|
||||
if (! matches) {
|
||||
chars += nextbyte;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
advance += matches[0].length-1;
|
||||
|
||||
// The last 2 chars of matches[0] are the ESC \
|
||||
sos = matches[0].substr(0,matches[0].length-2).split(';');
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', SOS: '+sos);
|
||||
|
||||
var num = null;
|
||||
var fieldlen = null;
|
||||
for (num in sos) {
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM: '+num+', SOS: '+sos[num]);
|
||||
|
||||
switch (num) {
|
||||
// First value is the field name
|
||||
case '0':
|
||||
field = sos[num];
|
||||
break;
|
||||
|
||||
// Second value is the length/type of the field
|
||||
case '1':
|
||||
x = sos[num].match(/([0-9]+)([a-z])/);
|
||||
if (! x) {
|
||||
log(LOG_ERROR,'SOS FAILED PARSING FIELD LENGTH/TYPE. ['+r+'x'+c+'] '+sos[num]);
|
||||
break;
|
||||
}
|
||||
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM CHARS: '+x[1]+', TYPE: '+x[2]);
|
||||
fieldlen = x[1];
|
||||
fieldtype = x[2];
|
||||
break;
|
||||
|
||||
// Third field is the char to to use
|
||||
case '2':
|
||||
fieldchar = sos[num];
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_ERROR,'IGNORING ADDITIONAL SOS FIELDS. ['+r+'x'+c+'] '+sos[num]);
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldlen) {
|
||||
chars = fieldchar.repeat(fieldlen);
|
||||
}
|
||||
|
||||
byte = '';
|
||||
|
||||
this.frame_fields.push({
|
||||
ftype: fieldtype,
|
||||
flength: fieldlen,
|
||||
fchar: fieldchar,
|
||||
fname: field,
|
||||
r: r,
|
||||
c: c,
|
||||
attribute: {i:i,f:f,b:b},
|
||||
fvalue: '',
|
||||
});
|
||||
|
||||
log(LOG_DEBUG,'SOS Field found at ['+r+'x'+(c-1)+'], Type: '+fieldtype+', Length: '+fieldlen+', Attrs: '+JSON.stringify({i:i,f:f,b:b}));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_DEBUG,'DEFAULT ['+r+'x'+c+'] '+advance);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
c++;
|
||||
}
|
||||
|
||||
output += byte;
|
||||
|
||||
if (advance) {
|
||||
//log(LOG_DEBUG,'ADVANCE P ['+r+'x'+c+'] '+advance+', NEXT CHAR: '+text.charAt(p+advance)+' ('+text.charCodeAt(p+advance)+')');
|
||||
output += chars;
|
||||
p += advance;
|
||||
}
|
||||
|
||||
if (c>FRAME_WIDTH) {
|
||||
c = 1;
|
||||
r++;
|
||||
}
|
||||
|
||||
/*
|
||||
// @todo - If we are longer than FRAME_LENGTH, move the output into the next frame.
|
||||
if (r>FRAME_LENGTH) {
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
this.save=function() {
|
||||
file = system.mods_dir+'ansitex/text/'+this.page+'.tex';
|
||||
w = new File(file);
|
||||
if (! w.open('w')) {
|
||||
log(LOG_ERROR,'! ERROR: Unable to create TEX file for '+this.page);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
w.write(JSON.stringify(this));
|
||||
w.close();
|
||||
|
||||
log(LOG_DEBUG,'Saved file: '+this.page+'.tex');
|
||||
}
|
||||
|
||||
Object.defineProperty(this,'page', {
|
||||
get: function() {
|
||||
if (this.frame == null || this.index == null) return null;
|
||||
@ -149,268 +427,4 @@ function TexFrame() {
|
||||
});
|
||||
}
|
||||
|
||||
// Load a frame from disk (.tex file)
|
||||
TexFrame.prototype.load = function(filename) {
|
||||
log(LOG_DEBUG,'Loading frame from: '+filename);
|
||||
|
||||
f = new File(system.mods_dir+'ansitex/text/'+filename+'.tex');
|
||||
if (! f.exists || ! f.open('r')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
var load = JSON.parse(f.read());
|
||||
|
||||
for (property in load) {
|
||||
this[property] = load[property];
|
||||
}
|
||||
|
||||
this.content = base64_decode(this.content);
|
||||
|
||||
} catch (error) {
|
||||
log(LOG_ERROR,'Frame error: '+error);
|
||||
return null;
|
||||
}
|
||||
|
||||
log(LOG_DEBUG,'Loaded frame: ['+this.frame+']['+this.index+'] ('+this.page+')');
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the page text, and return the frame as 2 arrays:
|
||||
* + First array is all the characters and the position on the frame
|
||||
* + Second array is the array of the control codes that changes the color of the character
|
||||
*
|
||||
* The purpose of this function is to convert any special char sequences there are interpreted directly by Ansitex
|
||||
* Currently they are:
|
||||
* + ESC _ <value>[;value] ESC \
|
||||
*
|
||||
* Additionally, for response frames, if the cursor is moved to a field, its to determine what attributes (eg: color)
|
||||
* should apply for that field.
|
||||
*
|
||||
* @param text
|
||||
*/
|
||||
TexFrame.prototype.parse = function(text) {
|
||||
var c = 1; // column
|
||||
var r = 2; // row (row 1 is the header)
|
||||
var output = '';
|
||||
this.frame_fields = [];
|
||||
|
||||
// Default Attributes
|
||||
f = 39;
|
||||
b = 49;
|
||||
i = 0;
|
||||
|
||||
for(p=0;p<text.length;p++) {
|
||||
// Look for a special character until the end of the frame width
|
||||
cte = (r*FRAME_WIDTH - ((r-1)*FRAME_WIDTH+c));
|
||||
match = text.substr(p,cte).match(/[\r\n\x1b]/);
|
||||
//log(LOG_DEBUG,'SPECIAL CHAR ['+r+'x'+c+'] ['+p+'-'+cte+'] for: '+match);
|
||||
|
||||
if (match == null || match.index) {
|
||||
advance = match ? match.index : cte;
|
||||
//log(LOG_DEBUG,'INCLUDE: '+text.substr(p,advance));
|
||||
|
||||
output += text.substr(p,advance);
|
||||
p += advance;
|
||||
c += advance;
|
||||
advance = 0;
|
||||
}
|
||||
|
||||
// If the frame is not big enough, fill it with spaces.
|
||||
byte = text.charAt(p);
|
||||
advance = 0;
|
||||
|
||||
switch (byte) {
|
||||
// Carriage Return
|
||||
case '\r':
|
||||
// log(LOG_DEBUG,'CR');
|
||||
c=1;
|
||||
break;
|
||||
|
||||
// New line
|
||||
case '\n':
|
||||
// log(LOG_DEBUG,'LF');
|
||||
r++;
|
||||
break;
|
||||
|
||||
// ESC
|
||||
case KEY_ESC:
|
||||
advance = 1;
|
||||
// Is the next byte something we know about
|
||||
nextbyte = text.charAt(p+advance);
|
||||
//log(LOG_DEBUG,'ESC ['+r+'x'+c+'] NEXT: '+nextbyte);
|
||||
|
||||
switch (nextbyte) {
|
||||
// CSI
|
||||
case '[':
|
||||
advance++;
|
||||
chars = '';
|
||||
|
||||
// Find our end CSI param in the next 50 chars
|
||||
matches = text.substr(p+advance,50).match(/([0-9]+[;]?)+([a-zA-Z])/);
|
||||
//log(LOG_DEBUG,'CSI ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', STRING: '+text.substr(p+advance,50));
|
||||
|
||||
if (! matches) {
|
||||
chars += nextbyte;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
advance += matches[0].length-1;
|
||||
chars += nextbyte+matches[0];
|
||||
//log(LOG_DEBUG,'CSI ['+r+'x'+c+'] ADVANCE: '+advance+', CHARS: '+chars+', CHARSLEN: '+chars.length);
|
||||
|
||||
switch (matches[2]) {
|
||||
// Color CSIs
|
||||
case 'm':
|
||||
//log(LOG_DEBUG,'CSI m ['+r+'x'+c+'] MATCHES: '+matches[0]+', LENGTH : '+matches[0].length);
|
||||
|
||||
csi = matches[0].substr(0,matches[0].length-1).split(';');
|
||||
var num = null;
|
||||
for (num in csi) {
|
||||
//log(LOG_DEBUG,'CSI m ['+r+'x'+c+'] NUM: '+num+', CSI: '+csi[num]);
|
||||
// Intensity
|
||||
if (csi[num] >= 0 && csi[num] <= 8) {
|
||||
i = csi[num];
|
||||
f = 39;
|
||||
b = 49;
|
||||
|
||||
// Forground Color
|
||||
} else if (csi[num] >= 30 && csi[num] <= 39) {
|
||||
f = csi[num];
|
||||
|
||||
// Background Color
|
||||
} else if (csi[num] >= 40 && csi[num] <= 49) {
|
||||
b = num;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Advance characters
|
||||
case 'C':
|
||||
//log(LOG_DEBUG,'CSI C ['+r+'x'+c+'] CHARS: '+matches[1]);
|
||||
c += parseInt(matches[1]); // Advance our position
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_DEBUG,'? CSI: '.matches[2]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
log(LOG_DEBUG,'LOOSE ESC? ['+r+'x'+c+'] '+advance);
|
||||
|
||||
break;
|
||||
|
||||
// SOS
|
||||
case '_':
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] '+advance);
|
||||
advance++;
|
||||
|
||||
// Find our end ST param in the next 50 chars
|
||||
matches = text.substr(p+advance,50).match(/(([A-Z]+;[0-9a-z]+)([;]?.+)?)\x1b\\/);
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', LENGTH: '+matches[0].length+', STRING: '+text.substr(p+advance,50));
|
||||
|
||||
if (! matches) {
|
||||
chars += nextbyte;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
advance += matches[0].length-1;
|
||||
|
||||
// The last 2 chars of matches[0] are the ESC \
|
||||
sos = matches[0].substr(0,matches[0].length-2).split(';');
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', SOS: '+sos);
|
||||
|
||||
var num = null;
|
||||
var fieldlen = null;
|
||||
for (num in sos) {
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM: '+num+', SOS: '+sos[num]);
|
||||
|
||||
switch (num) {
|
||||
// First value is the field name
|
||||
case '0':
|
||||
field = sos[num];
|
||||
break;
|
||||
|
||||
// Second value is the length/type of the field
|
||||
case '1':
|
||||
x = sos[num].match(/([0-9]+)([a-z])/);
|
||||
if (! x) {
|
||||
log(LOG_ERROR,'SOS FAILED PARSING FIELD LENGTH/TYPE. ['+r+'x'+c+'] '+sos[num]);
|
||||
break;
|
||||
}
|
||||
|
||||
//log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM CHARS: '+x[1]+', TYPE: '+x[2]);
|
||||
fieldlen = x[1];
|
||||
fieldtype = x[2];
|
||||
break;
|
||||
|
||||
// Third field is the char to to use
|
||||
case '2':
|
||||
fieldchar = sos[num];
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_ERROR,'IGNORING ADDITIONAL SOS FIELDS. ['+r+'x'+c+'] '+sos[num]);
|
||||
}
|
||||
}
|
||||
|
||||
if (fieldlen) {
|
||||
chars = fieldchar.repeat(fieldlen);
|
||||
}
|
||||
|
||||
byte = '';
|
||||
|
||||
this.frame_fields.push({
|
||||
ftype: fieldtype,
|
||||
flength: fieldlen,
|
||||
fchar: fieldchar,
|
||||
fname: field,
|
||||
r: r,
|
||||
c: c,
|
||||
attribute: {i:i,f:f,b:b},
|
||||
fvalue: '',
|
||||
});
|
||||
|
||||
log(LOG_DEBUG,'SOS Field found at ['+r+'x'+(c-1)+'], Type: '+fieldtype+', Length: '+fieldlen+', Attrs: '+JSON.stringify({i:i,f:f,b:b}));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
log(LOG_DEBUG,'DEFAULT ['+r+'x'+c+'] '+advance);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
c++;
|
||||
}
|
||||
|
||||
output += byte;
|
||||
|
||||
if (advance) {
|
||||
//log(LOG_DEBUG,'ADVANCE P ['+r+'x'+c+'] '+advance+', NEXT CHAR: '+text.charAt(p+advance)+' ('+text.charCodeAt(p+advance)+')');
|
||||
output += chars;
|
||||
p += advance;
|
||||
}
|
||||
|
||||
if (c>FRAME_WIDTH) {
|
||||
c = 1;
|
||||
r++;
|
||||
}
|
||||
|
||||
/*
|
||||
// @todo - If we are longer than FRAME_LENGTH, move the output into the next frame.
|
||||
if (r>FRAME_LENGTH) {
|
||||
break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
this;
|
@ -65,7 +65,7 @@ function edit(fo) {
|
||||
editor.menu.addItem('Save & Exit', save_and_exit);
|
||||
|
||||
x = new Graphic;
|
||||
x.ANSI = fo.content;
|
||||
x.ANSI = base64_decode(fo.content);
|
||||
log(LOG_DEBUG,JSON.stringify(x));
|
||||
|
||||
const bin = x.BIN;
|
||||
@ -99,7 +99,8 @@ function edit(fo) {
|
||||
frame.close();
|
||||
complete = true;
|
||||
console.clear(LIGHTGRAY);
|
||||
fo.content = editor.exportAnsi().join('');
|
||||
fo.content = base64_encode(editor.exportAnsi().join(''));
|
||||
fo.save();
|
||||
console.putmsg(fo.render());
|
||||
return '';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user