aboutsummaryrefslogtreecommitdiffstats
path: root/app/mmmfs/conversion.moon
diff options
context:
space:
mode:
Diffstat (limited to 'app/mmmfs/conversion.moon')
-rw-r--r--app/mmmfs/conversion.moon121
1 files changed, 121 insertions, 0 deletions
diff --git a/app/mmmfs/conversion.moon b/app/mmmfs/conversion.moon
new file mode 100644
index 0000000..a670e2e
--- /dev/null
+++ b/app/mmmfs/conversion.moon
@@ -0,0 +1,121 @@
+import text, code from require 'lib.html'
+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: (val) ->
+ html = markdown val
+ warn html
+ html
+ }
+
+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
+}