aboutsummaryrefslogtreecommitdiffstats
path: root/app/mmmfs/init.moon
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2018-10-29 08:35:53 +0000
committers-ol <s-ol@users.noreply.github.com>2018-10-29 08:35:53 +0000
commit27d1cf641ce3bbfe96e6fe18f24dd46f95efbe5e (patch)
treeac703b9f84c1c8e4666d039a880a2af91c450c4a /app/mmmfs/init.moon
parentmove duct_tape to lib (diff)
downloadmmm-27d1cf641ce3bbfe96e6fe18f24dd46f95efbe5e.tar.gz
mmm-27d1cf641ce3bbfe96e6fe18f24dd46f95efbe5e.zip
better conversion inverence for mmmfs
Diffstat (limited to 'app/mmmfs/init.moon')
-rw-r--r--app/mmmfs/init.moon221
1 files changed, 50 insertions, 171 deletions
diff --git a/app/mmmfs/init.moon b/app/mmmfs/init.moon
index 1f2d2f6..19cb028 100644
--- a/app/mmmfs/init.moon
+++ b/app/mmmfs/init.moon
@@ -1,143 +1,35 @@
-export ^
-
--- list of interps
--- interp signature is (fileder, value) -> value
-interps = {
- moon: (method) => method @
-}
-
-split = (str, delim='->') ->
- return {}, str if nil == str\find delim
+require = relative ...
+import get_conversions from require '.conversion'
- -- @TODO interp chain?
- interp, rest = str\match ' *(%w+) *-> *(.*)'
- { interp }, rest
+export ^
-- Key of a Fileder Property
-- contains:
-- * @name - key name or '' for main content
--- * @type - final type after interps
--- * @interps - array describing interp chain
+-- * @type - type string (type -> type -> type)
class Key
-- instantiate from table w/ keys described above
-- or string like 'name: interp -> interp -> type' (name + interps optional)
- new: (opts) =>
- if 'string' == type opts
- @name, rest = opts\match '(%w+): *(.+)'
+ 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 = ''
- rest = opts
- @interps, @type = split rest, '->'
+ @type = opts
elseif 'table' == type opts
@name = opts.name
- @type = assert opts.type, 'no type given'
- @interps = opts.interps or {}
+ @type = opts.type
else
- error 'wrong argument type'
-
- -- get a function that interpretes a raw value according to @interps
- -- and returns a value of @type
- -- overrides is a map of interp overrides
- get_interp: (overrides={}) =>
- return ((val) => val) if #@interps == 0
-
- assert #@interps == 1, 'not supported rn' -- @TODO
- _name = @interps[1]
-
- return overrides[_name] if overrides and overrides[_name]
-
- assert overrides[_name] or interps[_name], "interp not found: '#{_name}'"
+ error "wrong argument type: #{type opts}, #{type second}"
-- format as a string (see constructor)
tostring: =>
- list = { table.unpack @interps }
- table.insert list, @type
-
- type = table.concat list, ' -> '
-
if @name == ''
- type
+ @type
else
- "#{@name}: #{type}"
-
-
-import text, code from require 'lib.html'
-import tohtml from require 'lib.component'
-
--- list of converts
--- converts each have
--- * inp - input type
--- * out - output type
--- * transform - function (inp) -> out
-converts = {
- {
- inp: 'text/plain',
- out: 'mmm/dom',
- transform: text
- },
- {
- inp: 'alpha',
- out: 'mmm/dom',
- transform: code
- },
- {
- inp: 'mmm/dom',
- out: 'text/html',
- transform: (node) -> if MODE == 'SERVER' then node else node.outerHTML
- },
- {
- inp: 'mmm/component',
- out: 'mmm/dom',
- transform: tohtml
- },
- {
- -- @TODO this chained rule *should* be inferred, but that's way too hot rn
- inp: 'mmm/component',
- out: 'text/html',
- transform: (node) ->
- node = tohtml node
- if MODE == 'SERVER' then node else node.outerHTML
- },
-}
-
-table.insert converts, {
- inp: 'text/html',
- out: 'mmm/dom',
- transform: if MODE == 'SERVER'
- (...) -> ...
- else
- (html) ->
- tmp = document\createElement 'div'
- tmp.innerHTML = html
- tmp.firstChild
- }
-
-do
- local markdown
- if MODE == 'SERVER'
- success, discount = pcall require, 'discount'
- markdown = discount if success
- else
- markdown = window and window\marked
-
- if markdown
- table.insert converts, {
- inp: 'text/markdown',
- out: 'text/html',
- transform: markdown,
- }
-
- -- @TODO chained w above
- table.insert converts, {
- inp: 'text/markdown',
- out: 'mmm/dom',
- transform: if MODE == 'SERVER'
- (md) -> markdown md
- else
- (md) ->
- with document\createElement 'div'
- .innerHTML = markdown md
- }
+ "#{@name}: #{@type}"
-- Fileder itself
-- contains:
@@ -158,69 +50,56 @@ class Fileder
-- 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
- -- * convert - allow conversion (optional: default true)
- find: (name='', type, convert=true) =>
- if not type
- type = name
- name = ''
+ find: (...) =>
+ want = Key ...
- -- first pass, interps only
- for key, value in pairs @props
- continue unless key.name == name and key.type == type
+ -- filter props by name
+ matching = [ key for key in pairs @props when key.name == want.name ]
+ return unless #matching > 0
- return key
+ -- get shortest conversion path
+ shortest_path, start = get_conversions want.type, [ key.type for key in *matching ]
- if convert
- -- second pass, interps + converts
- for key, value in pairs @props
- continue unless key.name == name
+ if start
+ for key in *matching
+ if key.type == start
+ return key, shortest_path
- for { :inp, :out, :transform } in *converts
- return key if inp == key.type and out == type
+ 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
- -- * overrides - map of interp overrides (optional)
- get: (name='', type, overrides) =>
- if not type
- type = name
- name = ''
+ get: (...) =>
+ want = Key ...
- key = @find name, type, not overrides
+ -- find matching key and shortest conversion path
+ key, conversions = @find want
if key
- interp = key\get_interp overrides
-
- return (interp @, @props[key]), key if key.type == type
+ value = @props[key]
- for { :inp, :out, :transform } in *converts
- return (transform interp @, @props[key]), key if inp == key.type and out == type
+ -- apply conversions (in reverse order)
+ for i=#conversions,1,-1
+ { :inp, :out, :transform } = conversions[i]
+ value = transform value, @
- nil, nil
+ value, key
- -- like get, throw if no value or conversion path
- gett: (name='', type, overrides) =>
- if not type
- type = name
- name = ''
+ -- like @get, throw if no value or conversion path
+ gett: (...) =>
+ want = Key ...
- val, key = @get name, type, overrides
- assert val, "node doesn't have value for #{name}:#{type}"
- val, key
+ value, key = @get want
+ assert value, "node doesn't have value for #{want\tostring!}"
+ value, key
-CONVERT = (type, val, key) ->
- return unless val and key
-
- if key.type == type
- val
- else
- for { :inp, :out, :transform } in *converts
- return transform val if inp == key.type and out == type
-
-require = relative ...
-import Browser from require '.browser'
root = require '.tree'
-
-BROWSER = Browser root
-append BROWSER.node
+if MODE == 'CLIENT'
+ import Browser from require '.browser'
+
+ export BROWSER
+ BROWSER = Browser root
+ append BROWSER.node
+else
+ append root\get 'mmm/dom'