From 01f387f8e6930769422b26dc5e35d408adc3caaf Mon Sep 17 00:00:00 2001 From: ngradwohl Date: Wed, 17 Jul 2019 06:17:17 +0200 Subject: [PATCH 01/24] added my "Ronin experiment no 1 - spiral" --- examples/g_spiral1.lisp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 examples/g_spiral1.lisp diff --git a/examples/g_spiral1.lisp b/examples/g_spiral1.lisp new file mode 100644 index 0000000..c2fcc22 --- /dev/null +++ b/examples/g_spiral1.lisp @@ -0,0 +1,24 @@ +( + (defn rec + (v) + (if (gt v 0) + ((stroke + (circle + (add 300 + (mul (cos (add (div v 17) (div (time) 2000))) + (div v 2) + ) + ) + (add 300 + (mul (sin (div v 11)) + (div v 2) + ) + ) + (div v 2)) + 1 "rgba(255,255,255,0.1") + (rec (sub v 0.3)) + ) + ) + ) +(rec 300) +) From 828b9823ce46d44d66ce985ada84ea7aecf18574 Mon Sep 17 00:00:00 2001 From: ngradwohl Date: Wed, 17 Jul 2019 06:28:27 +0200 Subject: [PATCH 02/24] added comments --- examples/g_spiral1.lisp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/g_spiral1.lisp b/examples/g_spiral1.lisp index c2fcc22..741ef27 100644 --- a/examples/g_spiral1.lisp +++ b/examples/g_spiral1.lisp @@ -1,3 +1,6 @@ +; animated recusive spiral +; click on "toggle animation" +; by @local_guru ( (defn rec (v) From f6c94cbb36993fd5d80c34c318e523671b8b171a Mon Sep 17 00:00:00 2001 From: ngradwohl Date: Wed, 17 Jul 2019 06:42:11 +0200 Subject: [PATCH 03/24] added new "start" function --- examples/g_spiral1.lisp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/g_spiral1.lisp b/examples/g_spiral1.lisp index 741ef27..0fc82e6 100644 --- a/examples/g_spiral1.lisp +++ b/examples/g_spiral1.lisp @@ -1,7 +1,8 @@ ; animated recusive spiral -; click on "toggle animation" ; by @local_guru ( + (def start (get ronin "animate")) + (clear) (defn rec (v) (if (gt v 0) @@ -23,5 +24,6 @@ ) ) ) +(start) (rec 300) ) From 7d27897d8bbbc0cd67c06fb75f1f52899be541e0 Mon Sep 17 00:00:00 2001 From: Quentin Leonetti Date: Wed, 17 Jul 2019 21:27:56 +0200 Subject: [PATCH 04/24] add linear gradient --- desktop/sources/scripts/library.js | 6 ++++++ desktop/sources/scripts/surface.js | 9 +++++++++ examples/gradient.lisp | 16 ++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 examples/gradient.lisp diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index c04f194..b1a0e46 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -215,6 +215,12 @@ function Library (ronin) { return getComputedStyle(el).getPropertyValue(`--${variable}`) } + // Gradients + + this.gradient = ([x1,y1,x2,y2], colors=['white','black']) => { + return ronin.surface.linearGradient(x1, y1, x2, y2, colors) + } + // Pixels this.pixels = (rect, fn, q) => { diff --git a/desktop/sources/scripts/surface.js b/desktop/sources/scripts/surface.js index d1143e0..e7de660 100644 --- a/desktop/sources/scripts/surface.js +++ b/desktop/sources/scripts/surface.js @@ -61,6 +61,15 @@ function Surface (ronin) { context.closePath() } + this.linearGradient = function(x1, y1, x2, y2, colors, context = this.context) { + const gradient = context.createLinearGradient(x1, y1, x2, y2) + const step = 1/(colors.length - 1) + colors.forEach((color,i) => { + gradient.addColorStop(i*step, color) + }) + return gradient + } + // Tracers this.trace = function (shape, context) { diff --git a/examples/gradient.lisp b/examples/gradient.lisp new file mode 100644 index 0000000..b11e9aa --- /dev/null +++ b/examples/gradient.lisp @@ -0,0 +1,16 @@ +( +; gradients + +(clear) +(fill + (svg "M405,15 L405,15 L150,150 L195,90 L240,135 L120,195 L75,90 L135,165 L120,225 L90,240 L60,210 L90,150 L255,180 L285,180 L285,165 ") + (gradient + (0 -50 600 175) + ("red" "orange" "blue" "green"))) + +(stroke + (svg "M255,60 L255,60 L135,180 L75,60 L195,210 L120,225 L105,225 L165,255 L225,195 L255,135 L285,150") 1 + (gradient + (50 0 180 0) + ("black" "white" "blue" "green"))) +) \ No newline at end of file From d59e6e93fff63d87dfa367e73453462eb12db95f Mon Sep 17 00:00:00 2001 From: Quentin Leonetti Date: Wed, 17 Jul 2019 21:47:11 +0200 Subject: [PATCH 05/24] remove old filter --- desktop/sources/scripts/library.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index b1a0e46..14e96b7 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -79,9 +79,6 @@ function Library (ronin) { return Promise.all(arr.map(fn)) } - this._filter = (fn, arr) => { - return arr.filter(fn) - } this.filter = (fn, arr) => { const list = Array.from(arr) return Promise.all(list.map((element, index) => fn(element, index, list))) From 24f6f93c4ff07012b46bfe6d8caf040cb24091db Mon Sep 17 00:00:00 2001 From: Quentin Leonetti Date: Wed, 17 Jul 2019 22:33:27 +0200 Subject: [PATCH 06/24] add start of documentation --- documentation.md | 155 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 documentation.md diff --git a/documentation.md b/documentation.md new file mode 100644 index 0000000..13fb4e4 --- /dev/null +++ b/documentation.md @@ -0,0 +1,155 @@ +# Functions + +## IO + +`(open path)` + +`(export path type quality)` + +`(draw path rect)` + +`(resize width height)` + +`(crop rect)` + +`(folder path)` + +`(exit)` + +## Logic + +`(gt a b)` check if `a` is greater than `b` + +`(lt a b)` check if `a` is lower than `b` + +`(eq a b)` check if `a` is equal to `b` + +`(and a b )` returns true if all conditions are true + +`(or a b )` returns true if at least one condition is true + +## Arrays + +`(map function array)` + +`(filter function array)` + +`(reduce function array accumulator)` + +`(len array)` + +`(first array)` + +`(last array)` + +`(rest array)` + +`(range start end step)` + +## Shapes + +`(pos x y)` + +`(size w h)` + +`(rect x y w h t)` + +`(circle x y r)` + +`(line start end)` + +`(text x y g string font)` + +`(svg data)` + +## Helpers + +`(frame)` + +`(center)` + +`(scale rect width height)` + +## Copy/Paste + +`(clone start end)` clone start `rect` into end `rect` + +`(stroke shape thickness color)` + +`(fill shape color)` + +`(clear shape)` + +## Objects + +`(get item key )` + +`(set item key val)` + +## Colors + +`(theme variable)` + +`(gradient (x1,y1,x2,y2) colors)` + +`(pixels rect function q)` + +`(saturation pixel q)` + +`(contrast pixel q)` + +## Math + +`(add ...values)` + +`(sub...values)` + +`(mul ...values)` + +`(div ...values)` + +`(mod a b)` + +`(clamp value min max)` + +`(step value step)` + +`(min a b)` + +`(max a b)` + +`(ceil value)` + +`(floor value)` + +`(sin a)` + +`(cos a)` + +`PI, TWO_PI` + +`(random)` + +`(random start end)` + +`(random max)` + +## Generics + +`(echo args)` + +`(str args)` + +`(test name value expectedValue)` + +## Livecoding + +`(time)` returns timestamp in milliseconds + +## Javascript interop + +`js` + +## Client + +`ronin` From 77eb301d3e7118646311d9aabe8081e9f1075751 Mon Sep 17 00:00:00 2001 From: Quentin Leonetti Date: Wed, 17 Jul 2019 22:35:03 +0200 Subject: [PATCH 07/24] add link to documentation --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6682bc3..6c8cf4e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,10 @@ npm install npm start ``` +## Documentation + +Documentation is accessible [here](./documentation.md) + ## Extras - This application supports the [Ecosystem Theme](https://github.com/hundredrabbits/Themes). From 521ece7937a40f387b97237e7f83d57e281a415d Mon Sep 17 00:00:00 2001 From: Quentin Leonetti Date: Wed, 17 Jul 2019 23:00:21 +0200 Subject: [PATCH 08/24] add (animate) --- desktop/sources/scripts/library.js | 8 ++++++-- documentation.md | 4 ++++ examples/animate.lisp | 5 ++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 14e96b7..1ea70c6 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -1,4 +1,5 @@ function Library (ronin) { + console.log(ronin) this.open = async (path) => { return ronin.surface.open(path) } @@ -326,12 +327,15 @@ function Library (ronin) { return a === b } + // Client + this.ronin = ronin + // Livecoding this.time = Date.now + this.animate = (b = true) => ronin.animate(b) + // javascript interop this.js = window - // Client - this.ronin = ronin } diff --git a/documentation.md b/documentation.md index 13fb4e4..706fee5 100644 --- a/documentation.md +++ b/documentation.md @@ -146,6 +146,10 @@ `(time)` returns timestamp in milliseconds +`(animate)` start animation + +`(animate false)` stop animation + ## Javascript interop `js` diff --git a/examples/animate.lisp b/examples/animate.lisp index fa12b3c..b43d696 100644 --- a/examples/animate.lisp +++ b/examples/animate.lisp @@ -1,13 +1,12 @@ ; animate ( - (def start (get ronin "animate")) - (def t (sin (div (time) 100))) (def pos (add 200 (mul 30 t))) (defn square (a) (rect a a a a)) (stroke (square pos) 1 "red") - (start) + (animate) + ;(animate false) to stop animation ) \ No newline at end of file From eedd6868a1b6460fb40347dc412faaae72da4219 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 08:24:43 +0900 Subject: [PATCH 09/24] Implemented docs --- desktop/sources/scripts/commander.js | 25 ++++++++++++++++++++++++- desktop/sources/scripts/library.js | 4 +--- desktop/sources/scripts/surface.js | 8 ++++---- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index ccf9f1f..a4e8aec 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -10,8 +10,8 @@ function Commander (ronin) { this.el.appendChild(this._input) this.el.appendChild(this._status) host.appendChild(this.el) - this._input.addEventListener('input', this.onInput) + this.docs.install() } this.start = function () { @@ -162,4 +162,27 @@ function Commander (ronin) { this.hide() } } + + // Docs micro-module + + this.docs = { + path: 'sources/scripts/library.js', + load: function () { + const fs = require('fs') + if (!fs.existsSync(this.path)) { console.warn('Docs', 'File does not exist: ' + this.path); return } + const lines = fs.readFileSync(this.path, 'utf8').split('\n').filter((line) => { return line.substr(0, 7) === ' this.' }) + return lines.map((line) => { return line.trim().substr(5, line.length - 5).trim() }) + }, + install: function (payload = this.load()) { + const dict = {} + for (const id in payload) { + const parts = payload[id].split(' = ') + const name = parts[0] + const params = parts[1].match(/\(([^)]+)\)/) + if (!params) { console.warn('Docs', 'Misformatted ' + name); continue } + dict[name] = params[1].split(',').map((word) => { return word.trim() }) + } + console.log(dict) + } + } } diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 1ea70c6..0cdc753 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -1,5 +1,4 @@ function Library (ronin) { - console.log(ronin) this.open = async (path) => { return ronin.surface.open(path) } @@ -215,7 +214,7 @@ function Library (ronin) { // Gradients - this.gradient = ([x1,y1,x2,y2], colors=['white','black']) => { + this.gradient = ([x1, y1, x2, y2], colors = ['white', 'black']) => { return ronin.surface.linearGradient(x1, y1, x2, y2, colors) } @@ -337,5 +336,4 @@ function Library (ronin) { // javascript interop this.js = window - } diff --git a/desktop/sources/scripts/surface.js b/desktop/sources/scripts/surface.js index e7de660..a1bd5eb 100644 --- a/desktop/sources/scripts/surface.js +++ b/desktop/sources/scripts/surface.js @@ -61,11 +61,11 @@ function Surface (ronin) { context.closePath() } - this.linearGradient = function(x1, y1, x2, y2, colors, context = this.context) { + this.linearGradient = function (x1, y1, x2, y2, colors, context = this.context) { const gradient = context.createLinearGradient(x1, y1, x2, y2) - const step = 1/(colors.length - 1) - colors.forEach((color,i) => { - gradient.addColorStop(i*step, color) + const step = 1 / (colors.length - 1) + colors.forEach((color, i) => { + gradient.addColorStop(i * step, color) }) return gradient } From 5d9472af18d531277a0427b5c95139f8ed936af8 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 08:33:07 +0900 Subject: [PATCH 10/24] Prints docs on launch --- desktop/sources/scripts/commander.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index a4e8aec..765c71d 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -166,23 +166,31 @@ function Commander (ronin) { // Docs micro-module this.docs = { + dict: {}, path: 'sources/scripts/library.js', load: function () { const fs = require('fs') if (!fs.existsSync(this.path)) { console.warn('Docs', 'File does not exist: ' + this.path); return } const lines = fs.readFileSync(this.path, 'utf8').split('\n').filter((line) => { return line.substr(0, 7) === ' this.' }) - return lines.map((line) => { return line.trim().substr(5, line.length - 5).trim() }) + return lines.map((line) => { return line.trim().substr(5).trim() }) }, install: function (payload = this.load()) { - const dict = {} for (const id in payload) { const parts = payload[id].split(' = ') const name = parts[0] const params = parts[1].match(/\(([^)]+)\)/) if (!params) { console.warn('Docs', 'Misformatted ' + name); continue } - dict[name] = params[1].split(',').map((word) => { return word.trim() }) + this.dict[name] = params[1].split(',').map((word) => { return word.trim() }) } - console.log(dict) + console.log('Dict', `Loaded ${Object.keys(this.dict).length} functions.`) + console.log(this.toMarkdown()) + }, + toMarkdown: function () { + return Object.keys(this.dict).reduce((acc, item, key) => { + return `${acc}- \`(${item} ${this.dict[item].reduce((acc, item) => { + return `${acc}${item} ` + }, '').trim()})\`\n` + }, '') } } } From aa0415a2001b8fcf6e6a1fa42ec8322879ca9310 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 08:48:00 +0900 Subject: [PATCH 11/24] Started documenting --- desktop/sources/scripts/commander.js | 16 ++++++++++------ desktop/sources/scripts/library.js | 12 ++++++------ desktop/sources/scripts/source.js | 4 ++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index 765c71d..7268d6c 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -178,18 +178,22 @@ function Commander (ronin) { for (const id in payload) { const parts = payload[id].split(' = ') const name = parts[0] - const params = parts[1].match(/\(([^)]+)\)/) - if (!params) { console.warn('Docs', 'Misformatted ' + name); continue } - this.dict[name] = params[1].split(',').map((word) => { return word.trim() }) + const parent = parts[1].match(/\(([^)]+)\)/) + const params = parent ? parent[1].split(',').map((word) => { return word.trim() }) : [] + const note = payload[id].indexOf('// ') > -1 ? payload[id].split('//')[1].trim() : '' + this.dict[name] = { note, params } + if (params.length < 1) { console.warn('Docs', 'Missing params for ' + name) } + if (note === '') { console.warn('Docs', 'Missing note for ' + name) } } - console.log('Dict', `Loaded ${Object.keys(this.dict).length} functions.`) + console.log('Docs', `Loaded ${Object.keys(this.dict).length} functions.`) console.log(this.toMarkdown()) }, toMarkdown: function () { return Object.keys(this.dict).reduce((acc, item, key) => { - return `${acc}- \`(${item} ${this.dict[item].reduce((acc, item) => { + const example = `${item} ${this.dict[item].params.reduce((acc, item) => { return `${acc}${item} ` - }, '').trim()})\`\n` + }, '').trim()}` + return `${acc}- \`(${example.trim()})\` ${this.dict[item].note}\n` }, '') } } diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 0cdc753..fccd085 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -31,25 +31,25 @@ function Library (ronin) { return ronin.surface.crop(rect) } - this.folder = (path = ronin.source.path) => { + this.folder = (path = ronin.source.path) => { // Returns the content of a folder path. return fs.existsSync(path) ? fs.readdirSync(path) : [] } - this.exit = () => { - ronin.source.quit() + this.exit = (force = false) => { // Exits Ronin/ + ronin.source.quit(force) } // Logic - this.gt = (a, b) => { + this.gt = (a, b) => { // Returns true if a is greater than b, else false. return a > b } - this.lt = (a, b) => { + this.lt = (a, b) => { // Returns true if a is less than b, else false. return a < b } - this.eq = (a, b) => { + this.eq = (a, b) => { // Returns true if a is equal to b, else false. return a === b } diff --git a/desktop/sources/scripts/source.js b/desktop/sources/scripts/source.js index 29a6457..71bb8eb 100644 --- a/desktop/sources/scripts/source.js +++ b/desktop/sources/scripts/source.js @@ -75,8 +75,8 @@ function Source (ronin) { ronin.commander._input.value = data } - this.quit = function () { - if (this.hasChanges() === true) { + this.quit = function (force = false) { + if (this.hasChanges() === true && force === false) { this.verify() } else { app.exit() From c916fcab5fa8f52ae4925208eda85320a702f11a Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 08:54:23 +0900 Subject: [PATCH 12/24] Improved reading of params --- desktop/sources/scripts/commander.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index 7268d6c..58e3680 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -176,10 +176,9 @@ function Commander (ronin) { }, install: function (payload = this.load()) { for (const id in payload) { - const parts = payload[id].split(' = ') - const name = parts[0] - const parent = parts[1].match(/\(([^)]+)\)/) - const params = parent ? parent[1].split(',').map((word) => { return word.trim() }) : [] + const name = payload[id].substr(0, payload[id].indexOf(' = ')) + const parent = payload[id].substr(payload[id].indexOf(' = ')).match(/\(([^)]+)\)/) + const params = parent ? parent[1].split(',').map((word) => { return word.indexOf(' = ') ? word.split(' = ')[0].trim() : word }) : [] const note = payload[id].indexOf('// ') > -1 ? payload[id].split('//')[1].trim() : '' this.dict[name] = { note, params } if (params.length < 1) { console.warn('Docs', 'Missing params for ' + name) } From 194c128234f94b4c1c915b724317df57f2c3b2ce Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 09:07:21 +0900 Subject: [PATCH 13/24] Progress on docs --- desktop/sources/scripts/library.js | 187 ++++++++++++++--------------- 1 file changed, 92 insertions(+), 95 deletions(-) diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index fccd085..bffba50 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -11,26 +11,6 @@ function Library (ronin) { return path } - this.draw = async (path, rect) => { - const img = new Image() - img.src = path - return ronin.surface.draw(img, rect) - } - - this.resize = async (w = 1, h = 1) => { - const rect = w <= 1 || h <= 1 ? { x: 0, y: 0, w: this.frame().w * w, h: this.frame().h * h } : { x: 0, y: 0, w, h } - const a = document.createElement('img') - const b = document.createElement('img') - a.src = ronin.surface.el.toDataURL() - ronin.surface.resizeImage(a, b) - ronin.surface.resize(rect, true) - return ronin.surface.draw(b, rect) - } - - this.crop = async (rect) => { - return ronin.surface.crop(rect) - } - this.folder = (path = ronin.source.path) => { // Returns the content of a folder path. return fs.existsSync(path) ? fs.readdirSync(path) : [] } @@ -39,6 +19,63 @@ function Library (ronin) { ronin.source.quit(force) } + // Math + + this.add = (...args) => { // Adds values. + return args.reduce((sum, val) => sum + val) + } + + this.sub = (...args) => { // Subtracts values. + return args.reduce((sum, val) => sum - val) + } + + this.mul = (...args) => { // Multiplies values. + return args.reduce((sum, val) => sum * val) + } + + this.div = (...args) => { // Divides values. + return args.reduce((sum, val) => sum / val) + } + + this.mod = (a, b) => { // Returns the modulo of a and b. + return a % b + } + + this.clamp = (val, min, max) => { // Clamps a value between min and max. + return Math.min(max, Math.max(min, val)) + } + + this.step = (val, step) => { + return Math.round(val / step) * step + } + + this.min = Math.min + + this.max = Math.max + + this.ceil = Math.ceil + + this.floor = Math.floor + + this.sin = Math.sin + + this.cos = Math.cos + + this.PI = Math.PI + + this.TWO_PI = Math.PI * 2 + + this.random = (...args) => { + if (args.length >= 2) { + // (random start end) + return args[0] + Math.random() * (args[1] - args[0]) + } else if (args.length === 1) { + // (random max) + return Math.random() * args[0] + } + return Math.random() + } + // Logic this.gt = (a, b) => { // Returns true if a is greater than b, else false. @@ -93,15 +130,15 @@ function Library (ronin) { return arr.reduce(fn, acc) } - this.len = (item) => { + this.len = (item) => { // Returns the length of a list. return item.length } - this.first = (arr) => { + this.first = (arr) => { // Returns the first item of a list. return arr[0] } - this.last = (arr) => { + this.last = (arr) => { // Returns the last return arr[arr.length - 1] } @@ -125,41 +162,41 @@ function Library (ronin) { // Shapes - this.pos = (x, y, t = 'pos') => { + this.pos = (x, y, t = 'pos') => { // Returns a position shape. return { x, y, t } } - this.size = (w, h, t = 'size') => { + this.size = (w, h, t = 'size') => { // Returns a size shape. return { w, h, t } } - this.rect = (x, y, w, h, t = 'rect') => { + this.rect = (x, y, w, h, t = 'rect') => { // Returns a rect shape. return { x, y, w, h, t } } - this.circle = (x, y, r, t = 'circle') => { + this.circle = (x, y, r, t = 'circle') => { // Returns a circle shape. return { x, y, r, t } } - this.line = (a, b, t = 'line') => { + this.line = (a, b, t = 'line') => { // Returns a line shape. return { a, b, t } } - this.text = (x, y, g, s, f = 'Arial', t = 'text') => { + this.text = (x, y, g, s, f = 'Arial', t = 'text') => { // Returns a text shape. return { x, y, g, s, f, t } } - this.svg = (d, t = 'svg') => { + this.svg = (d, t = 'svg') => { // Returns a svg shape. return { d, t } } // Helpers - this.frame = () => { + this.frame = () => { // Returns a rect of the frame. return ronin.surface.getFrame() } - this.center = () => { + this.center = () => { // Returns a position of the center of the frame. const rect = this.frame() return this.pos(rect.w / 2, rect.h / 2) } @@ -175,26 +212,26 @@ function Library (ronin) { return [a, b] } - this.stroke = (shape = this.frame(), thickness, color) => { + this.stroke = (shape = this.frame(), thickness, color) => { // Strokes a shape. ronin.surface.stroke(shape, thickness, color) return shape } - this.fill = (rect = this.frame(), color) => { + this.fill = (rect = this.frame(), color) => { // Fills a shape. ronin.surface.fill(rect, color) return rect } - this.clear = (rect = this.frame()) => { + this.clear = (rect = this.frame()) => { // Clears a rect. ronin.surface.clear(rect) return rect } - this.get = (item, key) => { + this.get = (item, key) => { // Gets an object's parameter with name. return item[key] } - this.set = (item, key, val) => { + this.set = (item, key, val) => { // Sets an object's parameter with name as value. item[key] = val return item[key] } @@ -220,6 +257,12 @@ function Library (ronin) { // Pixels + this.draw = async (path, rect) => { + const img = new Image() + img.src = path + return ronin.surface.draw(img, rect) + } + this.pixels = (rect, fn, q) => { const img = ronin.surface.context.getImageData(0, 0, rect.w, rect.h) for (let i = 0, loop = img.data.length; i < loop; i += 4) { @@ -244,61 +287,20 @@ function Library (ronin) { return [pixel.r * q + intercept, pixel.g * q + intercept, pixel.b * q + intercept, pixel.a] } - // Math + // - this.add = (...args) => { - return args.reduce((sum, val) => sum + val) + this.resize = async (w = 1, h = 1) => { + const rect = w <= 1 || h <= 1 ? { x: 0, y: 0, w: this.frame().w * w, h: this.frame().h * h } : { x: 0, y: 0, w, h } + const a = document.createElement('img') + const b = document.createElement('img') + a.src = ronin.surface.el.toDataURL() + ronin.surface.resizeImage(a, b) + ronin.surface.resize(rect, true) + return ronin.surface.draw(b, rect) } - this.sub = (...args) => { - return args.reduce((sum, val) => sum - val) - } - - this.mul = (...args) => { - return args.reduce((sum, val) => sum * val) - } - - this.div = (...args) => { - return args.reduce((sum, val) => sum / val) - } - - this.mod = (a, b) => { - return a % b - } - - this.clamp = (val, min, max) => { - return Math.min(max, Math.max(min, val)) - } - - this.step = (val, step) => { - return Math.round(val / step) * step - } - - this.min = Math.min - - this.max = Math.max - - this.ceil = Math.ceil - - this.floor = Math.floor - - this.sin = Math.sin - - this.cos = Math.cos - - this.PI = Math.PI - - this.TWO_PI = Math.PI * 2 - - this.random = (...args) => { - if (args.length >= 2) { - // (random start end) - return args[0] + Math.random() * (args[1] - args[0]) - } else if (args.length === 1) { - // (random max) - return Math.random() * args[0] - } - return Math.random() + this.crop = async (rect) => { + return ronin.surface.crop(rect) } // Generics @@ -313,12 +315,7 @@ function Library (ronin) { } this.test = (name, a, b) => { - if (Array.isArray(a)) { - // TODO: make testing more solid - a = a.toString() - b = b.toString() - } - if (a !== b) { + if (`${a}` !== `${b}`) { console.warn('failed ' + name, a, b) } else { console.log('passed ' + name, a) From 7890968398a644b41eefde560562a23b8728ef87 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 09:09:52 +0900 Subject: [PATCH 14/24] Further documentation --- desktop/sources/scripts/library.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index bffba50..99a3291 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -90,7 +90,7 @@ function Library (ronin) { return a === b } - this.and = (a, b, ...rest) => { + this.and = (a, b, ...rest) => { // Returns true if all conditions are true. let args = [a, b].concat(rest) for (let i = 0; i < args.length; i++) { if (!args[i]) { @@ -100,7 +100,7 @@ function Library (ronin) { return args[args.length - 1] } - this.or = (a, b, ...rest) => { + this.or = (a, b, ...rest) => { // Returns true if at least one condition is true. let args = [a, b].concat(rest) for (let i = 0; i < args.length; i++) { if (args[i]) { @@ -327,9 +327,13 @@ function Library (ronin) { this.ronin = ronin // Livecoding - this.time = Date.now + this.time = () => { // Returns timestamp in milliseconds. + return Date.now + } - this.animate = (b = true) => ronin.animate(b) + this.animate = (play = true) => { // Toggles animation. + ronin.animate(play) + } // javascript interop this.js = window From bf17394bc47619882f374735476596f1025a4ec1 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 09:19:09 +0900 Subject: [PATCH 15/24] Improved README --- README.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6c8cf4e..a118927 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,89 @@ # Ronin -_All I wanted, was a way of resizing photos._ +_"All I wanted, was a quick way of resizing a few photos.."_ -Ronin is a LISP repl to create generative graphics currently under development. You can follow the daily progress on [Mastodon](https://merveilles.town/@neauoire/). Until we have documented the library, you can find a list of available functions [here](https://github.com/hundredrabbits/Ronin/blob/master/desktop/sources/scripts/library.js). +Ronin is a [LISP](https://en.wikipedia.org/wiki/Lisp_(programming_language)) repl to create generative graphics currently under development. You can follow the daily progress on [Mastodon](https://merveilles.town/@neauoire/). - +## Install & Run -## Electron Build +You can download [builds](https://hundredrabbits.itch.io/ronin) for **OSX, Windows and Linux**, or if you wish to build it yourself, follow these steps: ``` -cd desktop +git clone https://github.com/hundredrabbits/Ronin.git +cd Ronin/desktop/ npm install npm start ``` -## Documentation + -Documentation is accessible [here](./documentation.md) +## Library + +- `(open path)` +- `(export path type quality)` +- `(folder path)` Returns the content of a folder path. +- `(exit force)` Exits Ronin/ +- `(add ...args)` Adds values. +- `(sub ...args)` Subtracts values. +- `(mul ...args)` Multiplies values. +- `(div ...args)` Divides values. +- `(mod a b)` Returns the modulo of a and b. +- `(clamp val min max)` Clamps a value between min and max. +- `(step val step)` +- `(min)` +- `(max)` +- `(ceil)` +- `(floor)` +- `(sin)` +- `(cos)` +- `(PI)` +- `(TWO_PI)` +- `(random ...args)` +- `(gt a b)` Returns true if a is greater than b, else false. +- `(lt a b)` Returns true if a is less than b, else false. +- `(eq a b)` Returns true if a is equal to b, else false. +- `(and a b ...rest)` Returns true if all conditions are true. +- `(or a b ...rest)` Returns true if at least one condition is true. +- `(map fn arr)` +- `(filter fn arr)` +- `(reduce fn arr acc)` +- `(len item)` Returns the length of a list. +- `(first arr)` Returns the first item of a list. +- `(last arr)` Returns the last +- `(rest [_ ...arr])` +- `(range start end step)` +- `(pos x y t)` Returns a position shape. +- `(size w h t)` Returns a size shape. +- `(rect x y w h t)` Returns a rect shape. +- `(circle x y r t)` Returns a circle shape. +- `(line a b t)` Returns a line shape. +- `(text x y g s f t)` Returns a text shape. +- `(svg d t)` Returns a svg shape. +- `(frame)` Returns a rect of the frame. +- `(center)` Returns a position of the center of the frame. +- `(scale rect w h)` +- `(clone a b)` +- `(stroke shape)` Strokes a shape. +- `(fill rect)` Fills a shape. +- `(clear rect)` Clears a rect. +- `(get item key)` Gets an object's parameter with name. +- `(set item key val)` Sets an object's parameter with name as value. +- `(of h ...keys)` +- `(theme variable el)` +- `(gradient [x1 y1 x2 y2] colors 'black'])` +- `(draw path rect)` +- `(pixels rect fn q)` +- `(saturation pixel q)` +- `(contrast pixel q)` +- `(resize w h)` +- `(crop rect)` +- `(echo ...args)` +- `(str ...args)` +- `(test name a b)` +- `(ronin)` +- `(time)` Returns timestamp in milliseconds. +- `(animate play)` Toggles animation. +- `(js)` ## Extras From 5b9819b84fd33d1b0a7e0d5a3290372d45c88266 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 09:28:03 +0900 Subject: [PATCH 16/24] Moved things around a bit --- README.md | 42 +++---- desktop/sources/scripts/library.js | 178 +++++++++++++++-------------- 2 files changed, 111 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index a118927..db36152 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,18 @@ npm start ## Library -- `(open path)` -- `(export path type quality)` -- `(folder path)` Returns the content of a folder path. -- `(exit force)` Exits Ronin/ +- `(import path rect)` Imports a graphic file with format. +- `(export path format quality)` Exports a graphic file with format. +- `(pos x y t)` Returns a position shape. +- `(size w h t)` Returns a size shape. +- `(rect x y w h t)` Returns a rect shape. +- `(circle x y r t)` Returns a circle shape. +- `(line a b t)` Returns a line shape. +- `(text x y g s f t)` Returns a text shape. +- `(svg d t)` Returns a svg shape. +- `(stroke shape)` Strokes a shape. +- `(fill rect)` Fills a shape. +- `(clear rect)` Clears a rect. - `(add ...args)` Adds values. - `(sub ...args)` Subtracts values. - `(mul ...args)` Multiplies values. @@ -52,38 +60,30 @@ npm start - `(last arr)` Returns the last - `(rest [_ ...arr])` - `(range start end step)` -- `(pos x y t)` Returns a position shape. -- `(size w h t)` Returns a size shape. -- `(rect x y w h t)` Returns a rect shape. -- `(circle x y r t)` Returns a circle shape. -- `(line a b t)` Returns a line shape. -- `(text x y g s f t)` Returns a text shape. -- `(svg d t)` Returns a svg shape. +- `(get item key)` Gets an object's parameter with name. +- `(set item key val)` Sets an object's parameter with name as value. - `(frame)` Returns a rect of the frame. - `(center)` Returns a position of the center of the frame. - `(scale rect w h)` +- `(resize w h)` +- `(crop rect)` - `(clone a b)` -- `(stroke shape)` Strokes a shape. -- `(fill rect)` Fills a shape. -- `(clear rect)` Clears a rect. -- `(get item key)` Gets an object's parameter with name. -- `(set item key val)` Sets an object's parameter with name as value. - `(of h ...keys)` - `(theme variable el)` - `(gradient [x1 y1 x2 y2] colors 'black'])` -- `(draw path rect)` - `(pixels rect fn q)` - `(saturation pixel q)` - `(contrast pixel q)` -- `(resize w h)` -- `(crop rect)` - `(echo ...args)` - `(str ...args)` -- `(test name a b)` +- `(open path)` Imports a graphic file and resizes the frame. +- `(folder path)` Returns the content of a folder path. +- `(exit force)` Exits Ronin. - `(ronin)` - `(time)` Returns timestamp in milliseconds. - `(animate play)` Toggles animation. -- `(js)` +- `(js)` +- `(test name a b)` ## Extras diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 99a3291..2a83d8e 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -1,22 +1,63 @@ function Library (ronin) { - this.open = async (path) => { - return ronin.surface.open(path) + this.import = async (path, rect) => { // Imports a graphic file with format. + const img = new Image() + img.src = path + return ronin.surface.draw(img, rect) } - this.export = (path, type = 'image/png', quality = 1.0) => { + this.export = (path, format = 'image/png', quality = 1.0) => { // Exports a graphic file with format. if (!path) { console.warn('Missing export path'); return path } - var dataUrl = ronin.surface.el.toDataURL(type, quality) + var dataUrl = ronin.surface.el.toDataURL(format, quality) const data = dataUrl.replace(/^data:image\/png;base64,/, '') fs.writeFileSync(path, data, 'base64') return path } - this.folder = (path = ronin.source.path) => { // Returns the content of a folder path. - return fs.existsSync(path) ? fs.readdirSync(path) : [] + // Shapes + + this.pos = (x, y, t = 'pos') => { // Returns a position shape. + return { x, y, t } } - this.exit = (force = false) => { // Exits Ronin/ - ronin.source.quit(force) + this.size = (w, h, t = 'size') => { // Returns a size shape. + return { w, h, t } + } + + this.rect = (x, y, w, h, t = 'rect') => { // Returns a rect shape. + return { x, y, w, h, t } + } + + this.circle = (x, y, r, t = 'circle') => { // Returns a circle shape. + return { x, y, r, t } + } + + this.line = (a, b, t = 'line') => { // Returns a line shape. + return { a, b, t } + } + + this.text = (x, y, g, s, f = 'Arial', t = 'text') => { // Returns a text shape. + return { x, y, g, s, f, t } + } + + this.svg = (d, t = 'svg') => { // Returns a svg shape. + return { d, t } + } + + // Actions + + this.stroke = (shape = this.frame(), thickness, color) => { // Strokes a shape. + ronin.surface.stroke(shape, thickness, color) + return shape + } + + this.fill = (rect = this.frame(), color) => { // Fills a shape. + ronin.surface.fill(rect, color) + return rect + } + + this.clear = (rect = this.frame()) => { // Clears a rect. + ronin.surface.clear(rect) + return rect } // Math @@ -160,37 +201,18 @@ function Library (ronin) { return arr } - // Shapes + // Objects - this.pos = (x, y, t = 'pos') => { // Returns a position shape. - return { x, y, t } + this.get = (item, key) => { // Gets an object's parameter with name. + return item[key] } - this.size = (w, h, t = 'size') => { // Returns a size shape. - return { w, h, t } + this.set = (item, key, val) => { // Sets an object's parameter with name as value. + item[key] = val + return item[key] } - this.rect = (x, y, w, h, t = 'rect') => { // Returns a rect shape. - return { x, y, w, h, t } - } - - this.circle = (x, y, r, t = 'circle') => { // Returns a circle shape. - return { x, y, r, t } - } - - this.line = (a, b, t = 'line') => { // Returns a line shape. - return { a, b, t } - } - - this.text = (x, y, g, s, f = 'Arial', t = 'text') => { // Returns a text shape. - return { x, y, g, s, f, t } - } - - this.svg = (d, t = 'svg') => { // Returns a svg shape. - return { d, t } - } - - // Helpers + // Frame this.frame = () => { // Returns a rect of the frame. return ronin.surface.getFrame() @@ -205,6 +227,20 @@ function Library (ronin) { return { x: rect.x, y: rect.y, w: rect.w * w, h: rect.h * h } } + this.resize = async (w = 1, h = 1) => { + const rect = w <= 1 || h <= 1 ? { x: 0, y: 0, w: this.frame().w * w, h: this.frame().h * h } : { x: 0, y: 0, w, h } + const a = document.createElement('img') + const b = document.createElement('img') + a.src = ronin.surface.el.toDataURL() + ronin.surface.resizeImage(a, b) + ronin.surface.resize(rect, true) + return ronin.surface.draw(b, rect) + } + + this.crop = async (rect) => { + return ronin.surface.crop(rect) + } + // Copy/Paste this.clone = (a, b) => { @@ -212,30 +248,6 @@ function Library (ronin) { return [a, b] } - this.stroke = (shape = this.frame(), thickness, color) => { // Strokes a shape. - ronin.surface.stroke(shape, thickness, color) - return shape - } - - this.fill = (rect = this.frame(), color) => { // Fills a shape. - ronin.surface.fill(rect, color) - return rect - } - - this.clear = (rect = this.frame()) => { // Clears a rect. - ronin.surface.clear(rect) - return rect - } - - this.get = (item, key) => { // Gets an object's parameter with name. - return item[key] - } - - this.set = (item, key, val) => { // Sets an object's parameter with name as value. - item[key] = val - return item[key] - } - // TODO: Should remove (of) for (get)? this.of = (h, ...keys) => { @@ -257,12 +269,6 @@ function Library (ronin) { // Pixels - this.draw = async (path, rect) => { - const img = new Image() - img.src = path - return ronin.surface.draw(img, rect) - } - this.pixels = (rect, fn, q) => { const img = ronin.surface.context.getImageData(0, 0, rect.w, rect.h) for (let i = 0, loop = img.data.length; i < loop; i += 4) { @@ -287,23 +293,7 @@ function Library (ronin) { return [pixel.r * q + intercept, pixel.g * q + intercept, pixel.b * q + intercept, pixel.a] } - // - - this.resize = async (w = 1, h = 1) => { - const rect = w <= 1 || h <= 1 ? { x: 0, y: 0, w: this.frame().w * w, h: this.frame().h * h } : { x: 0, y: 0, w, h } - const a = document.createElement('img') - const b = document.createElement('img') - a.src = ronin.surface.el.toDataURL() - ronin.surface.resizeImage(a, b) - ronin.surface.resize(rect, true) - return ronin.surface.draw(b, rect) - } - - this.crop = async (rect) => { - return ronin.surface.crop(rect) - } - - // Generics + // Misc this.echo = (...args) => { ronin.log(args) @@ -314,13 +304,16 @@ function Library (ronin) { return args.reduce((acc, val) => { return acc + val }, '') } - this.test = (name, a, b) => { - if (`${a}` !== `${b}`) { - console.warn('failed ' + name, a, b) - } else { - console.log('passed ' + name, a) - } - return a === b + this.open = async (path) => { // Imports a graphic file and resizes the frame. + return ronin.surface.open(path) + } + + this.folder = (path = ronin.source.path) => { // Returns the content of a folder path. + return fs.existsSync(path) ? fs.readdirSync(path) : [] + } + + this.exit = (force = false) => { // Exits Ronin. + ronin.source.quit(force) } // Client @@ -337,4 +330,13 @@ function Library (ronin) { // javascript interop this.js = window + + this.test = (name, a, b) => { + if (`${a}` !== `${b}`) { + console.warn('failed ' + name, a, b) + } else { + console.log('passed ' + name, a) + } + return a === b + } } From c179fbce7edebd017798dd786471f00b769fa89d Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 09:42:03 +0900 Subject: [PATCH 17/24] Display optionals --- README.md | 42 ++++++++++++++-------------- desktop/sources/scripts/commander.js | 2 +- desktop/sources/scripts/library.js | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index db36152..36453b0 100644 --- a/README.md +++ b/README.md @@ -20,17 +20,17 @@ npm start ## Library - `(import path rect)` Imports a graphic file with format. -- `(export path format quality)` Exports a graphic file with format. -- `(pos x y t)` Returns a position shape. -- `(size w h t)` Returns a size shape. -- `(rect x y w h t)` Returns a rect shape. -- `(circle x y r t)` Returns a circle shape. -- `(line a b t)` Returns a line shape. -- `(text x y g s f t)` Returns a text shape. -- `(svg d t)` Returns a svg shape. -- `(stroke shape)` Strokes a shape. -- `(fill rect)` Fills a shape. -- `(clear rect)` Clears a rect. +- `(export path ~format ~quality)` Exports a graphic file with format. +- `(pos x y ~t)` Returns a position shape. +- `(size w h ~t)` Returns a size shape. +- `(rect x y w h ~t)` Returns a rect shape. +- `(circle x y r ~t)` Returns a circle shape. +- `(line a b ~t)` Returns a line shape. +- `(text x y g s ~f ~t)` Returns a text shape. +- `(svg d ~t)` Returns a svg shape. +- `(stroke ~shape)` Strokes a shape. +- `(fill ~rect)` Fills a shape. +- `(clear ~rect)` Clears a rect. - `(add ...args)` Adds values. - `(sub ...args)` Subtracts values. - `(mul ...args)` Multiplies values. @@ -54,34 +54,34 @@ npm start - `(or a b ...rest)` Returns true if at least one condition is true. - `(map fn arr)` - `(filter fn arr)` -- `(reduce fn arr acc)` +- `(reduce fn arr ~acc)` - `(len item)` Returns the length of a list. - `(first arr)` Returns the first item of a list. - `(last arr)` Returns the last - `(rest [_ ...arr])` -- `(range start end step)` +- `(range start end ~step)` - `(get item key)` Gets an object's parameter with name. - `(set item key val)` Sets an object's parameter with name as value. - `(frame)` Returns a rect of the frame. - `(center)` Returns a position of the center of the frame. - `(scale rect w h)` -- `(resize w h)` +- `(resize ~w ~h)` - `(crop rect)` - `(clone a b)` - `(of h ...keys)` -- `(theme variable el)` -- `(gradient [x1 y1 x2 y2] colors 'black'])` +- `(theme variable ~el)` +- `(gradient [x1 y1 x2 y2] ~colors 'black'])` - `(pixels rect fn q)` -- `(saturation pixel q)` -- `(contrast pixel q)` +- `(saturation pixel ~q)` +- `(contrast pixel ~q)` - `(echo ...args)` - `(str ...args)` - `(open path)` Imports a graphic file and resizes the frame. -- `(folder path)` Returns the content of a folder path. -- `(exit force)` Exits Ronin. +- `(folder ~path)` Returns the content of a folder path. +- `(exit ~force)` Exits Ronin. - `(ronin)` - `(time)` Returns timestamp in milliseconds. -- `(animate play)` Toggles animation. +- `(animate ~play)` Toggles animation. - `(js)` - `(test name a b)` diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index 58e3680..cab77f4 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -178,7 +178,7 @@ function Commander (ronin) { for (const id in payload) { const name = payload[id].substr(0, payload[id].indexOf(' = ')) const parent = payload[id].substr(payload[id].indexOf(' = ')).match(/\(([^)]+)\)/) - const params = parent ? parent[1].split(',').map((word) => { return word.indexOf(' = ') ? word.split(' = ')[0].trim() : word }) : [] + const params = parent ? parent[1].split(',').map((word) => { return word.indexOf(' = ') > -1 ? '~' + (word.split(' = ')[0]).trim() : word.trim() }) : [] const note = payload[id].indexOf('// ') > -1 ? payload[id].split('//')[1].trim() : '' this.dict[name] = { note, params } if (params.length < 1) { console.warn('Docs', 'Missing params for ' + name) } diff --git a/desktop/sources/scripts/library.js b/desktop/sources/scripts/library.js index 2a83d8e..e9b4b03 100644 --- a/desktop/sources/scripts/library.js +++ b/desktop/sources/scripts/library.js @@ -330,7 +330,7 @@ function Library (ronin) { // javascript interop this.js = window - + this.test = (name, a, b) => { if (`${a}` !== `${b}`) { console.warn('failed ' + name, a, b) From 557750c3f8518af2bdec6b5940920544986a2ce1 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 10:31:22 +0900 Subject: [PATCH 18/24] Added indenter, fixes #34 --- desktop/sources/index.html | 1 + desktop/sources/links/main.css | 2 +- desktop/sources/scripts/commander.js | 22 ++++++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/desktop/sources/index.html b/desktop/sources/index.html index 6a57f64..d3a5353 100644 --- a/desktop/sources/index.html +++ b/desktop/sources/index.html @@ -40,6 +40,7 @@ ronin.controller.addRole('default', 'Edit', 'paste') ronin.controller.addRole('default', 'Edit', 'delete') ronin.controller.addRole('default', 'Edit', 'selectall') + ronin.controller.add("default","Edit","Re-Indent",() => { ronin.commander.reindent() },"CmdOrCtrl+Shift+I") ronin.controller.add("default","View","Zoom In",() => { ronin.modZoom(0.25) },"CmdOrCtrl+=") ronin.controller.add("default","View","Zoom Out",() => { ronin.modZoom(-0.25) },"CmdOrCtrl+-") ronin.controller.add("default","View","Zoom Reset",() => { ronin.modZoom(1,true) },"CmdOrCtrl+0") diff --git a/desktop/sources/links/main.css b/desktop/sources/links/main.css index 350ac06..edf46f1 100644 --- a/desktop/sources/links/main.css +++ b/desktop/sources/links/main.css @@ -13,4 +13,4 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_regular #ronin canvas#guide { background:none; } #ronin canvas#surface { border-radius: 2px } -#ronin.hidden canvas#surface, #ronin.hidden canvas#guide { left:0px; } \ No newline at end of file +#ronin.hidden canvas#surface, #ronin.hidden canvas#guide { left:10px; } \ No newline at end of file diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index cab77f4..4f9d441 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -33,6 +33,26 @@ function Commander (ronin) { this.run() } + this.reindent = function () { + let val = this._input.value.replace(/\n/g, '').replace(/\( \(/g, '((').replace(/\) \)/g, '))').replace(/ {2}/g, ' ').trim() + let depth = 0 + for (let i = 0; i < val.length; i++) { + const c = val.charAt(i) + if (c === '(') { depth++ } else if (c === ')') { depth-- } + if (c === ';') { + const indent = '\n' + (' '.repeat(depth)) + val = val.insert(indent, i) + i += indent.length + } + if (c === '(') { + const indent = '\n' + (' '.repeat(depth - 1)) + val = val.insert(indent, i) + i += indent.length + } + } + this._input.value = val.trim() + } + this.setStatus = function (msg) { if (!msg) { return } this._status.textContent = `${(msg + '').substr(0, 40)}` @@ -196,4 +216,6 @@ function Commander (ronin) { }, '') } } + + String.prototype.insert = function (s, i) { return [this.slice(0, i), `${s}`, this.slice(i)].join('') } } From c71cd4a6de844363cc4acd9e303f75939ebd814e Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 10:57:49 +0900 Subject: [PATCH 19/24] Renamed run -> include --- desktop/sources/scripts/commander.js | 2 +- desktop/sources/scripts/lisp.js | 6 +++--- examples/include.lisp | 4 ++++ examples/recursive.lisp | 27 +++++++++++++-------------- examples/run.lisp | 4 ---- 5 files changed, 21 insertions(+), 22 deletions(-) create mode 100644 examples/include.lisp delete mode 100644 examples/run.lisp diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index 4f9d441..cfc6f34 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -34,7 +34,7 @@ function Commander (ronin) { } this.reindent = function () { - let val = this._input.value.replace(/\n/g, '').replace(/\( \(/g, '((').replace(/\) \)/g, '))').replace(/ {2}/g, ' ').trim() + let val = this._input.value.replace(/\n/g, '').replace(/ +(?= )/g, '').replace(/\( \(/g, '((').replace(/\) \)/g, '))').trim() let depth = 0 for (let i = 0; i < val.length; i++) { const c = val.charAt(i) diff --git a/desktop/sources/scripts/lisp.js b/desktop/sources/scripts/lisp.js index fe9b520..ed2a26a 100644 --- a/desktop/sources/scripts/lisp.js +++ b/desktop/sources/scripts/lisp.js @@ -20,9 +20,9 @@ function Lisp (input, lib) { const special = { include: (input, context) => { - const p = input[1].value - if (!fs.existsSync(p)) { console.warn('Source', p); return [] } - const file = fs.readFileSync(p, { encoding: 'utf-8' }) + if (!input[1].value || !fs.existsSync(input[1].value)) { console.warn('Source', input[1].value); return [] } + const file = fs.readFileSync(input[1].value, { encoding: 'utf-8' }) + console.log(input, context) return interpret(this.parse(file), context) }, let: function (input, context) { diff --git a/examples/include.lisp b/examples/include.lisp new file mode 100644 index 0000000..bb1fdb9 --- /dev/null +++ b/examples/include.lisp @@ -0,0 +1,4 @@ +; include +( + (include "../examples/recursive.lisp") + (echo line-color)) \ No newline at end of file diff --git a/examples/recursive.lisp b/examples/recursive.lisp index 7c4cd6c..fb7003f 100644 --- a/examples/recursive.lisp +++ b/examples/recursive.lisp @@ -1,17 +1,16 @@ ; recursive - ( - (clear) - (def line-color "red") + (clear) (defn rec - (v) - (if (gt v 0) - ((stroke (circle - (mul 5 v) - (mul 5 v) - (mul 5 v)) 1 line-color) - (rec (sub v 5)))) - ) - - (rec 100) -) \ No newline at end of file + (v) + (if + (gt v 0) + ( + (stroke + (circle + (mul 5 v) + (mul 5 v) + (mul 5 v)) 1 "red") + (rec + (sub v 5))))) + (rec 100)) \ No newline at end of file diff --git a/examples/run.lisp b/examples/run.lisp deleted file mode 100644 index 1877cf0..0000000 --- a/examples/run.lisp +++ /dev/null @@ -1,4 +0,0 @@ -( - (include "../examples/recursive.lisp") - (echo line-color) -) \ No newline at end of file From c1594dd4cc4c07985ff509d90e0d12d1f3f7f8bd Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 11:10:23 +0900 Subject: [PATCH 20/24] Updated some examples --- desktop/sources/scripts/lisp.js | 1 - examples/glitch.lisp | 2 +- examples/guides.lisp | 71 +++++++++++++++++++++------------ examples/pixels.lisp | 13 ++---- examples/random.lisp | 26 +++++------- examples/svg.lisp | 13 +++--- 6 files changed, 70 insertions(+), 56 deletions(-) diff --git a/desktop/sources/scripts/lisp.js b/desktop/sources/scripts/lisp.js index ed2a26a..3a38a83 100644 --- a/desktop/sources/scripts/lisp.js +++ b/desktop/sources/scripts/lisp.js @@ -22,7 +22,6 @@ function Lisp (input, lib) { include: (input, context) => { if (!input[1].value || !fs.existsSync(input[1].value)) { console.warn('Source', input[1].value); return [] } const file = fs.readFileSync(input[1].value, { encoding: 'utf-8' }) - console.log(input, context) return interpret(this.parse(file), context) }, let: function (input, context) { diff --git a/examples/glitch.lisp b/examples/glitch.lisp index f84b501..b5f723e 100644 --- a/examples/glitch.lisp +++ b/examples/glitch.lisp @@ -17,7 +17,7 @@ ; Draw photo - (draw + (import "../static/crystal.jpg" (rect 0 0 400 400)) diff --git a/examples/guides.lisp b/examples/guides.lisp index c6bff1a..f956c75 100644 --- a/examples/guides.lisp +++ b/examples/guides.lisp @@ -1,36 +1,57 @@ -; guides file - -((clear) - (stroke (frame) 1 "red") - +; guides +( + (clear) + (stroke + (frame) 1 "red") (stroke (line (pos 0 0) - (pos (of (frame) "w") (of (frame) "h"))) - 1 "red") - - + (pos + (of + (frame) "w") + (of + (frame) "h"))) 1 "red") (stroke (line - (pos (of (frame) "w") 0) - (pos 0 (of (frame) "h"))) - 1 "red") - + (pos + (of + (frame) "w") 0) + (pos 0 + (of + (frame) "h"))) 1 "red") (stroke (line - (pos (div (of (frame) "w") 2) 0) - (pos (div (of (frame) "w") 2) (of (frame) "h"))) - 1 "red") - + (pos + (div + (of + (frame) "w") 2) 0) + (pos + (div + (of + (frame) "w") 2) + (of + (frame) "h"))) 1 "red") (stroke (line - (pos 0 (div (of (frame) "h") 2)) - (pos (div (of (frame) "w") 2) (of (frame) "h"))) - 1 "#72dec2") - + (pos 0 + (div + (of + (frame) "h") 2)) + (pos + (div + (of + (frame) "w") 2) + (of + (frame) "h"))) 1 "#72dec2") (stroke (line - (pos (div (of (frame) "w") 2) 0) - (pos (of (frame) "w") (div (of (frame) "h") 2))) - 1 "#72dec2") -) \ No newline at end of file + (pos + (div + (of + (frame) "w") 2) 0) + (pos + (of + (frame) "w") + (div + (of + (frame) "h") 2))) 1 "#72dec2")) \ No newline at end of file diff --git a/examples/pixels.lisp b/examples/pixels.lisp index d45baa9..d4edbff 100644 --- a/examples/pixels.lisp +++ b/examples/pixels.lisp @@ -1,12 +1,7 @@ ; pixels - ( - (clear) - (draw - "../../PREVIEW.jpg" - (frame)) + (clear) + (import "../../PREVIEW.jpg" + (frame)) (pixels - (rect 0 0 500 500) - saturation - 0.5) -) \ No newline at end of file + (rect 0 0 500 500) saturation 0.5)) \ No newline at end of file diff --git a/examples/random.lisp b/examples/random.lisp index 0753a05..ff3754c 100644 --- a/examples/random.lisp +++ b/examples/random.lisp @@ -1,21 +1,17 @@ ; random - ( - (clear) - - (defn place - (rec) - (if (gt rec 0) + (clear) + (defn place + (rec) + (if + (gt rec 0) ( - (draw "../static/crystal.jpg" + (import "../static/crystal.jpg" (rect - (random 200) (random 200) (random 200) - (random 200))) - (place (sub rec 1)) - )) - ) - - (place 30) -) \ No newline at end of file + (random 200) + (random 200))) + (place + (sub rec 1))))) + (place 30)) \ No newline at end of file diff --git a/examples/svg.lisp b/examples/svg.lisp index 2a81943..497871b 100644 --- a/examples/svg.lisp +++ b/examples/svg.lisp @@ -1,5 +1,8 @@ -((fill - (svg "M255,60 L255,60 L135,180 L75,60 L195,210 L120,225 L105,225 L165,255 L225,195 L255,135 L285,150") "white") - -(stroke - (svg "M405,15 L405,15 L150,150 L195,90 L240,135 L120,195 L75,90 L135,165 L120,225 L90,240 L60,210 L90,150 L255,180 L285,180 L285,165 ") "pink")) \ No newline at end of file +( + (clear) + ; ronin path + (stroke + (svg "M60,60 L195,60 A45,45 0 0,1 240,105 A45,45 0 0,1 195,150 L60,150 M195,150 A45,45 0 0,1 240,195 L240,240 ") 2 "white") + ; outline + (stroke + (svg "M15,15 L15,15 L285,15 L285,285 L15,285 Z") 1 "#555")) \ No newline at end of file From 998a2db53e55fdb0517479330c5c011a75881557 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 11:15:18 +0900 Subject: [PATCH 21/24] Quieted message --- desktop/sources/scripts/commander.js | 3 ++- desktop/sources/scripts/ronin.js | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index cfc6f34..b855cc3 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -54,8 +54,9 @@ function Commander (ronin) { } this.setStatus = function (msg) { - if (!msg) { return } + if (!msg || msg === this._status.textContent) { return } this._status.textContent = `${(msg + '').substr(0, 40)}` + console.log(...msg) } this.update = function () { diff --git a/desktop/sources/scripts/ronin.js b/desktop/sources/scripts/ronin.js index 0883f22..ea59299 100644 --- a/desktop/sources/scripts/ronin.js +++ b/desktop/sources/scripts/ronin.js @@ -52,7 +52,6 @@ function Ronin () { } this.log = function (...msg) { - console.log(...msg) this.commander.setStatus(msg.reduce((acc, val) => { return acc + val + ' ' }, '')) } From ef68e52438c74dd40a09f3797460e2e1a80759ef Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 11:37:51 +0900 Subject: [PATCH 22/24] Begin implementing onscreen docs. --- desktop/sources/links/main.css | 4 +- desktop/sources/scripts/commander.js | 30 +++++++----- desktop/sources/scripts/source.js | 5 +- examples/resize.lisp | 8 ++-- examples/theme.lisp | 68 ++++++++++++++++------------ 5 files changed, 66 insertions(+), 49 deletions(-) diff --git a/desktop/sources/links/main.css b/desktop/sources/links/main.css index edf46f1..f2d5491 100644 --- a/desktop/sources/links/main.css +++ b/desktop/sources/links/main.css @@ -5,8 +5,8 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_regular #ronin { height: calc(100vh - 60px); width:calc(100vw - 60px); -webkit-app-region: drag; padding: 30px;overflow: hidden; } #ronin #wrapper { overflow: hidden; position: relative; } #ronin #wrapper #commander { z-index: 9000;position: relative;width: 310px;height: calc(100vh - 60px);-webkit-app-region: no-drag;padding-right: 30px;transition: margin-left 250ms;} -#ronin #wrapper #commander textarea { background: none; width: 100%; height: calc(100vh - 80px); resize: none; font-size: 12px;line-height: 15px; padding-right: 15px} -#ronin #wrapper #commander div#status { position: absolute; bottom: 0px; } +#ronin #wrapper #commander textarea { background: none; width: 100%; height: calc(100vh - 90px); resize: none; font-size: 12px;line-height: 15px; padding-right: 15px} +#ronin #wrapper #commander div#status { position: absolute; bottom: 0px; text-transform: lowercase;} #ronin.hidden #wrapper #commander { margin-left:-331px; } #ronin canvas#surface,#ronin canvas#guide { position: absolute; top:0px; -webkit-user-select: none;-webkit-app-region: no-drag; background-image: url("data:image/svg+xml;utf8,"); background-size: 10px 10px; background-position: -4px -4px; width:100%; height:100%; left:340px; transition: left 250ms} diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index b855cc3..e645a9a 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -4,18 +4,28 @@ function Commander (ronin) { this._input = document.createElement('textarea') this._status = document.createElement('div') this._status.id = 'status' + this._log = document.createElement('div') + this._log.id = 'log' + this._source = document.createElement('div') + this._source.id = 'source' + this._help = document.createElement('div') + this._help.id = 'help' this.isVisible = true this.install = function (host) { this.el.appendChild(this._input) + this._status.appendChild(this._log) + this._status.appendChild(this._source) + this._status.appendChild(this._help) this.el.appendChild(this._status) host.appendChild(this.el) this._input.addEventListener('input', this.onInput) + this._input.addEventListener('click', this.onClick) this.docs.install() } this.start = function () { - this._status.textContent = 'Idle. (zoom 100%)' + this.setStatus('Ready.') this._input.focus() this.run() this.hide() @@ -54,21 +64,22 @@ function Commander (ronin) { } this.setStatus = function (msg) { - if (!msg || msg === this._status.textContent) { return } - this._status.textContent = `${(msg + '').substr(0, 40)}` - console.log(...msg) + if (!msg || msg === this._log.textContent) { return } + this._log.textContent = `${msg}` + this._source.textContent = `${ronin.source} ${this._input.value.split('\n').length} lines` + console.log(msg) } this.update = function () { } - this.onInput = function () { - + this.onInput = () => { + console.log('input', this._input.selectionStart) } - this.getQuery = function () { - + this.onClick = () => { + console.log('click', this._input.selectionStart) } // Mouse @@ -83,7 +94,6 @@ function Commander (ronin) { this.mouseRect.a.x = e.offsetX this.mouseRect.a.y = e.offsetY this.mouseRect.t = 'pos' - this._status.textContent = `${this.mouseRect.x},${this.mouseRect.y} ${this.mouseRect.w},${this.mouseRect.h}` this.capture() this.show() } @@ -94,7 +104,6 @@ function Commander (ronin) { this.mouseRect.h = e.offsetY - this.mouseRect.y this.mouseRect.b.x = e.offsetX this.mouseRect.b.y = e.offsetY - this._status.textContent = `${this.mouseRect.x},${this.mouseRect.y} ${this.mouseRect.w},${this.mouseRect.h}` this.commit() } } @@ -106,7 +115,6 @@ function Commander (ronin) { this.mouseRect.b.x = e.offsetX this.mouseRect.b.y = e.offsetY this.mouseRect.t = '' - this._status.textContent = `${this.mouseRect.x},${this.mouseRect.y} ${this.mouseRect.w},${this.mouseRect.h}` this.commit() this._input.focus() ronin.surface.clearGuide() diff --git a/desktop/sources/scripts/source.js b/desktop/sources/scripts/source.js index 71bb8eb..c6bfd72 100644 --- a/desktop/sources/scripts/source.js +++ b/desktop/sources/scripts/source.js @@ -15,6 +15,7 @@ function Source (ronin) { console.log('Source', 'Make a new file..') this.path = null ronin.surface.clear() + ronin.log(`New file.`) } this.open = function () { @@ -57,6 +58,7 @@ function Source (ronin) { if (quitAfter === true) { app.exit() } + ronin.log(`Writing file.`) } this.read = function (loc = this.path) { @@ -65,6 +67,7 @@ function Source (ronin) { console.log('Source', 'Reading ' + loc) this.path = loc this.load(fs.readFileSync(this.path, 'utf8')) + ronin.log(`Reading file.`) } this.run = function () { @@ -144,7 +147,7 @@ function Source (ronin) { } this.toString = function () { - return this.path ? this.name() : 'unsaved' + return this.path ? this.name() + '.lisp' : 'unsaved' } function isDifferent (a, b) { diff --git a/examples/resize.lisp b/examples/resize.lisp index 620a36c..5dbd409 100644 --- a/examples/resize.lisp +++ b/examples/resize.lisp @@ -1,7 +1,5 @@ ; resize - ( - (clear) - (open "../../PREVIEW.jpg") - (resize 0.5 0.5) -) \ No newline at end of file + (clear) + (open "../../PREVIEW.jpg") + (resize 0.5 0.5)) \ No newline at end of file diff --git a/examples/theme.lisp b/examples/theme.lisp index 498e19f..9c50830 100644 --- a/examples/theme.lisp +++ b/examples/theme.lisp @@ -1,30 +1,38 @@ -((clear) - (def col - (lambda - (i) - (of - ((theme "f_high") - (theme "f_med") - (theme "f_low") - (theme "f_inv") - (theme "b_high") - (theme "b_med") - (theme "b_low") - (theme "b_inv")) - (mod i 8)))) - (def rec - (lambda - (v i) - (if (gt v 0) - ((fill - (circle - (add - (div (of (frame) "w") 1.6) - (mul 1.5 v)) - (mul 10 v) - (mul v (div v 5))) - (col i)) - (rec - (sub v 3) - (add i 1)))))) - (rec 40 0)) \ No newline at end of file +; theme +( + (clear) + (def col + (lambda + (i) + (of + ( + (theme "f_high") + (theme "f_med") + (theme "f_low") + (theme "f_inv") + (theme "b_high") + (theme "b_med") + (theme "b_low") + (theme "b_inv")) + (mod i 8)))) + (def rec + (lambda + (v i) + (if + (gt v 0) + ( + (fill + (circle + (add + (div + (of + (frame) "w") 1.6) + (mul 1.5 v)) + (mul 10 v) + (mul v + (div v 5))) + (col i)) + (rec + (sub v 3) + (add i 1)))))) + (rec 40 0)) \ No newline at end of file From 1d9f530b479b543ca3dad15e060d55ccdd536d8c Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 12:01:40 +0900 Subject: [PATCH 23/24] Added on-screen docs --- desktop/sources/links/main.css | 2 +- desktop/sources/scripts/commander.js | 37 +++++++++++++++++++++------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/desktop/sources/links/main.css b/desktop/sources/links/main.css index f2d5491..8abe5c2 100644 --- a/desktop/sources/links/main.css +++ b/desktop/sources/links/main.css @@ -5,7 +5,7 @@ body { margin:0px; padding:0px; overflow:hidden; font-family:"input_mono_regular #ronin { height: calc(100vh - 60px); width:calc(100vw - 60px); -webkit-app-region: drag; padding: 30px;overflow: hidden; } #ronin #wrapper { overflow: hidden; position: relative; } #ronin #wrapper #commander { z-index: 9000;position: relative;width: 310px;height: calc(100vh - 60px);-webkit-app-region: no-drag;padding-right: 30px;transition: margin-left 250ms;} -#ronin #wrapper #commander textarea { background: none; width: 100%; height: calc(100vh - 90px); resize: none; font-size: 12px;line-height: 15px; padding-right: 15px} +#ronin #wrapper #commander textarea { background: none; width: 100%; height: calc(100vh - 105px); resize: none; font-size: 12px;line-height: 15px; padding-right: 15px} #ronin #wrapper #commander div#status { position: absolute; bottom: 0px; text-transform: lowercase;} #ronin.hidden #wrapper #commander { margin-left:-331px; } diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index e645a9a..720de5b 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -8,15 +8,15 @@ function Commander (ronin) { this._log.id = 'log' this._source = document.createElement('div') this._source.id = 'source' - this._help = document.createElement('div') - this._help.id = 'help' + this._docs = document.createElement('div') + this._docs.id = 'help' this.isVisible = true this.install = function (host) { this.el.appendChild(this._input) this._status.appendChild(this._log) this._status.appendChild(this._source) - this._status.appendChild(this._help) + this._status.appendChild(this._docs) this.el.appendChild(this._status) host.appendChild(this.el) this._input.addEventListener('input', this.onInput) @@ -64,10 +64,21 @@ function Commander (ronin) { } this.setStatus = function (msg) { - if (!msg || msg === this._log.textContent) { return } - this._log.textContent = `${msg}` - this._source.textContent = `${ronin.source} ${this._input.value.split('\n').length} lines` - console.log(msg) + // Logs + if (msg && msg !== this._log.textContent) { + this._log.textContent = `${msg}` + console.log(msg) + } + // Source + const _source = `${ronin.source} ${this._input.value.split('\n').length} lines` + if (_source !== this._source.textContent) { + this._source.textContent = _source + } + // Docs + const _docs = this.docs.print(this.getLastfn()) + if (_docs !== this._docs.textContent) { + this._docs.textContent = `${_docs}` + } } this.update = function () { @@ -75,11 +86,16 @@ function Commander (ronin) { } this.onInput = () => { - console.log('input', this._input.selectionStart) + this.setStatus() } this.onClick = () => { - console.log('click', this._input.selectionStart) + this.setStatus() + } + + this.getLastfn = function () { + const pos = this._input.value.substr(0, this._input.selectionStart).lastIndexOf('(') + return this._input.value.substr(pos).split(' ')[0].replace(/\(/g, '').replace(/\)/g, '').trim() } // Mouse @@ -223,6 +239,9 @@ function Commander (ronin) { }, '').trim()}` return `${acc}- \`(${example.trim()})\` ${this.dict[item].note}\n` }, '') + }, + print: function (name) { + return this.dict[name] ? `(${name} ${this.dict[name].params.reduce((acc, item) => { return `${acc}${item} ` }, '').trim()})` : '' } } From b7ba8282a713743883bb9f21f83bd78d8b5a76b8 Mon Sep 17 00:00:00 2001 From: Devine Lu Linvega Date: Thu, 18 Jul 2019 12:05:11 +0900 Subject: [PATCH 24/24] Fixed docs path for build. --- desktop/sources/scripts/commander.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/desktop/sources/scripts/commander.js b/desktop/sources/scripts/commander.js index 720de5b..b7aae9b 100644 --- a/desktop/sources/scripts/commander.js +++ b/desktop/sources/scripts/commander.js @@ -212,11 +212,12 @@ function Commander (ronin) { this.docs = { dict: {}, - path: 'sources/scripts/library.js', load: function () { const fs = require('fs') - if (!fs.existsSync(this.path)) { console.warn('Docs', 'File does not exist: ' + this.path); return } - const lines = fs.readFileSync(this.path, 'utf8').split('\n').filter((line) => { return line.substr(0, 7) === ' this.' }) + const path = require('path') + const p = path.join(__dirname, 'scripts/', 'library.js') + if (!fs.existsSync(p)) { console.warn('Docs', 'File does not exist: ' + p); return } + const lines = fs.readFileSync(p, 'utf8').split('\n').filter((line) => { return line.substr(0, 7) === ' this.' }) return lines.map((line) => { return line.trim().substr(5).trim() }) }, install: function (payload = this.load()) {