aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2018-10-30 02:41:14 +0000
committers-ol <s-ol@users.noreply.github.com>2018-10-30 02:41:14 +0000
commit3b02770e7f9ec14487493c68ff12ec42e0f2755b (patch)
tree45c8d7d8ef4c813634321f280146e8ddad9c333e /lib
parentupdate interp docs (diff)
downloadmmm-3b02770e7f9ec14487493c68ff12ec42e0f2755b.tar.gz
mmm-3b02770e7f9ec14487493c68ff12ec42e0f2755b.zip
reorganize lib
Diffstat (limited to 'lib')
-rw-r--r--lib/color.moon (renamed from lib/color.shared.moon)0
-rw-r--r--lib/init.client.moon2
-rw-r--r--lib/mmmfs/browser.moon99
-rw-r--r--lib/mmmfs/conversion.moon118
-rw-r--r--lib/mmmfs/init.moon98
-rw-r--r--lib/ordered.moon (renamed from lib/ordered.shared.moon)0
6 files changed, 316 insertions, 1 deletions
diff --git a/lib/color.shared.moon b/lib/color.moon
index 6233b47..6233b47 100644
--- a/lib/color.shared.moon
+++ b/lib/color.moon
diff --git a/lib/init.client.moon b/lib/init.client.moon
index d39143d..0fbaaf7 100644
--- a/lib/init.client.moon
+++ b/lib/init.client.moon
@@ -25,7 +25,7 @@ warn = (...) ->
contents = [deep_tostring v for v in *{ ... } ]
console\warn table.unpack contents
-package.path = '/?.shared.moon.lua;/?.client.moon.lua;/?.moon.lua;/?/init.moon.lua;/?.lua;/?/init.lua'
+package.path = '/?.client.moon.lua;/?.moon.lua;/?/init.moon.lua;/?.lua;/?/init.lua'
-- relative imports
relative = do
diff --git a/lib/mmmfs/browser.moon b/lib/mmmfs/browser.moon
new file mode 100644
index 0000000..427d952
--- /dev/null
+++ b/lib/mmmfs/browser.moon
@@ -0,0 +1,99 @@
+import ReactiveVar, text, elements from require 'lib.component'
+import div, span, a, select, option from elements
+
+limit = (list, num) -> [v for i,v in ipairs list when i <= num]
+
+class Browser
+ new: (@root) =>
+ @path = ReactiveVar {}
+ @path\subscribe (path) -> window.location.hash = '/' .. table.concat path, '/'
+ @prop = ReactiveVar (@root\find 'mmm/dom') or next @root.props
+ @active = @path\map (path) ->
+ fileder = @root
+ for name in *path
+ local next
+ for child in *fileder.children
+ if name == child\get 'name', 'alpha'
+ next = child
+ break
+
+ if not next
+ return
+
+ fileder = next
+
+ fileder
+
+ @active\subscribe (fileder) -> @prop\set (fileder\find 'mmm/dom') or next fileder.props
+
+ @tree = div {
+ style: {
+ position: 'absolute',
+ top: 0,
+ bottom: 0,
+ left: 0,
+ right: 0,
+ display: 'flex',
+ overflow: 'hidden',
+ 'flex-direction': 'column',
+ 'justify-content': 'space-between',
+ },
+ div {
+ style: {
+ padding: '1em',
+ flex: '0 0 auto',
+ display: 'flex',
+ 'justify-content': 'space-between',
+ background: '#eeeeee',
+ },
+ span 'path: ', @path\map (path) -> with div style: { display: 'inline-block' }
+ \append a 'root', href: '#', onclick: (_, e) ->
+ e\preventDefault!
+ @navigate {}
+
+ for i,name in ipairs path
+ \append '/'
+ \append a name, href: '#', onclick: (_, e) ->
+ e\preventDefault!
+ @navigate limit path, i
+
+ span 'view property: ', @active\map (fileder) ->
+ onchange = (_, e) ->
+ @prop\set Key e.target.value
+
+ with select :onchange
+ if fileder
+ for key, _ in pairs fileder.props
+ value = key\tostring!
+ \append option value, :value
+ }
+
+ div {
+ style: {
+ flex: '1 0 0',
+ overflow: 'auto',
+ padding: '1em 2em',
+ },
+ @prop\map (prop) ->
+ active = @active\get!
+
+ ok, res = pcall ->
+ -- val, key = active\get prop.name, prop.type
+ -- CONVERT 'mmm/dom', val, key
+ active\get prop.name, 'mmm/dom'
+
+ if ok and res
+ res
+ else
+ warn "error: ", res unless ok
+ span "cannot display!", style: { color: '#f00' }
+ }
+ }
+
+ @node = @tree.node
+
+ navigate: (new) => @path\set new
+
+{
+ :Browser,
+}
diff --git a/lib/mmmfs/conversion.moon b/lib/mmmfs/conversion.moon
new file mode 100644
index 0000000..7f86aa4
--- /dev/null
+++ b/lib/mmmfs/conversion.moon
@@ -0,0 +1,118 @@
+import text, code from require 'lib.dom'
+import tohtml from require 'lib.component'
+
+-- limit function to one argument
+single = (func) -> (val) -> func val
+
+-- list of converts
+-- converts each have
+-- * inp - input type. can capture subtypes using `(.+)`
+-- * out - output type. can substitute subtypes from inp with %1, %2 etc.
+-- * transform - function (val: inp, fileder) -> val: out
+converts = {
+ {
+ inp: 'moon -> (.+)',
+ out: '%1',
+ transform: (val, fileder) -> val fileder
+ },
+ {
+ inp: 'text/plain',
+ out: 'mmm/dom',
+ transform: single text
+ },
+ {
+ inp: 'alpha',
+ out: 'mmm/dom',
+ transform: single code
+ },
+ {
+ inp: 'URL -> .*',
+ out: 'mmm/dom',
+ transform: single code
+ },
+ {
+ inp: 'mmm/component',
+ out: 'mmm/dom',
+ transform: single tohtml
+ },
+ {
+ inp: 'mmm/dom',
+ out: 'text/html',
+ transform: (node) -> if MODE == 'SERVER' then node else node.outerHTML
+ },
+ {
+ inp: 'text/html',
+ out: 'mmm/dom',
+ transform: if MODE == 'SERVER'
+ (...) -> ...
+ else
+ (html) ->
+ tmp = document\createElement 'div'
+ tmp.innerHTML = html
+ if tmp.childElementCount == 1
+ tmp.firstChild
+ else
+ tmp
+ }
+}
+
+do
+ local markdown
+ if MODE == 'SERVER'
+ success, discount = pcall require, 'discount'
+ markdown = discount if success
+ else
+ markdown = window and window.marked and window\marked
+
+ if markdown
+ table.insert converts, {
+ inp: 'text/markdown',
+ out: 'text/html',
+ transform: single markdown
+ }
+
+count = (base, pattern='->') -> select 2, base\gsub pattern, ''
+escape_inp = (inp) -> "^#{inp\gsub '([-/])', '%%%1'}$"
+
+-- attempt to find a conversion path from 'have' to 'want'
+-- * have - start type string or list of type strings
+-- * want - stop type string
+-- * limit - limit conversion amount
+-- returns a list of conversion steps
+get_conversions = (want, have, limit=3) ->
+ assert have, 'need starting type(s)'
+
+ if 'string' == type have
+ have = { have }
+
+ assert #have > 0, 'need starting type(s) (list was empty)'
+
+ iterations = limit + math.max table.unpack [count type for type in *have]
+ have = [{ :start, rest: start, conversions: {} } for start in *have]
+
+ for i=1, iterations
+ next_have, c = {}, 1
+ for { :start, :rest, :conversions } in *have
+ if want == rest
+ return conversions, start
+ else
+ for convert in *converts
+ inp = escape_inp convert.inp
+ matches = { rest\match inp }
+ continue unless #matches > 0
+ result = rest\gsub inp, convert.out
+ if result
+ next_have[c] = {
+ :start,
+ rest: result,
+ conversions: { convert, table.unpack conversions }
+ }
+ c += 1
+
+ have = next_have
+ return unless #have > 0
+
+{
+ :converts
+ :get_conversions
+}
diff --git a/lib/mmmfs/init.moon b/lib/mmmfs/init.moon
new file mode 100644
index 0000000..2393c75
--- /dev/null
+++ b/lib/mmmfs/init.moon
@@ -0,0 +1,98 @@
+require = relative ...
+import get_conversions from require '.conversion'
+
+-- Key of a Fileder Property
+-- contains:
+-- * @name - key name or '' for main content
+-- * @type - type string (type -> type -> type)
+class Key
+ -- instantiate from table w/ keys described above
+ -- or string like '@name: @type' (name optional)
+ new: (opts, second) =>
+ if 'string' == type second
+ @name, @type = (opts or ''), second
+ elseif 'string' == type opts
+ @name, @type = opts\match '(%w+): *(.+)'
+ if not @name
+ @name = ''
+ @type = opts
+ elseif 'table' == type opts
+ @name = opts.name
+ @type = opts.type
+ else
+ error "wrong argument type: #{type opts}, #{type second}"
+
+ -- format as a string (see constructor)
+ tostring: =>
+ if @name == ''
+ @type
+ else
+ "#{@name}: #{@type}"
+
+-- Fileder itself
+-- contains:
+-- * @props - Property Map (Key to Value)
+-- * @children - Children Array
+class Fileder
+ -- instantiate from props and children tables
+ -- or mix in one table (numeric keys are children, remainder props)
+ -- prop-keys are passed to Key constructor
+ new: (props, @children) =>
+ if not @children
+ @children = for i, child in ipairs props
+ props[i] = nil
+ child
+
+ @props = { (Key k), v for k, v in pairs props }
+
+ -- find property key according to criteria, nil if no value or conversion path
+ -- * name - property name (optional: defaults to main content)
+ -- * type - wanted result type
+ find: (...) =>
+ want = Key ...
+
+ -- filter props by name
+ matching = [ key for key in pairs @props when key.name == want.name ]
+ return unless #matching > 0
+
+ -- get shortest conversion path
+ shortest_path, start = get_conversions want.type, [ key.type for key in *matching ]
+
+ if start
+ for key in *matching
+ if key.type == start
+ return key, shortest_path
+
+ error "couldn't find key after resolution?"
+
+ -- get property according to criteria, nil if no value or conversion path
+ -- * name - property name (optional: defaults to main content)
+ -- * type - wanted result type
+ get: (...) =>
+ want = Key ...
+
+ -- find matching key and shortest conversion path
+ key, conversions = @find want
+
+ if key
+ value = @props[key]
+
+ -- apply conversions (in reverse order)
+ for i=#conversions,1,-1
+ { :inp, :out, :transform } = conversions[i]
+ value = transform value, @
+
+ value, key
+
+ -- like @get, throw if no value or conversion path
+ gett: (...) =>
+ want = Key ...
+
+ value, key = @get want
+ assert value, "node doesn't have value for #{want\tostring!}"
+ value, key
+
+{
+ :Key
+ :Fileder
+}
diff --git a/lib/ordered.shared.moon b/lib/ordered.moon
index 59c07bf..59c07bf 100644
--- a/lib/ordered.shared.moon
+++ b/lib/ordered.moon