Implements {ex,im}porting {as,from} ANSI.

Bump to v1.1.2.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2019-08-25 18:39:49 +02:00
parent a002cb96bb
commit 922b9b6c5d
14 changed files with 285 additions and 88 deletions

View File

@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.lalbornoz.MiRCART" version="1.1.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<widget id="com.lalbornoz.MiRCART" version="1.1.2" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<author email="lucio@lucioillanes.de" href="https://github.com/lalbornoz/MiRCART#readme">
Lucio Andrés Illanes Albornoz &lt;lucio@lucioillanes.de&gt;, based on work by JOLLO NET NA
</author>

2
MiRCART-cordoba/package-lock.json generated vendored
View File

@ -1,6 +1,6 @@
{
"name": "MiRCART-cordoba",
"version": "1.1.0",
"version": "1.1.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -30,5 +30,5 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "1.1.0"
"version": "1.1.2"
}

2
MiRCART-nw/package-lock.json generated vendored
View File

@ -1,5 +1,5 @@
{
"name": "MiRCART",
"version": "1.1.0",
"version": "1.1.2",
"lockfileVersion": 1
}

View File

@ -18,7 +18,7 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "1.1.0",
"version": "1.1.2",
"window": {
"title": "MiRCART (standalone NW app)",
"toolbar": true,

View File

@ -20,10 +20,12 @@ body.grid #palette_wrapper > div:first-child {
/* {{{ .initial styles */
.initial #add_custom_el,
.initial #doc_el,
.initial #export_button,
.initial #format_el,
.initial #grid_el,
.initial #export_format_el,
.initial #export_textarea,
.initial #import_button,
.initial #import_format_el,
.initial #import_textarea,
.initial #grid_el,
.initial #load_el,
.initial #save_el,
.initial #vertical_checkbox {
@ -109,6 +111,7 @@ body.grid #palette_wrapper > div:first-child {
.hidden { visibility: hidden; }
.loading .vertical #ui_wrapper { clear: none }
#experimental_palette_toggle.focused { box-shadow: none; }
#export_wrapper { display: none; }
#import_wrapper { display: none; }
#tools_block > * { cursor: crosshair; }
#workspace_wrapper { width: 100%; }
@ -247,6 +250,16 @@ textarea, input[type=text], body {
top: 0;
width: 30px;
}
#export_textarea {
background: #001100;
border: 1px solid #333333;
color: #00FF00;
font-family: 'FixedsysExcelsior301Regular';
font-size: 12pt;
height: 300px;
outline: 0;
width: 37vw;
}
#import_textarea {
background: #001100;
border: 1px solid #333333;

View File

@ -7,7 +7,7 @@
<link charset="utf-8" href="../css/fonts.css" rel="stylesheet" type="text/css" />
<link charset="utf-8" href="../css/help.css" rel="stylesheet" type="text/css" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>MiRCART v1.1.0 documentation</title>
<title>MiRCART v1.1.2 documentation</title>
</head>
<!-- }}} -->
<!-- {{{ BODY -->

View File

@ -46,7 +46,7 @@ function bind () {
var ae = document.activeElement
if (ae !== import_textarea) {
if ((ae !== export_textarea) && (ae !== import_textarea)) {
cursor_input.focus()
}

View File

@ -2,50 +2,55 @@ var clipboard = (function () {
var exports = {
format: "mirc",
importing: false,
exporting: false,
visible: false,
canvas: document.createElement("canvas"),
canvas_r: document.createElement("canvas"),
bind: function () {
import_button.addEventListener("click", exports.import_colorcode)
import_textarea.addEventListener("focus", exports.focus)
import_textarea.addEventListener("blur", exports.blur)
import_textarea.addEventListener('paste', exports.paste)
export_textarea.addEventListener("focus", exports.export_focus)
export_textarea.addEventListener("blur", exports.blur)
import_button.addEventListener("click", exports.import_click)
import_textarea.addEventListener("focus", exports.import_focus)
import_textarea.addEventListener("paste", exports.paste)
},
setFormat: function (name) {
return function () {
clipboard.format = name
if (! clipboard.importing) { clipboard.export_data() }
if (! clipboard.exporting) { clipboard.export_data() }
}
},
show: function () { import_wrapper.style.display = "block"; clipboard.visible = true; changed = false },
hide: function () { import_wrapper.style.display = "none"; clipboard.visible = false },
focus: function () {
if (! clipboard.importing) {
import_textarea.focus()
import_textarea.select()
import_hide: function () { import_wrapper.style.display = "none"; clipboard.visible = false },
import_show: function () { import_wrapper.style.display = "block"; clipboard.visible = true; },
export_hide: function () { export_wrapper.style.display = "none"; clipboard.visible = false },
export_show: function () { export_wrapper.style.display = "block"; clipboard.visible = true; changed = false },
export_focus: function () {
if (! clipboard.exporting) {
export_textarea.focus()
export_textarea.select()
}
},
import_focus: function () {
import_textarea.focus()
import_textarea.select()
},
blur: function () {
},
import_mode: function () {
focus()
clipboard.importing = true
format_el.style.display = 'none'
cutoff_warning_el.style.display = 'none'
import_buttons.style.display = "inline"
import_textarea.value = ""
export_mode: function () {
exports.export_focus()
clipboard.exporting = true
export_cutoff_warning_el.style.display = "none"
export_format_el.style.display = "inline"
clipboard.export_data()
},
export_mode: function () {
focus()
clipboard.importing = false
import_buttons.style.display = "none"
format_el.style.display = 'inline'
cutoff_warning_el.style.display = 'none'
clipboard.export_data()
import_mode: function () {
import_button.style.display = "inline"
import_format_el.style.display = "inline"
import_textarea.value = ""
exports.import_focus()
},
paste: function (e) {
@ -65,7 +70,101 @@ var clipboard = (function () {
})
},
import_colorcode: function (data, no_undo) {
import_click: function (data, no_undo) {
switch (controls.load_format.value) {
case 'ansi':
exports.import_ansi(data, no_undo)
break
case 'mirc':
exports.import_mirc(data, no_undo)
break
}
},
import_ansi: function (data, no_undo) {
if (data && data.preventDefault) {
data = import_textarea.value
} else {
data = data || import_textarea.value
}
var to_json = function(string, opts){
var lines_in = string.split(/\r?\n/)
var lines_out = []
var w = 0, h = 0
for (var y = 0; y < lines_in.length; y++) {
var bg = 1, fg = 15
var cells = [], line = lines_in[y]
if (line.length === 0) {
continue
} else {
for (var x = 0; x < line.length; x++) {
var m = line.substring(x).match(/^\x1b\[(\d{1,3});(\d{1,3})m/);
if (m !== null) {
if (ansi_bg_import[parseInt(m[1])] !== undefined) {
bg = ansi_bg_import[parseInt(m[1])];
}
if (ansi_fg_import[parseInt(m[1])] !== undefined) {
fg = ansi_fg_import[parseInt(m[1])];
}
if (ansi_bg_import[parseInt(m[2])] !== undefined) {
bg = ansi_bg_import[parseInt(m[2])];
}
if (ansi_fg_import[parseInt(m[2])] !== undefined) {
fg = ansi_fg_import[parseInt(m[2])];
}
x += (m[0].length - 1)
} else {
var m = line.substring(x).match(/^\x1b\[(\d{1,3})m/);
if (m !== null) {
if (ansi_bg_import[parseInt(m[1])] !== undefined) {
bg = ansi_bg_import[parseInt(m[1])];
}
if (ansi_fg_import[parseInt(m[1])] !== undefined) {
fg = ansi_fg_import[parseInt(m[1])];
}
x += (m[0].length - 1)
} else {
cells.push({bg: bg, fg: fg, value: line[x]})
}
}
}
if (cells.length > 0) {
if (w < cells.length) {
w = cells.length
}
lines_out.push(cells); h++;
}
}
}
return {h: h, lines: lines_out, w: w}
}
var json = to_json(data, {fg:0, bg:1})
if (!no_undo) undo.new()
if (!no_undo) undo.save_rect(0,0, canvas.w, canvas.h)
if (json.w !== canvas.w || json.h !== canvas.h){
if (!no_undo) undo.save_size(canvas.w, canvas.h)
canvas.resize(json.w, json.h, true)
}
canvas.clear()
for (var y = 0, line; line = json.lines[y]; y++){
var row = canvas.aa[y]
for (var x = 0, char; char = line[x]; x++){
var lex = row[x]
lex.char = char.value
lex.fg = char.fg
lex.bg = char.bg
lex.opacity = 1
lex.build()
}
}
current_filetool && current_filetool.blur()
},
import_mirc: function (data, no_undo) {
if (data && data.preventDefault) {
data = import_textarea.value
} else {
@ -167,17 +266,20 @@ var clipboard = (function () {
case 'ascii':
output = canvas.ascii()
break
case 'ansi':
output = canvas.ansi()
break
case 'mirc':
output = canvas.mirc({cutoff: 425})
break
}
if (output.cutoff){
cutoff_warning_el.style.display = 'block'
export_cutoff_warning_el.style.display = 'block'
} else {
cutoff_warning_el.style.display = 'none'
export_cutoff_warning_el.style.display = 'none'
}
import_textarea.value = output
clipboard.focus()
export_textarea.value = output
clipboard.export_focus()
return output
},

View File

@ -68,39 +68,77 @@ Object.keys(css_lookup).forEach(function(color){
})
var ansi_fg = [
97, // white
30, // black
34, // dark blue
32, // green
91, // light red
31, // dark red
35, // purple
33, // "dark yellow" (orange?)
93, // "light yellow"
92, // light green
36, // cyan (teal?)
96, // light cyan
94, // light blue
95, // light magenta
90, // dark gray
37, // light gray
97, // Bright White
30, // Black
94, // Light Blue
32, // Green
91, // Red
31, // Light Red
35, // Pink
33, // Yellow
93, // Light Yellow
92, // Light Green
36, // Cyan
96, // Light Cyan
34, // Blue
95, // Light Pink
90, // Grey
37, // Light Grey
]
var ansi_fg_import = {
97: 0, // Bright White
30: 1, // Black
94: 2, // Light Blue
32: 3, // Green
91: 4, // Red
31: 5, // Light Red
35: 6, // Pink
33: 7, // Yellow
93: 8, // Light Yellow
92: 9, // Light Green
36: 10, // Cyan
96: 11, // Light Cyan
34: 12, // Blue
95: 13, // Light Pink
90: 14, // Grey
37: 15, // Light Grey
}
var ansi_bg = [
107, // white
40, // black
44, // dark blue
42, // green
101, // light red
41, // dark red
45, // purple
43, // yellow (orange)
103, // light yellow
102, // light green
46, // cyan (teal?)
106, // light cyan
104, // light blue
105, // light magenta
100, // dark gray
47, // light gray
107, // Bright White
40, // Black
104, // Light Blue
42, // Green
101, // Red
41, // Light Red
45, // Pink
43, // Yellow
103, // Light Yellow
102, // Light Green
46, // Cyan
106, // Light Cyan
44, // Blue
105, // Light Pink
100, // Grey
47, // Light Grey
]
var ansi_bg_import = {
107: 0, // Bright White
40: 1, // Black
104: 2, // Light Blue
42: 3, // Green
101: 4, // Red
41: 5, // Light Red
45: 6, // Pink
43: 7, // Yellow
103: 8, // Light Yellow
102: 9, // Light Green
46: 10, // Cyan
106: 11, // Light Cyan
44: 12, // Blue
105: 13, // Light Pink
100: 14, // Grey
47: 15, // Light Grey
}

View File

@ -47,15 +47,29 @@ Lex.prototype.sanitize = function(){
default: return this.char
}
}
Lex.prototype.ansi = function(bg_, fg_){
var char = this.char || " "
var charIsNaN = isNaN(parseInt(char))
if ((bg_ == this.fg) && (fg_ == this.bg)) {
bg_ = this.bg; fg_ = this.fg
return [bg_, fg_, "\x1b[7m" + char]
} else if ((bg_ != this.bg) && (fg_ != this.fg)) {
bg_ = this.bg; fg_ = this.fg;
return [bg_, fg_, "\x1b[" + ansi_bg[bg_] + ";" + ansi_fg[fg_] + "m" + char]
} else if (bg_ != this.bg) {
bg_ = this.bg
return [bg_, fg_, "\x1b[" + ansi_bg[bg_] + "m" + char]
} else if (fg_ != this.fg) {
fg_ = this.fg
return [bg_, fg_, "\x1b[" + ansi_fg[fg_] + "m" + char]
}
}
Lex.prototype.mirc = function(bg_, fg_){
var char = this.char || " "
var charIsNaN = isNaN(parseInt(char))
if ((bg_ == this.fg) && (fg_ == this.bg)) {
if ((bg_ == this.fg) && (fg_ == this.bg)) {
bg_ = this.bg; fg_ = this.fg
return [bg_, fg_, "\x16" + char]
} else if ((bg_ != this.bg) && (fg_ == this.fg)) {
bg_ = this.bg
return [bg_, fg_, "\x03," + ((this.bg&15) < 10 && !charIsNaN ? "0" : "") + (this.bg&15) + char]
} else if ((bg_ == this.bg) && (fg_ != this.fg)) {
fg_ = this.fg
return [bg_, fg_, "\x03" + ((this.fg&15) < 10 && !charIsNaN ? "0" : "") + (this.fg&15) + char]

View File

@ -239,6 +239,26 @@ Matrix.prototype.ascii = function () {
var txt = lines.join("\n")
return txt
}
Matrix.prototype.ansi = function (opts) {
var lines = this.aa.map(function(row, y){
var last, line = ""
row.forEach(function(lex, x) {
var bg_ = -1, fg_ = -1
if (lex.eqColor(last)) {
line += lex.sanitize()
}
else {
[bg_, fg_, line_] = lex.ansi(bg_, fg_)
line += line_; last = lex;
}
})
return line
})
var txt = lines.filter(function(line){ return line.length > 0 }).join('\n')
return txt
}
Matrix.prototype.mirc = function (opts) {
var cutoff = false
var lines = this.aa.map(function(row, y){

View File

@ -131,26 +131,32 @@ var controls = (function(){
ClipboardTool = FileTool.extend({
blur: function(){
this.__blur()
clipboard.hide()
clipboard.export_hide()
clipboard.import_hide()
}
})
controls.save = new ClipboardTool (save_el)
controls.save.use = function(){
clipboard.show()
clipboard.export_show()
clipboard.export_mode()
}
controls.load = new ClipboardTool (load_el)
controls.load.use = function(){
// console.log("use")
clipboard.show()
clipboard.import_show()
clipboard.import_mode()
}
controls.save_format = new RadioGroup(format_el)
controls.load_format = new RadioGroup(import_format_el)
controls.load_format.name = 'load_format'
controls.load_format.memorable = true
var cs = controls.load_format.controls
//
controls.save_format = new RadioGroup(export_format_el)
controls.save_format.name = 'save_format'
controls.save_format.memorable = true
var cs = controls.save_format.controls
cs.mirc.use = cs.ascii.use = function(){
cs.mirc.use = cs.ansi.use = cs.ascii.use = function(){
clipboard.export_data()
}
//

View File

@ -9,7 +9,7 @@
<link charset="utf-8" href="assets/css/sally.css" rel="stylesheet" type="text/css" />
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<meta content="width=device-width, maximum-scale=1.0, user-scalable=yes" name="viewport" />
<title>MiRCART v1.1.0</title>
<title>MiRCART v1.1.2</title>
</head>
<!-- }}} -->
<!-- {{{ BODY -->
@ -72,13 +72,17 @@
<span id="grid_el" class="tool">_ grid</span>
<span id="vertical_checkbox" class="tool">x vertical</span>
</div>
<div id="export_wrapper">
<span id="export_format_el">ascii ansi *mirc</span>
<div id="gallery_wrapper"></div><br />
<div id="export_cutoff_warning_el">character limit of 425 exceeded</div>
<textarea id="export_textarea" cols="100" rows="30"></textarea>
</div>
<div id="import_wrapper">
<span id="format_el">ascii *mirc</span>
<span id="import_format_el">ansi *mirc</span>
<span id="import_buttons">
<button id="import_button">import</button>
</span>
<div id="gallery_wrapper" /><br />
<div id="cutoff_warning_el">character limit of 425 exceeded</div>
</span><br />
<textarea id="import_textarea" cols="100" rows="30"></textarea>
</div>
</div>