diff --git a/Cakefile b/Cakefile deleted file mode 100644 index 2443240..0000000 --- a/Cakefile +++ /dev/null @@ -1,47 +0,0 @@ -fs = require 'fs' -option '-o', '--output [dir]', 'dir for compiled code' - -task 'watch', 'watch current dir', (options) -> - {spawn} = require 'child_process' - args = ['-w','-c'] - if options.output - args = args.concat ['./'] - - process.chdir __originalDirname - coffee = spawn 'coffee', args - coffee.stderr.on 'data', (data) -> - process.stderr.write data.toString() - coffee.stdout.on 'data', (data) -> - console.log data.toString() - -source = [ - '16col/imgtxtmode.coffee', - '16col/ansi.coffee', - '16col/bin.coffee', - '16col/idf.coffee', - '16col/adf.coffee', - '16col/sauce.coffee', - '16col/tundra.coffee', - '16col/pcboard.coffee', - '16col/avatar.coffee', - '16col/xbin.coffee', - '16col/pallette.coffee', - '16col/fonts.coffee', -] - -task 'build', 'Build merged file for production', (options) -> - {exec} = require 'child_process' - content = [] - - for file, index in source then do (file, index) -> - fs.readFile file, 'utf8', (err, fileContents) -> - throw err if err - content[index] = fileContents - if index == source.length - 1 - coffee = content.join('\n') - fs.writeFile 'textmode.coffee', coffee, 'utf8', (err) -> - throw err if err - command = 'coffee --compile textmode.coffee' - exec command, (err, stdout, stderr) -> - throw err if err - console.log stdout + stderr \ No newline at end of file diff --git a/editor/sahliedit.coffee b/editor/sahliedit.coffee new file mode 100644 index 0000000..14a4122 --- /dev/null +++ b/editor/sahliedit.coffee @@ -0,0 +1,427 @@ +### +Sahli Editor +============ + +Editor for Sahli files. + +- open existing file +- create new item + * get filename from dir + * insert SAUCE data if available + * use SAUCE data to find font + * allow Amiga choices + * colorpicker +- edit existing item +- remove item +- clear whole file +- copy/clone +- move items around +- sort items +- output to screen (copy into file) + * run from node - save filename dialog + +*** +It should be noted that this does not do bounds checking, and it would be very +possible to overflow this by using a debugger and such. As the purpose of this +is limited, and this should NOT be put on a live website, I feel that is ok for +now. Perhaps I will fix it after Revision. + +*** + +== Create Initial crappage +We need to make a screen that has a few things in it for starters +Title, load existing, and new file options. + +Silliness for checking that this works. +### + +$(-> $("h1").hide().slideDown(500)) + +### +Create buttons to choose between the New and Load functionalities +(As we aren't going to ever load a file _and_ do a new file.) +(If someone wants to do that, they can restart with F5 or something.) +Also hide the editor until needed, and initialize some elements. +### +$(-> + $("#newsahli") + .button { disabled: false} + .click -> newsahli() + ) + +$(-> + $("#loadsahli") + .button { disabled: false} + .click -> loadsahli() + ) +$(-> + $(".hidden").hide() + $("#entryamiga").button {icons: {primary:"ui-icon-gear"}} + .click -> + stuff = $(@).children() + if @.value == "1" + stuff[1].textContent = 'Ansi' + @.value = "0" + else + stuff[1].textContent = 'Ascii' + @.value = "1" + $(".45box").css {width:'40ex',display:'inline-block'} + $(".groupbox p").css {margin:"0 0 .25em 0"} + $(".colorbox").change -> + sahlicolor() + $("#entryfont").change -> + font = $("#entryfont").val() + if font == "ansifont" + font = "BlockZone" + $('pre').css 'font-family',font + + + $("#entryfilepick").change -> + if @.files[0]? then $("#entryfile").val @.files[0].name + $("#entryfile").click -> + $("#entryfilepick").click() +) + +### +The sahli file definition format is as follows: +"file" - the actual filename on disk, "name" - the title of the piece, +the boolean 'amiga' indicates if it is ansi or ascii (True = ascii), +width is the width (widest point of the file), author the author of the piece, +the color and bg items define the color for amiga ascii, and the font +defines the font similarly. For PC ansi, this should be 'ansifont.' +The three remaining lines are informational and optional. + +The slide format is currently unused, but consists of a background picture, +a html template, and a css file. +### +class Emptyfiledef + constructor: -> + @file = "" + @name = "" + @amiga = true + @filetype = 'plain' + @width = "" + @author = "" + @font = "Propaz" + @color = [ 255,255,255,255 ] + @bg = [ 0,0,0,0 ] + @line1 = "" + @line2 = "" + @text = "" + + +class Sahli + constructor: -> + @emptyfiledef = new Emptyfiledef + @emptyslidesdef = { + "background": "", + "template": "", + "css": "" + } + @empty = { + "location": "", + "slides": @emptyslidesdef, + "filedata": [ ] + } + + loader: -> + $.ajax { + url: '../list.sahli', + dataType: "json", + success: (result) => + @data = result + @.edit() + } + + edit: -> + $('#buttonbox').hide() + $('#dirlocation').change (event) => + @data.location = event.target.value + $('#listsave').button {icons: {primary:"ui-icon-disk"}} + .click => + $('#sahlioutput').text dumpjson @data + $('#dumparea').show 100 + $('#listlist').button {icons: {primary:"ui-icon-folder-open"}} + .click -> + getfilelist() + $('#listappend').button {icons: {primary:"ui-icon-1-n"}} + .click (event) => + newentry = new Emptyfiledef + @data.filedata.push newentry + @buildlist @data + $('#listdisplay').button {icons: {primary:"ui-icon-refresh"}} + .click => + @buildlist @data + $('#closespan').click -> + $(@parentElement.parentElement).hide() + $('#sahlioutput').text '' + @buildlist @data + + buildlist: (data) -> + $('#list').show 100 + $('#list ol li').remove() + console.log i.author for i in @data.filedata + x = 0 + $('#dirlocation').val @data.location + $('#sortlist').append @.additem item,x++ for item in @data.filedata + $('#sortlist').sortable + start: (event,ui) -> + ui.item.data + startpos:ui.item.index() + stop: (event,ui) => + a = 2 + s = ui.item.data().startpos + e = ui.item.index() + @data.filedata = @.rearrangearray s,e,@data.filedata + @buildlist @data + + rearrangearray: (startpos,endpos,a) -> + moving = a[startpos] + alen = a.length + tarr = a[0...startpos].concat a[startpos+1..-1] + tarr[0...endpos].concat [moving].concat tarr[endpos..-1] + + + additem: (item,pos) -> + entry = @genentryline item,pos + entry.dblclick => + @editline item,pos + + genentryline: (item,pos) -> + arrows = "" + amigastatus = ansiorascii booltoint item.amiga + delbutton = $("delete") + .click (event) => + pos = event.currentTarget.id.replace "del-","" + @data.filedata.splice pos,1 + @buildlist @data + whichone = "
  • #{arrows}#{amigastatus} |" + whichone += " #{item.author} : #{item.name} : #{item.file}
  • " + entry = $(whichone) + entry.append delbutton + + save: -> + pos = $("#entryindex").val() + entry = @data.filedata[pos] + entry.name = $("#entryname").val() + entry.author = $("#entryauthor").val() + entry.amiga = statustobool $("#entryamiga").children()[1].textContent + console.log $("#entryamiga").children()[1].textContent + console.log entry.amiga,entry.author + entry.color = colortoarray $("#entrycolor").val() + entry.bg = colortoarray $("#entrybg").val() + entry.width = $("#entrywidth").val() + entry.line1 = $("#entryline1").val() + entry.line2 = $("#entryline2").val() + entry.text = $("#entrytext").val() + entry.font = $("#entryfont").val() + entry.file = $("#entryfile").val() + entry.filetype = $("#entryfiletype").val() + @buildlist @data + + editline: (data,pos) -> + $("#formica").dialog { + width:'800', + modal: false, + title:"Entry #{data.file} ", + buttons: [{ + text: "Cancel", + icons: {primary: 'ui-icon-trash'}, + click: -> + $(@).dialog "close" + },{ + text: "Save", + icons: {primary: 'ui-icon-disk'}, + click: (event) => + event.preventDefault() + @save() + event.currentTarget.previousElementSibling.click() + }] + } + data.amiga = booltoint data.amiga + + fcol = colortoname arraytocolor data.color + bcol = colortoname arraytocolor data.bg + + $("#entryindex").val pos + $("#entryname").val data.name + $("#entryauthor").val data.author + $("#entryfiletpye").val data.filetype + $("#entryfiletype").children()[resolvefiletype data.filetype].selected =true + $("#entryamiga").val data.amiga + $("#entryamiga").children()[1].textContent = ansiorascii data.amiga + $("#entryfont").val data.font + $("#entrycolor").val fcol + $("#entrycolor").children()[colorindex fcol ].selected = true + $("#entrybg").val bcol + $("#entrybg").children()[colorindex bcol ].selected = true + $("#entrywidth").val data.width + $("#entryline1").val data.line1 + $("#entryline2").val data.line2 + $("#entrytext").val data.text + $("#entryfile").val data.file + sahlicolor() + +### +A Helper function to dump json out of an object as text: +### +dumpjson = (obj) -> + JSON.stringify obj,null,"\t" + +### + Boolean / integer Helpers +### + +booltoint = (bool) -> + bool + 1 - 1 + +inttobool = (intstr) -> + (intstr == 1).toString() + +statustobool = (status) -> + if status is 'Ascii' then true else false + +### +Resolve filetype offset in array: +### + +resolvefiletype = (filetype) -> + options = { + "plain":0 + "ansi":1 + "xbin":2 + "ice":3 + "adf":4 + "avatar":5 + "bin":6 + "idf":7 + "pcboard":8 + "tundra":9 + } + options[filetype] + +### +Resolve ansi or ascii status +### + +ansiorascii = (status) -> + if status is 0 then "Ansi" else "Ascii" + +### +Color conversion from array to color item: + +This decimal to hex conversion only handles 00-FF but it's fine for this + purpose; we actually _want_ that limitation in the output. +### + +dec2hex = (num) -> + "#{('000'+num.toString 16).slice -2}" + +hex2dec = (num) -> + parseInt num,16 + +arraytocolor = (array) -> + c = (dec2hex x for x in array)[0..2].join '' + "##{c}" + +colortoarray = (color) -> + color = color.slice(1) + c1 = [ color[0..1], color[2..3], color[4..5] ] + x = (hex2dec i for i in c1) + x.push 255 + x + +### +Need a way to convert the array back to the color name. +### + +colortoname = (color) -> + names = { + "#E0E0E0":"Light Grey" + "#A0A0E0":"Light Blue" + "#9AFE2E":"Light Green" + "#FF0000":"Red" + "#FF8000":"Orange" + "#FFFF00":"Yellow" + "#00F000":"Green" + "#2EFEF7":"Cyan" + "#002EF7":"Blue" + "#0B0B3B":"Navy" + "#FF00FF":"Magenta" + "#8000FF":"Purple" + "#0A2A0A":"Dark Green" + "#3B3B3B":"Dark Grey" + "#FFFFFF":"White" + "#000000":"Black" + } + color = color.toUpperCase() + colorname = names[color] + bw = if hex2dec(color.slice(1)) > 8421504 then 'White' else "Black" + ret = if colorname? then colorname else bw +### +Similarly, need to be able to get the color index. +### + +colorindex = (colorname) -> + names = { + "Light Grey":0 + "Light Blue":1 + "Light Green":2 + "Red":3 + "Orange":4 + "Yellow":5 + "Green":6 + "Cyan":7 + "Blue":8 + "Navy":9 + "Magenta":10 + "Purple":11 + "Dark Green":12 + "Dark Grey":13 + "White":14 + "Black":15 + } + names[colorname] + +### +A function for changing the fore and background colors of the sahli ascii +example +### + +sahlicolor = -> + fg = $('#entrycolor').val() + bg = $('#entrybg').val() + console.log 'sahlicolor',fg,bg + $('#sahliascii').css {'color':fg,'background':bg} + +### +Function for loading the filelist from the specified directory on the +server/filesystem. +Needs to be made into an actual real thing. +### + +getfilelist = -> + location = $("#dirlocation").val() + $.get("../#{location}", (listing) -> + console.log listing + ) + +### +When clicking 'New' we want to make a brand new Sahli, and then clear out +the buttons and create the editor bit as blank. +### + +newsahli = -> + sahli = new Sahli + sahli.data = sahli.empty + newentry = new Emptyfiledef + sahli.data.filedata.push newentry + sahli.edit() + +### +And when clicking 'load' we want to load the existing sahli file. +### + +loadsahli = -> + sahli = new Sahli + sahli.loader 'list.sahli' diff --git a/editor/sahliedit.css b/editor/sahliedit.css index 3821a74..f9f3361 100644 --- a/editor/sahliedit.css +++ b/editor/sahliedit.css @@ -17,7 +17,7 @@ textarea { } pre { - font-family: 'TopazPlus a500a1000a2000','mOsOul',Monaco,monospace; + font-family: 'topaz500','mosoul',Monaco,monospace; font-size: 16; border: 2px inset #808080; } @@ -56,12 +56,14 @@ div ul li{ display: inline-block; } -# this does not actually change anything because the design is set by -# the jquery-ui bit. Altering in the script does work. Here for reference. +/* this does not actually change anything because the design is set by */ +/* the jquery-ui bit. Altering in the script does work. Here for reference. */ +/* .45box { width: 45%; display: inline-block; } +*/ div.groupbox p { margin: .25 ex; @@ -79,7 +81,7 @@ div.groupbox p { } #sahlioutput { - font-family: 'TopazPlus a500a1000a2000','mOsOul',Monaco,monospace; + font-family: 'microknight','P0t-nOodle',Monaco,monospace; font-size: 16; background: aliceblue; overflow-wrap: break-word; @@ -95,4 +97,135 @@ div.groupbox p { margin: 0px 0px 1ex; padding: 0px; -} \ No newline at end of file +} + +@font-face { + font-family: 'P0t-nOodle'; + src: url('fonts/P0T-NOoDLE_v1.0.woff2') format('woff2'); + src: url('fonts/P0T-NOoDLE_v1.0.woff') format('woff'); +} + +@font-face { + font-family: 'MicroKnight'; + src: url('fonts/MicroKnightPlus_v1.0.woff2') format('woff2'); + src: url('fonts/MicroKnightPlus_v1.0.woff') format('woff'); +} + +@font-face { + font-family: 'mOsOul'; + src: url('fonts/mOsOul_v1.0.woff2') format('woff2'); + src: url('fonts/mOsOul_v1.0.woff') format('woff'); +} + +@font-face { + font-family: 'Topaz1200'; + src: url('fonts/TopazPlusA1200.woff') format('woff2'); + src: url('fonts/TopazPlusA1200.woff') format('woff'); +} + +@font-face { + font-family: 'Topaz500'; + src: url('fonts/TopazPlusA500.woff2') format('woff2'); + src: url('fonts/TopazPlusA500.woff') format('woff'); +} + +@font-face { + font-family: 'blockzone'; + src: url('fonts/BlockZone.woff2') format('woff2'); + src: url('fonts/BlockZone.woff') format('woff'); +} + +.mosoul { + font-family: mOsOul; + text-align: left; +} + +.pot-noodle , .p0t-noodle { + font-family: 'P0t-nOodle'; + text-align: left; +} + +.topaz, .topaz500 { + font-family: 'Topaz500'; + text-align: left; +} + +.propaz, .topaz1200 { + font-family: 'Topaz1200'; + text-align: left; +} + +.microknight, .microknightplus { + font-family: 'MicroKnight'; + text-align: left; +} + +.blockzone, .pcansifont { + font-family: 'blockzone'; + text-align: left; +} +@font-face { + font-family: 'P0t-nOodle'; + src: url('../fonts/P0T-NOoDLE_v1.0.woff2') format('woff2'); + src: url('../fonts/P0T-NOoDLE_v1.0.woff') format('woff'); +} + +@font-face { + font-family: 'MicroKnight'; + src: url('../fonts/MicroKnightPlus_v1.0.woff2') format('woff2'); + src: url('../fonts/MicroKnightPlus_v1.0.woff') format('woff'); +} + +@font-face { + font-family: 'mOsOul'; + src: url('../fonts/mOsOul_v1.0.woff2') format('woff2'); + src: url('../fonts/mOsOul_v1.0.woff') format('woff'); +} + +@font-face { + font-family: 'Topaz1200'; + src: url('../fonts/TopazPlusA1200.woff') format('woff2'); + src: url('../fonts/TopazPlusA1200.woff') format('woff'); +} + +@font-face { + font-family: 'Topaz500'; + src: url('../fonts/TopazPlusA500.woff2') format('woff2'); + src: url('../fonts/TopazPlusA500.woff') format('woff'); +} + +@font-face { + font-family: 'blockzone'; + src: url('../fonts/BlockZone.woff2') format('woff2'); + src: url('../fonts/BlockZone.woff') format('woff'); +} + +.mosoul { + font-family: mOsOul; + text-align: left; +} + +.pot-noodle , .p0t-noodle { + font-family: 'P0t-nOodle'; + text-align: left; +} + +.topaz, .topaz500 { + font-family: 'Topaz500'; + text-align: left; +} + +.propaz, .topaz1200 { + font-family: 'Topaz1200'; + text-align: left; +} + +.microknight, .microknightplus { + font-family: 'MicroKnight'; + text-align: left; +} + +.blockzone, .pcansifont { + font-family: 'blockzone'; + text-align: left; +} diff --git a/editor/sahliedit.doclit b/editor/sahliedit.doclit new file mode 100644 index 0000000..7341dae --- /dev/null +++ b/editor/sahliedit.doclit @@ -0,0 +1,413 @@ +Sahli Editor +============ + +Editor for Sahli files. + +- open existing file +- create new item + * get filename from dir + * insert SAUCE data if available + * use SAUCE data to find font + * allow Amiga choices + * colorpicker +- edit existing item +- remove item +- clear whole file +- copy/clone +- move items around +- sort items +- output to screen (copy into file) + * run from node - save filename dialog + +*** +It should be noted that this does not do bounds checking, and it would be very +possible to overflow this by using a debugger and such. As the purpose of this +is limited, and this should NOT be put on a live website, I feel that is ok for +now. Perhaps I will fix it after Revision. + +*** + +== Create Initial crappage +We need to make a screen that has a few things in it for starters +Title, load existing, and new file options. + +Silliness for checking that this works. + + $(-> $("h1").hide().slideDown(500)) + +Create buttos to choose between the New and Load functionalities +(As we aren't going to ever load a file _and_ do a new file.) +(If someone wants to do that, they can restart with F5 or something.) +Also hide the editor until needed, and initialize some elements. + + $(-> + $("#newsahli") + .button { disabled: false} + .click -> newsahli() + ) + + $(-> + $("#loadsahli") + .button { disabled: false} + .click -> loadsahli() + ) + + $(-> + $(".hidden").hide() + $("#entryamiga").button {icons: {primary:"ui-icon-gear"}} + .click -> + stuff = $(@).children() + if @.value == "1" + stuff[1].textContent = 'Ansi' + @.value = "0" + else + stuff[1].textContent = 'Ascii' + @.value = "1" + $(".45box").css {width:'45%',display:'inline-block'} + $(".groupbox p").css {margin:"0 0 .25em 0"} + $(".colorbox").change -> + sahlicolor() + $("#entryfont").change -> + $('pre').css 'font-family',$('#entryfont').val() + + $("#entryfilepick").change -> + if @.files[0]? then $("#entryfile").val @.files[0].name + $("#entryfile").click -> + $("#entryfilepick").click() + ) + +The sahli file definition format is as follows: +"file" - the actual filename on disk, "name" - the title of the piece, +the boolean 'amiga' indicates if it is ansi or ascii (True = ascii), +width is the width (widest point of the file), author the author of the piece, +the color and bg items define the color for amiga ascii, and the font +defines the font similarly. For PC ansi, this should be 'ansifont.' +The three remaining lines are informational and optional. + +The slide format is currently unused, but consists of a background picture, +a html template, and a css file. + + class Emptyfiledef + constructor: -> + @file = "" + @name = "" + @amiga = true + @filetype = 'plain' + @width = "" + @author = "" + @font = "Propaz" + @color = [ 255,255,255,255 ] + @bg = [ 0,0,0,0 ] + @line1 = "" + @line2 = "" + @text = "" + + + class Sahli + constructor: -> + @emptyfiledef = new Emptyfiledef + @emptyslidesdef = { + "background": "", + "template": "", + "css": "" + } + @empty = { + "location": "", + "slides": @emptyslidesdef, + "filedata": [ ] + } + + loader: -> + $.ajax { + url: '../list.sahli', + dataType: "json", + success: (result) => + @data = result + @.edit() + } + +Editor functionality: +Close the new/load buttons - unneeded now. +list, and allow dragon-droppings for sorting. Doubleclick to edit, or use +edit button. + + edit: -> + $('#buttonbox').hide() + $('#dirlocation').change (event) => + @data.location = event.target.value + $('#listsave').button {icons: {primary:"ui-icon-disk"}} + .click => + $('#sahlioutput').text dumpjson @data + $('#dumparea').show 100 + console.log dumpjson @data + $('#listlist').button {icons: {primary:"ui-icon-folder-open"}} + .click -> + getfilelist() + $('#listappend').button {icons: {primary:"ui-icon-1-n"}} + .click (event) => + newentry = new Emptyfiledef + @data.filedata.push newentry + @buildlist @data + $('#listdisplay').button {icons: {primary:"ui-icon-refresh"}} + .click => + @buildlist @data + + $('#closespan').click -> + $(@parentElement.parentElement).hide() + $('#sahlioutput').text '' + + +You need to save the order, and extract these in that order; moving around +does not alter the array. Alternately, _have_ it alter the array. + + @buildlist @data + + buildlist: (data) -> + $('#list').show 100 + $('#list ol li').remove() + console.log i.author for i in @data.filedata + x = 0 + $('#dirlocation').val @data.location + $('#sortlist').append @.additem item,x++ for item in @data.filedata + $('#sortlist').sortable + start: (event,ui) -> + ui.item.data {startpos:ui.item.index()} + stop: (event,ui) => + s = ui.item.data().startpos + e = ui.item.index() + @data.filedata = @.rearrangearray s,e,@data.filedata + console.log name.author,name.name,name.file for name in @data.filedata + console.log '---' + @buildlist @data + +Given a start and and end position, pop the array element at start off and +insert it into the array at end position. A la the draggon-dropping. + + rearrangearray: (startpos,endpos,a) -> + moving = a[startpos] + alen = a.length + tarr = a[0...startpos].concat a[startpos+1..-1] + tarr[0...endpos].concat [moving].concat tarr[endpos..-1] + + + additem: (item,pos) -> + entry = @genentryline item,pos + entry.dblclick => + @editline item,pos + + genentryline: (item,pos) -> + arrows = "" + amigastatus = ansiorascii booltoint item.amiga + delbutton = $("delete") + .click (event) => + pos = event.currentTarget.id.replace "del-","" + @data.filedata.splice pos,1 + @buildlist @data + entry = $("
  • #{arrows}#{amigastatus} | #{item.author} : #{item.name} : #{item.file}
  • ") + entry.append delbutton + + + save: -> + pos = $("#entryindex").val() + entry = @data.filedata[pos] + entry.name = $("#entryname").val() + entry.author = $("#entryauthor").val() + entry.amiga = statustobool $("#entryamiga").children()[1].textContent + console.log $("#entryamiga").children()[1].textContent,entry.amiga,entry.author + entry.color = colortoarray $("#entrycolor").val() + entry.bg = colortoarray $("#entrybg").val() + entry.width = $("#entrywidth").val() + entry.line1 = $("#entryline1").val() + entry.line2 = $("#entryline2").val() + entry.text = $("#entrytext").val() + entry.file = $("#entryfile").val() + entry.filetype = $("#entryfiletype").val() + @buildlist @data + + editline: (data,pos) -> + $("#formica").dialog { + width:'800', + modal: false, + title:"Entry #{data.file} ", + buttons: [{ + text: "Cancel", + icons: {primary: 'ui-icon-trash'}, + click: -> + $(@).dialog "close" + },{ + text: "Save", + icons: {primary: 'ui-icon-disk'}, + click: (event) => + event.preventDefault() + @save() + event.currentTarget.previousElementSibling.click() + }] + } + + data.amiga = booltoint data.amiga + fcol = colortoname arraytocolor data.color + bcol = colortoname arraytocolor data.bg + $("#entryindex").val pos + $("#entryname").val data.name + $("#entryauthor").val data.author + $("#entryfiletpye").val data.filetype + $("#entryfiletype").children()[resolvefiletype data.filetype].selected = true + $("#entryamiga").val data.amiga + $("#entryamiga").children()[1].textContent = ansiorascii data.amiga + $("#entryfont").val data.font + $("#entrycolor").val fcol + $("#entrycolor").children()[colorindex fcol ].selected = true + $("#entrybg").val bcol + $("#entrybg").children()[colorindex bcol ].selected = true + $("#entrywidth").val data.width + $("#entryline1").val data.line1 + $("#entryline2").val data.line2 + $("#entrytext").val data.text + $("#entryfile").val data.file + sahlicolor() + + +A Helper function to dump json out of an object as text: + + dumpjson = (obj) -> + JSON.stringify obj,null,"\t" + +Boolean / integer Helpers + + booltoint = (bool) -> + bool + 1 - 1 + + inttobool = (intstr) -> + (intstr == 1).toString() + + statustobool = (status) -> + if status is 'Ascii' then true else false + +Resolve filetype offset in array: + + resolvefiletype = (filetype) -> + options = { + "plain":0 + "ansi":1 + "xbin":2 + "ice":3 + "adf":4 + "avatar":5 + "bin":6 + "idf":7 + "pcboard":8 + "tundra":9 + } + options[filetype] + +Resolve ansi or ascii status + + ansiorascii = (status) -> + if status is 0 then "Ansi" else "Ascii" + + +Color conversion from array to color item: + +This decimal to hex conversion only handles 00-FF but it's fine for this +purpose; we actually _want_ that limitation in the output. + + dec2hex = (num) -> + "#{('000'+num.toString 16).slice -2}" + + hex2dec = (num) -> + parseInt num,16 + + arraytocolor = (array) -> + c = (dec2hex x for x in array)[0..2].join '' + "##{c}" + + colortoarray = (color) -> + color = color.slice(1) + c1 = [ color[0..1], color[2..3], color[4..5] ] + x = (hex2dec i for i in c1) + x.push 255 + x + +Need a way to convert the array back to the color name. + + colortoname = (color) -> + names = { + "#E0E0E0":"Light Grey" + "#A0A0E0":"Light Blue" + "#9AFE2E":"Light Green" + "#FF0000":"Red" + "#FF8000":"Orange" + "#FFFF00":"Yellow" + "#00F000":"Green" + "#2EFEF7":"Cyan" + "#002EF7":"Blue" + "#0B0B3B":"Navy" + "#FF00FF":"Magenta" + "#8000FF":"Purple" + "#0A2A0A":"Dark Green" + "#3B3B3B":"Dark Grey" + "#FFFFFF":"White" + "#000000":"Black" + } + color = color.toUpperCase() + colorname = names[color] + bw = if hex2dec(color.slice(1)) > 8421504 then 'White' else "Black" + ret = if colorname? then colorname else bw + +Similarly, need to be able to get the color index. + + colorindex = (colorname) -> + names = { + "Light Grey":0 + "Light Blue":1 + "Light Green":2 + "Red":3 + "Orange":4 + "Yellow":5 + "Green":6 + "Cyan":7 + "Blue":8 + "Navy":9 + "Magenta":10 + "Purple":11 + "Dark Green":12 + "Dark Grey":13 + "White":14 + "Black":15 + } + names[colorname] + + +A function for changing the fore and background colors of the sahli ascii +example + + sahlicolor = -> + fg = $('#entrycolor').val() + bg = $('#entrybg').val() + console.log 'sahlicolor',fg,bg + $('#sahliascii').css {'color':fg,'background':bg} + +Function for loading the filelist from the specified directory on the +server/filesystem. + + getfilelist = -> + location = $("#dirlocation").val() + $.get("../#{location}", (listing) -> + console.log listing + ) + +When clicking 'New' we want to make a brand new Sahli, and then clear out +the buttons and create the editor bit as blank. + + newsahli = -> + sahli = new Sahli + sahli.data = sahli.empty + newentry = new Emptyfiledef + sahli.data.filedata.push newentry + sahli.edit() + +And when clicking 'load' we want to load the existing sahli file. + + loadsahli = -> + sahli = new Sahli + sahli.loader 'list.sahli' diff --git a/editor/sahliedit.js b/editor/sahliedit.js index 678a60e..02d3ce1 100644 --- a/editor/sahliedit.js +++ b/editor/sahliedit.js @@ -1,11 +1,57 @@ -// Generated by CoffeeScript 1.7.1 +// Generated by CoffeeScript 1.9.0 + +/* +Sahli Editor +============ + +Editor for Sahli files. + +- open existing file +- create new item + * get filename from dir + * insert SAUCE data if available + * use SAUCE data to find font + * allow Amiga choices + * colorpicker +- edit existing item +- remove item +- clear whole file +- copy/clone +- move items around +- sort items +- output to screen (copy into file) + * run from node - save filename dialog + +*** +It should be noted that this does not do bounds checking, and it would be very +possible to overflow this by using a debugger and such. As the purpose of this +is limited, and this should NOT be put on a live website, I feel that is ok for +now. Perhaps I will fix it after Revision. + +*** + +== Create Initial crappage +We need to make a screen that has a few things in it for starters +Title, load existing, and new file options. + +Silliness for checking that this works. + */ + (function() { - var Sahli, ansiorascii, arraytocolor, booltoint, colorindex, colortoarray, colortoname, dec2hex, dumpjson, emptyfiledef, getfilelist, hex2dec, inttobool, loadsahli, newsahli, resolvefiletype, sahlicolor, statustobool; + var Emptyfiledef, Sahli, ansiorascii, arraytocolor, booltoint, colorindex, colortoarray, colortoname, dec2hex, dumpjson, getfilelist, hex2dec, inttobool, loadsahli, newsahli, resolvefiletype, sahlicolor, statustobool; $(function() { return $("h1").hide().slideDown(500); }); + + /* + Create buttons to choose between the New and Load functionalities + (As we aren't going to ever load a file _and_ do a new file.) + (If someone wants to do that, they can restart with F5 or something.) + Also hide the editor until needed, and initialize some elements. + */ + $(function() { return $("#newsahli").button({ disabled: false @@ -40,17 +86,23 @@ } }); $(".45box").css({ - width: '45%', + width: '40ex', display: 'inline-block' }); $(".groupbox p").css({ margin: "0 0 .25em 0" }); - $(".colorbox").change((function(_this) { - return function() { - return sahlicolor(); - }; - })(this)); + $(".colorbox").change(function() { + return sahlicolor(); + }); + $("#entryfont").change(function() { + var font; + font = $("#entryfont").val(); + if (font === "ansifont") { + font = "BlockZone"; + } + return $('pre').css('font-family', font); + }); $("#entryfilepick").change(function() { if (this.files[0] != null) { return $("#entryfile").val(this.files[0].name); @@ -61,8 +113,22 @@ }); }); - emptyfiledef = (function() { - function emptyfiledef() { + + /* + The sahli file definition format is as follows: + "file" - the actual filename on disk, "name" - the title of the piece, + the boolean 'amiga' indicates if it is ansi or ascii (True = ascii), + width is the width (widest point of the file), author the author of the piece, + the color and bg items define the color for amiga ascii, and the font + defines the font similarly. For PC ansi, this should be 'ansifont.' + The three remaining lines are informational and optional. + + The slide format is currently unused, but consists of a background picture, + a html template, and a css file. + */ + + Emptyfiledef = (function() { + function Emptyfiledef() { this.file = ""; this.name = ""; this.amiga = true; @@ -77,13 +143,13 @@ this.text = ""; } - return emptyfiledef; + return Emptyfiledef; })(); Sahli = (function() { function Sahli() { - this.emptyfiledef = new emptyfiledef; + this.emptyfiledef = new Emptyfiledef; this.emptyslidesdef = { "background": "", "template": "", @@ -123,8 +189,7 @@ }).click((function(_this) { return function() { $('#sahlioutput').text(dumpjson(_this.data)); - $('#dumparea').show(100); - return console.log(dumpjson(_this.data)); + return $('#dumparea').show(100); }; })(this)); $('#listlist').button({ @@ -141,7 +206,7 @@ }).click((function(_this) { return function(event) { var newentry; - newentry = new emptyfiledef; + newentry = new Emptyfiledef; _this.data.filedata.push(newentry); return _this.buildlist(_this.data); }; @@ -186,16 +251,11 @@ }, stop: (function(_this) { return function(event, ui) { - var e, name, s, _k, _len2, _ref2; + var a, e, s; + a = 2; s = ui.item.data().startpos; e = ui.item.index(); _this.data.filedata = _this.rearrangearray(s, e, _this.data.filedata); - _ref2 = _this.data.filedata; - for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { - name = _ref2[_k]; - console.log(name.author, name.name, name.file); - } - console.log('---'); return _this.buildlist(_this.data); }; })(this) @@ -221,7 +281,7 @@ }; Sahli.prototype.genentryline = function(item, pos) { - var amigastatus, arrows, delbutton, entry; + var amigastatus, arrows, delbutton, entry, whichone; arrows = ""; amigastatus = ansiorascii(booltoint(item.amiga)); delbutton = $("delete").click((function(_this) { @@ -231,7 +291,9 @@ return _this.buildlist(_this.data); }; })(this)); - entry = $("
  • " + arrows + amigastatus + " | " + item.author + " : " + item.name + " : " + item.file + "
  • "); + whichone = "
  • " + arrows + amigastatus + " |"; + whichone += " " + item.author + " : " + item.name + " : " + item.file + "
  • "; + entry = $(whichone); return entry.append(delbutton); }; @@ -242,13 +304,15 @@ entry.name = $("#entryname").val(); entry.author = $("#entryauthor").val(); entry.amiga = statustobool($("#entryamiga").children()[1].textContent); - console.log($("#entryamiga").children()[1].textContent, entry.amiga, entry.author); + console.log($("#entryamiga").children()[1].textContent); + console.log(entry.amiga, entry.author); entry.color = colortoarray($("#entrycolor").val()); entry.bg = colortoarray($("#entrybg").val()); entry.width = $("#entrywidth").val(); entry.line1 = $("#entryline1").val(); entry.line2 = $("#entryline2").val(); entry.text = $("#entrytext").val(); + entry.font = $("#entryfont").val(); entry.file = $("#entryfile").val(); entry.filetype = $("#entryfiletype").val(); return this.buildlist(this.data); @@ -311,10 +375,20 @@ })(); + + /* + A Helper function to dump json out of an object as text: + */ + dumpjson = function(obj) { return JSON.stringify(obj, null, "\t"); }; + + /* + Boolean / integer Helpers + */ + booltoint = function(bool) { return bool + 1 - 1; }; @@ -331,6 +405,11 @@ } }; + + /* + Resolve filetype offset in array: + */ + resolvefiletype = function(filetype) { var options; options = { @@ -348,6 +427,11 @@ return options[filetype]; }; + + /* + Resolve ansi or ascii status + */ + ansiorascii = function(status) { if (status === 0) { return "Ansi"; @@ -356,6 +440,14 @@ } }; + + /* + Color conversion from array to color item: + + This decimal to hex conversion only handles 00-FF but it's fine for this + purpose; we actually _want_ that limitation in the output. + */ + dec2hex = function(num) { return "" + (('000' + num.toString(16)).slice(-2)); }; @@ -395,6 +487,11 @@ return x; }; + + /* + Need a way to convert the array back to the color name. + */ + colortoname = function(color) { var bw, colorname, names, ret; names = { @@ -421,6 +518,11 @@ return ret = colorname != null ? colorname : bw; }; + + /* + Similarly, need to be able to get the color index. + */ + colorindex = function(colorname) { var names; names = { @@ -444,6 +546,12 @@ return names[colorname]; }; + + /* + A function for changing the fore and background colors of the sahli ascii + example + */ + sahlicolor = function() { var bg, fg; fg = $('#entrycolor').val(); @@ -455,6 +563,13 @@ }); }; + + /* + Function for loading the filelist from the specified directory on the + server/filesystem. + Needs to be made into an actual real thing. + */ + getfilelist = function() { var location; location = $("#dirlocation").val(); @@ -463,15 +578,26 @@ }); }; + + /* + When clicking 'New' we want to make a brand new Sahli, and then clear out + the buttons and create the editor bit as blank. + */ + newsahli = function() { var newentry, sahli; sahli = new Sahli; sahli.data = sahli.empty; - newentry = new emptyfiledef; + newentry = new Emptyfiledef; sahli.data.filedata.push(newentry); return sahli.edit(); }; + + /* + And when clicking 'load' we want to load the existing sahli file. + */ + loadsahli = function() { var sahli; sahli = new Sahli; diff --git a/editor/sahliedit.litcoffee b/editor/sahliedit.litcoffee deleted file mode 100644 index 412b89c..0000000 --- a/editor/sahliedit.litcoffee +++ /dev/null @@ -1,415 +0,0 @@ -Sahli Editor -============ - -Editor for Sahli files. - -- open existing file -- create new item - * get filename from dir - * insert SAUCE data if available - * use SAUCE data to find font - * allow Amiga choices - * colorpicker -- edit existing item -- remove item -- clear whole file -- copy/clone -- move items around -- sort items -- output to screen (copy into file) - * run from node - save filename dialog - -*** -It should be noted that this does not do bounds checking, and it would be very -possible to overflow this by using a debugger and such. As the purpose of this -is limited, and this should NOT be put on a live website, I feel that is ok for -now. Perhaps I will fix it after Revision. - -*** - -== Create Initial crappage -We need to make a screen that has a few things in it for starters -Title, load existing, and new file options. - -Silliness for checking that this works. - - $(-> $("h1").hide().slideDown(500)) - -Create buttos to choose between the New and Load functionalities -(As we aren't going to ever load a file _and_ do a new file.) -(If someone wants to do that, they can restart with F5 or something.) -Also hide the editor until needed, and initialize some elements. - - $(-> - $("#newsahli") - .button { disabled: false} - .click -> newsahli() - ) - - $(-> - $("#loadsahli") - .button { disabled: false} - .click -> loadsahli() - ) - $(-> - $(".hidden").hide() - $("#entryamiga").button {icons: {primary:"ui-icon-gear"}} - .click -> - stuff = $(@).children() - if @.value == "1" - stuff[1].textContent = 'Ansi' - @.value = "0" - else - stuff[1].textContent = 'Ascii' - @.value = "1" - $(".45box").css {width:'45%',display:'inline-block'} - $(".groupbox p").css {margin:"0 0 .25em 0"} - $(".colorbox").change => - sahlicolor() - - $("#entryfilepick").change -> - if @.files[0]? then $("#entryfile").val @.files[0].name - $("#entryfile").click -> - $("#entryfilepick").click() - - ) - -The sahli file definition format is as follows: -"file" - the actual filename on disk, "name" - the title of the piece, -the boolean 'amiga' indicates if it is ansi or ascii (True = ascii), -width is the width (widest point of the file), author the author of the piece, -the color and bg items define the color for amiga ascii, and the font -defines the font similarly. For PC ansi, this should be 'ansifont.' -The three remaining lines are informational and optional. - -The slide format is currently unused, but consists of a background picture, -a html template, and a css file. - - class emptyfiledef - constructor: -> - @file = "" - @name = "" - @amiga = true - @filetype = 'plain' - @width = "" - @author = "" - @font = "Propaz" - @color = [ 255,255,255,255 ] - @bg = [ 0,0,0,0 ] - @line1 = "" - @line2 = "" - @text = "" - - - class Sahli - constructor: -> - @emptyfiledef = new emptyfiledef - @emptyslidesdef = { - "background": "", - "template": "", - "css": "" - } - @empty = { - "location": "", - "slides": @emptyslidesdef, - "filedata": [ ] - } - - loader: -> - $.ajax { - url: '../list.sahli', - dataType: "json", - success: (result) => - @data = result - @.edit() - } - -Editor functionality: -Close the new/load buttons - unneeded now. -list, and allow dragon-droppings for sorting. Doubleclick to edit, or use -edit button. - - edit: -> - $('#buttonbox').hide() - $('#dirlocation').change (event) => - @data.location = event.target.value - $('#listsave').button {icons: {primary:"ui-icon-disk"}} - .click => - $('#sahlioutput').text dumpjson @data - $('#dumparea').show 100 - console.log dumpjson @data - $('#listlist').button {icons: {primary:"ui-icon-folder-open"}} - .click -> - getfilelist() - $('#listappend').button {icons: {primary:"ui-icon-1-n"}} - .click (event) => - newentry = new emptyfiledef - @data.filedata.push newentry - @buildlist @data - $('#listdisplay').button {icons: {primary:"ui-icon-refresh"}} - .click => - @buildlist @data - - $('#closespan').click -> - $(@parentElement.parentElement).hide() - $('#sahlioutput').text '' - - -You need to save the order, and extract these in that order; moving around -does not alter the array. Alternately, _have_ it alter the array. - - @buildlist @data - - buildlist: (data) -> - $('#list').show 100 - $('#list ol li').remove() - console.log i.author for i in @data.filedata - x = 0 - $('#dirlocation').val @data.location - $('#sortlist').append @.additem item,x++ for item in @data.filedata - $('#sortlist').sortable - start: (event,ui) -> - ui.item.data {startpos:ui.item.index()} - stop: (event,ui) => - s = ui.item.data().startpos - e = ui.item.index() - @data.filedata = @.rearrangearray s,e,@data.filedata - console.log name.author,name.name,name.file for name in @data.filedata - console.log '---' - @buildlist @data - -Given a start and and end position, pop the array element at start off and -insert it into the array at end position. A la the draggon-dropping. - - rearrangearray: (startpos,endpos,a) -> - moving = a[startpos] - alen = a.length - tarr = a[0...startpos].concat a[startpos+1..-1] - tarr[0...endpos].concat [moving].concat tarr[endpos..-1] - - - additem: (item,pos) -> - entry = @genentryline item,pos - entry.dblclick => - @editline item,pos - - genentryline: (item,pos) -> - arrows = "" - amigastatus = ansiorascii booltoint item.amiga - delbutton = $("delete") - .click (event) => - pos = event.currentTarget.id.replace "del-","" - @data.filedata.splice pos,1 - @buildlist @data - entry = $("
  • #{arrows}#{amigastatus} | #{item.author} : #{item.name} : #{item.file}
  • ") - entry.append delbutton - - - save: -> - pos = $("#entryindex").val() - entry = @data.filedata[pos] - entry.name = $("#entryname").val() - entry.author = $("#entryauthor").val() - entry.amiga = statustobool $("#entryamiga").children()[1].textContent - console.log $("#entryamiga").children()[1].textContent,entry.amiga,entry.author - entry.color = colortoarray $("#entrycolor").val() - entry.bg = colortoarray $("#entrybg").val() - entry.width = $("#entrywidth").val() - entry.line1 = $("#entryline1").val() - entry.line2 = $("#entryline2").val() - entry.text = $("#entrytext").val() - entry.file = $("#entryfile").val() - entry.filetype = $("#entryfiletype").val() - @buildlist @data - - editline: (data,pos) -> - $("#formica").dialog { - width:'800', - modal: false, - title:"Entry #{data.file} ", - buttons: [{ - text: "Cancel", - icons: {primary: 'ui-icon-trash'}, - click: -> - $(@).dialog "close" - },{ - text: "Save", - icons: {primary: 'ui-icon-disk'}, - click: (event) => - event.preventDefault() - @save() - event.currentTarget.previousElementSibling.click() - - }] - } - - data.amiga = booltoint data.amiga - - fcol = colortoname arraytocolor data.color - bcol = colortoname arraytocolor data.bg - - $("#entryindex").val pos - $("#entryname").val data.name - $("#entryauthor").val data.author - $("#entryfiletpye").val data.filetype - $("#entryfiletype").children()[resolvefiletype data.filetype].selected = true - $("#entryamiga").val data.amiga - $("#entryamiga").children()[1].textContent = ansiorascii data.amiga - $("#entryfont").val data.font - $("#entrycolor").val fcol - $("#entrycolor").children()[colorindex fcol ].selected = true - $("#entrybg").val bcol - $("#entrybg").children()[colorindex bcol ].selected = true - $("#entrywidth").val data.width - $("#entryline1").val data.line1 - $("#entryline2").val data.line2 - $("#entrytext").val data.text - $("#entryfile").val data.file - sahlicolor() - - -A Helper function to dump json out of an object as text: - - dumpjson = (obj) -> - JSON.stringify obj,null,"\t" - -Boolean / integer Helpers - - booltoint = (bool) -> - bool + 1 - 1 - - inttobool = (intstr) -> - (intstr == 1).toString() - - statustobool = (status) -> - if status is 'Ascii' then true else false - -Resolve filetype offset in array: - - resolvefiletype = (filetype) -> - options = { - "plain":0 - "ansi":1 - "xbin":2 - "ice":3 - "adf":4 - "avatar":5 - "bin":6 - "idf":7 - "pcboard":8 - "tundra":9 - } - options[filetype] - -Resolve ansi or ascii status - - ansiorascii = (status) -> - if status is 0 then "Ansi" else "Ascii" - - -Color conversion from array to color item: - -This decimal to hex conversion only handles 00-FF but it's fine for this purpose; -we actually _want_ that limitation in the output. - - dec2hex = (num) -> - "#{('000'+num.toString 16).slice -2}" - - hex2dec = (num) -> - parseInt num,16 - - arraytocolor = (array) -> - c = (dec2hex x for x in array)[0..2].join '' - "##{c}" - - colortoarray = (color) -> - color = color.slice(1) - c1 = [ color[0..1], color[2..3], color[4..5] ] - x = (hex2dec i for i in c1) - x.push 255 - x - -Need a way to convert the array back to the color name. - - colortoname = (color) -> - names = { - "#E0E0E0":"Light Grey" - "#A0A0E0":"Light Blue" - "#9AFE2E":"Light Green" - "#FF0000":"Red" - "#FF8000":"Orange" - "#FFFF00":"Yellow" - "#00F000":"Green" - "#2EFEF7":"Cyan" - "#002EF7":"Blue" - "#0B0B3B":"Navy" - "#FF00FF":"Magenta" - "#8000FF":"Purple" - "#0A2A0A":"Dark Green" - "#3B3B3B":"Dark Grey" - "#FFFFFF":"White" - "#000000":"Black" - } - color = color.toUpperCase() - colorname = names[color] - bw = if hex2dec(color.slice(1)) > 8421504 then 'White' else "Black" - ret = if colorname? then colorname else bw - -Similarly, need to be able to get the color index. - - colorindex = (colorname) -> - names = { - "Light Grey":0 - "Light Blue":1 - "Light Green":2 - "Red":3 - "Orange":4 - "Yellow":5 - "Green":6 - "Cyan":7 - "Blue":8 - "Navy":9 - "Magenta":10 - "Purple":11 - "Dark Green":12 - "Dark Grey":13 - "White":14 - "Black":15 - } - names[colorname] - - -A function for changing the fore and background colors of the sahli ascii example - - sahlicolor = -> - fg = $('#entrycolor').val() - bg = $('#entrybg').val() - console.log 'sahlicolor',fg,bg - $('#sahliascii').css {'color':fg,'background':bg} - -Function for loading the filelist from the specified directory on the server/filesystem. - - getfilelist = -> - location = $("#dirlocation").val() - $.get("../#{location}", (listing) -> - console.log listing - ) - - - - -When clicking 'New' we want to make a brand new Sahli, and then clear out -the buttons and create the editor bit as blank. - - newsahli = -> - sahli = new Sahli - sahli.data = sahli.empty - newentry = new emptyfiledef - sahli.data.filedata.push newentry - sahli.edit() - -And when clicking 'load' we want to load the existing sahli file. - - loadsahli = -> - sahli = new Sahli - sahli.loader 'list.sahli' diff --git a/editor/sahlieditor.html b/editor/sahlieditor.html index 547f106..3c9bd68 100644 --- a/editor/sahlieditor.html +++ b/editor/sahlieditor.html @@ -83,12 +83,12 @@
  • @@ -138,10 +138,11 @@
    -   ________________________,  ._____,
    -  |  ___|___    |  |   |   |  |_____|
    -  |_____  |  _  |      |   |__|   |
    -    |_____|_____|___|__|______|___|
    +ABCDEFGHIJKLMNOPQRSTUVWXYZ><~`'"^&eXmPl
    +abcdefghijklmnopqrstuvwxyz1234567890?+@
    +* |  ___)___    7  I   |   |  \-~=#/  $
    +: |_____  | {~} !      |   \__[   : #~%
    +;   (_____j__"__l___|__|______]___; 0Oo