aboutsummaryrefslogtreecommitdiffstats
path: root/app
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 /app
parentupdate interp docs (diff)
downloadmmm-3b02770e7f9ec14487493c68ff12ec42e0f2755b.tar.gz
mmm-3b02770e7f9ec14487493c68ff12ec42e0f2755b.zip
reorganize lib
Diffstat (limited to 'app')
-rw-r--r--app/mmmfs/browser.moon99
-rw-r--r--app/mmmfs/conversion.moon121
-rw-r--r--app/mmmfs/gallery.moon (renamed from app/mmmfs/tree/gallery.moon)1
-rw-r--r--app/mmmfs/init.moon344
-rw-r--r--app/mmmfs/tree/init.moon244
-rw-r--r--app/mmmfs/twisted.moon (renamed from app/mmmfs/tree/twisted.moon)5
6 files changed, 251 insertions, 563 deletions
diff --git a/app/mmmfs/browser.moon b/app/mmmfs/browser.moon
deleted file mode 100644
index 427d952..0000000
--- a/app/mmmfs/browser.moon
+++ /dev/null
@@ -1,99 +0,0 @@
-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/app/mmmfs/conversion.moon b/app/mmmfs/conversion.moon
deleted file mode 100644
index b204ff8..0000000
--- a/app/mmmfs/conversion.moon
+++ /dev/null
@@ -1,121 +0,0 @@
-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: (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
-}
diff --git a/app/mmmfs/tree/gallery.moon b/app/mmmfs/gallery.moon
index 86478d3..98c9490 100644
--- a/app/mmmfs/tree/gallery.moon
+++ b/app/mmmfs/gallery.moon
@@ -1,3 +1,4 @@
+import Fileder from require 'lib.mmmfs'
import div, h1, a, img, br from require 'lib.dom'
children = for i=1,100
diff --git a/app/mmmfs/init.moon b/app/mmmfs/init.moon
index e1d813a..5d840ae 100644
--- a/app/mmmfs/init.moon
+++ b/app/mmmfs/init.moon
@@ -1,102 +1,252 @@
require = relative ...
-import get_conversions from require '.conversion'
-
-export ^
-
--- 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
-
-root = require '.tree'
+
+import Fileder from require 'lib.mmmfs'
+
+root = Fileder {
+ -- main content
+ -- doesn't have a name prefix (e.g. preview: moon -> mmm/dom)
+ -- uses the 'moon ->' conversion to execute the lua/moonscript function on get
+ -- resolves to a value of type mmm/dom
+ 'moon -> mmm/dom': () =>
+ html = require 'lib.dom'
+ import article, h1, h2, h3, p, div, a, sup, ol, li, span, code, pre, br from html
+
+ code = do
+ _code = code
+ (str) -> _code str\match '^ *(..-) *$'
+
+ article with _this = {}
+ append = (a) -> table.insert _this, a
+
+ footnote, getnotes = do
+ local *
+ notes = {}
+
+ id = (i) -> "footnote-#{i}"
+
+ footnote = (stuff) ->
+ i = #notes + 1
+ notes[i] = stuff
+ sup a "[#{i}]", style: { 'text-decoration': 'none' }, href: '#' .. id i
+
+ footnote, ->
+ args = for i, note in ipairs notes
+ li (span (tostring i), id: id i), ': ', note
+ notes = {}
+ table.insert args, style: { 'list-style': 'none', 'font-size': '0.8em' }
+ ol table.unpack args
+
+ append h1 'mmmfs', style: { 'margin-bottom': 0 }
+ append p "a file and operating system to live in", style: { 'margin-top': 0, 'margin-bottom': '1em' }
+
+ append p do
+ fileder = footnote "fileder: file + folder. 'node', 'table' etc. are too general to be used all over."
+ child = footnote "fileders can have multiple values, like the mentioned script, but these are not considered
+ children of the fileder, as they are not fileders themselves. One fileder can have many values of different
+ types/keys associated, but these have unspecified schemas and don't nest. In addition it can have many
+ children, which are fileders themselves and can nest, but they are not labelled."
+
+ "in mmmfs, directories are files and files are directories, or something like that.
+ Listen, I don't really know yet either. The idea is that every node knows how to display it's contents;
+ so for example your 'Pictures' fileder", fileder, " contains a script within itself that renders
+ all the picture files you put into it at the children level", child, "."
+
+ append p "a fileder should also be responsible for how it's children are sorted, filtered and interacted with.
+ For example you should be able to create a fileder that is essentially a 'word document' equivalent: it could
+ contain images, websites, links and of course text as children and let you reorder, layout and edit them in
+ it's own edit interface."
+
+ append p "a picture fileder could have an alternate slideshow view (whoops - built that. Click on the 'gallery'
+ example below), or one that shows your geotagged images on a world map, if you really want that.
+ Maybe you could build a music folder that contains links to youtube videos, spotify tracks and just plain mp3
+ files, and the folder knows how to play them all."
+
+ append p "Sounds cool, no? Here's some examples of things a fileder can be or embed:"
+
+ -- render a preview block
+ preview = (title, content, name) -> div {
+ h3 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate { name }
+ content or span '(no renderable content)', style: { color: 'red' },
+ style: {
+ display: 'inline-block',
+ width: '300px',
+ height: '200px',
+ padding: '4px',
+ margin: '8px',
+ border: '4px solid #eeeeee',
+ overflow: 'hidden',
+ },
+ }
+
+ append div for child in *@children
+ -- get 'title' as 'text/plain' (error if no value or conversion possible)
+ title = child\gett 'title', 'text/plain'
+
+ -- get 'preview' as a DOM description (nil if no value or conversion possible)
+ content = child\get 'preview', 'mmm/dom'
+
+ -- get 'preview' as a DOM description (nil if no value or conversion possible)
+ name = child\gett 'name', 'alpha'
+
+ preview title, content, name
+
+
+ append h2 "details"
+ append do
+ mmmdom = code ('mmm/dom'), footnote span (code 'mmm/dom'), " is a polymorphic content type;
+ on the server it is just an HTML string (like ", (code 'text/html'), "),
+ but on the client it is a JS DOM Element instance."
+ fengari = a 'fengari.io', href: 'https://fengari.io'
+ p "What you are viewing right now is a fileder that has a Lua/Moonscript function as a value which
+ is rendering all this text. It returns a value whose type interface is known as ", mmmdom, ", which is
+ basically an HTML subtree. The function can be run, and the results generated, statically on the server
+ (resulting in an HTML file), or dynamically on the client (via ", fengari, ").", br!,
+ "The function is passed the fileder itself (as a Lua table) and potentially also receives some other
+ helpers for accessing it's environment (parent fileders, functions for querying the tree etc) or info
+ specific to the function key/type, but I haven't built or thought about any of that yet. Sorry."
+
+ append do
+ github = footnote a 's-ol/mmm', href: 'https://github.com/s-ol/mmm/tree/master/app/mmmfs'
+ p "Anyway, this node is set up as some sort of wiki/index thing and just lists its children-fileders' ", (code 'title: text/plain'),
+ " values and ", (code 'preview: mmm/dom'), " previews (if set). Oh and also everything is on github and stuff", github,
+ " if you care about that."
+
+ append h3 "converts"
+ append p "Well actually it's a bit more complex. You see, the code that renders these previews ", (html.i "asks"), " for those
+ name/type pairs (", (code 'title: text/plain'), ', ', (code 'preview: mmm/dom'), "), but the values don't actually have to
+ be ", (html.i "defined"), " as these types."
+
+ append pre code [[
+-- render a preview block
+preview = (title, content) -> div {
+ h3 title, style: { ... },
+ content or span '(no renderable content)', style: { ... },
+ style: { ... }
+}
+
+append div for child in *@children
+ -- get 'title' as 'text/plain' (error if no value or conversion possible)
+ title = child\gett 'title', 'text/plain'
+
+ -- get 'preview' as a DOM description (nil if no value or conversion possible)
+ content = child\get 'preview', 'mmm/dom'
+
+ preview title, content
+ ]]
+
+ append p "For example, the markdown child below only provides ", (code 'preview'), " as ", (code 'text/markdown'), ":"
+
+ append pre code [[
+Fileder {
+ 'title: text/plain': "I'm not even five lines of markdown but i render myself!",
+ 'preview: text/markdown': "See I have like
+
+- a list of things
+- (two things)
+
+and some bold **text** and `code tags` with me.",
+}
+ ]]
+
+ append p "Then, globally, there are some conversion paths specified; such as one that maps from ",
+ (code 'text/markdown'), " to ", (code 'mmm/dom'), ":"
+
+ append pre code [[
+{
+ inp: 'text/markdown',
+ out: 'mmm/dom',
+ transform: (md) ->
+ -- polymorphic client/serverside implementation here,
+ -- uses lua-discount on the server, marked.js on the client
+}
+ ]]
+
+ append h3 "type chains"
+ append p "In addition, a property type can be encoded using multiple types in a ", (code 'type chain'), ".
+ For example the root node you are viewing currently is defined as ", (code 'moon -> mmm/dom'), ",
+ meaning it's value is a moonscript function returing a regular ", (code 'mmm/dom'), " value."
+
+ append p "Both value chains and 'sideways' converts are resolved using the same mechanism,
+ so this page is being rendered just using ", (code "append root\\get 'mmm/dom'"), " as well.
+ The convert that resolves the moon type is defined as follows:"
+
+ append pre code [[
+{
+ inp: 'moon -> (.+)',
+ out: '%1',
+ transform: (val, fileder) -> val fileder
+}
+ ]]
+
+ append p "The example with the image is curious as well. In mmmfs, you might want to save a link to an image,
+ without ever saving the actual image on your hard drive (or wherever the data may ever be stored - it is
+ quite transient currently). The image Fileder below has it's main (unnamed) value tagged as ",
+ (code 'URL -> image/png'), " - a png image, encoded as an URL. When accessed as ", (code 'image/png'), "
+ the URL should be resolved, and the binary data provided in it's place (yeah right - I haven't build that yet)."
+
+ append p "However, if a script is aware of URLs and knows a better way to handle them, then it can ask for and
+ use the URL directly instead.
+ This is what the image demo does in order to pass the URL to an ", (code 'img'), " tag's ", (code 'src'), " attribute:"
+
+ append pre code [[
+Fileder {
+ 'title: text/plain': "Hey I'm like a link to picture or smth",
+ 'URL -> image/png': 'https://picsum.photos/200?random',
+ 'preview: moon -> mmm/dom': =>
+ import img from require 'lib.dom'
+ img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
+}
+ ]]
+
+ append getnotes!
+
+ 'text/markdown': "this is a markdown version or something.
+
+There's no content here so switch back to the real one!
+(Assuming there is a switching UI by the time you are reading this, which I assume since you are reading this at all.
+If you are reading this in the source, then c'mon, just scroll past and give me a break.)
+
+(the switching UI has now been built.)"
+
+ Fileder {
+ 'name: alpha': 'empty',
+ 'title: text/plain': "Hey I'm an ad-hoc child with no content at all",
+ }
+
+ Fileder {
+ 'name: alpha': 'image',
+ 'title: text/plain': "Hey I'm like a link to picture or smth",
+
+ -- main content is image/png, to be interpreted by URL to access
+ 'URL -> image/png': 'https://picsum.photos/200?random',
+
+ -- preview is a lua/moonscript function that neturns an mmm/dom value
+ 'preview: moon -> mmm/dom': =>
+ import img from require 'lib.dom'
+ img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
+ }
+
+ Fileder {
+ 'name: alpha': 'markdown',
+ 'title: text/plain': "I'm not even five lines of markdown but i render myself!",
+
+ -- preview can be rendered using global convert
+ 'preview: text/markdown': "See I have like
+
+- a list of things
+- (two things)
+
+and some bold **text** and `code tags` with me.",
+ }
+
+ require '.gallery',
+
+ -- if we are on client, throw in twisted as a child
+ if MODE == 'CLIENT' then require '.twisted'
+}
+
if MODE == 'CLIENT'
- import Browser from require '.browser'
+ import Browser from require 'lib.mmmfs.browser'
export BROWSER
BROWSER = Browser root
diff --git a/app/mmmfs/tree/init.moon b/app/mmmfs/tree/init.moon
deleted file mode 100644
index 5150d8b..0000000
--- a/app/mmmfs/tree/init.moon
+++ /dev/null
@@ -1,244 +0,0 @@
-require = relative ...
-
-Fileder {
- -- main content
- -- doesn't have a name prefix (e.g. preview: moon -> mmm/dom)
- -- uses the 'moon ->' conversion to execute the lua/moonscript function on get
- -- resolves to a value of type mmm/dom
- 'moon -> mmm/dom': () =>
- html = require 'lib.dom'
- import article, h1, h2, h3, p, div, a, sup, ol, li, span, code, pre, br from html
-
- code = do
- _code = code
- (str) -> _code str\match '^ *(..-) *$'
-
- article with _this = {}
- append = (a) -> table.insert _this, a
-
- footnote, getnotes = do
- local *
- notes = {}
-
- id = (i) -> "footnote-#{i}"
-
- footnote = (stuff) ->
- i = #notes + 1
- notes[i] = stuff
- sup a "[#{i}]", style: { 'text-decoration': 'none' }, href: '#' .. id i
-
- footnote, ->
- args = for i, note in ipairs notes
- li (span (tostring i), id: id i), ': ', note
- notes = {}
- table.insert args, style: { 'list-style': 'none', 'font-size': '0.8em' }
- ol table.unpack args
-
- append h1 'mmmfs', style: { 'margin-bottom': 0 }
- append p "a file and operating system to live in", style: { 'margin-top': 0, 'margin-bottom': '1em' }
-
- append p do
- fileder = footnote "fileder: file + folder. 'node', 'table' etc. are too general to be used all over."
- child = footnote "fileders can have multiple values, like the mentioned script, but these are not considered
- children of the fileder, as they are not fileders themselves. One fileder can have many values of different
- types/keys associated, but these have unspecified schemas and don't nest. In addition it can have many
- children, which are fileders themselves and can nest, but they are not labelled."
-
- "in mmmfs, directories are files and files are directories, or something like that.
- Listen, I don't really know yet either. The idea is that every node knows how to display it's contents;
- so for example your 'Pictures' fileder", fileder, " contains a script within itself that renders
- all the picture files you put into it at the children level", child, "."
-
- append p "a fileder should also be responsible for how it's children are sorted, filtered and interacted with.
- For example you should be able to create a fileder that is essentially a 'word document' equivalent: it could
- contain images, websites, links and of course text as children and let you reorder, layout and edit them in
- it's own edit interface."
-
- append p "a picture fileder could have an alternate slideshow view (whoops - built that. Click on the 'gallery'
- example below), or one that shows your geotagged images on a world map, if you really want that.
- Maybe you could build a music folder that contains links to youtube videos, spotify tracks and just plain mp3
- files, and the folder knows how to play them all."
-
- append p "Sounds cool, no? Here's some examples of things a fileder can be or embed:"
-
- -- render a preview block
- preview = (title, content, name) -> div {
- h3 title, style: { margin: 0, cursor: 'pointer' }, onclick: -> BROWSER\navigate { name }
- content or span '(no renderable content)', style: { color: 'red' },
- style: {
- display: 'inline-block',
- width: '300px',
- height: '200px',
- padding: '4px',
- margin: '8px',
- border: '4px solid #eeeeee',
- overflow: 'hidden',
- },
- }
-
- append div for child in *@children
- -- get 'title' as 'text/plain' (error if no value or conversion possible)
- title = child\gett 'title', 'text/plain'
-
- -- get 'preview' as a DOM description (nil if no value or conversion possible)
- content = child\get 'preview', 'mmm/dom'
-
- -- get 'preview' as a DOM description (nil if no value or conversion possible)
- name = child\gett 'name', 'alpha'
-
- preview title, content, name
-
-
- append h2 "details"
- append do
- mmmdom = code ('mmm/dom'), footnote span (code 'mmm/dom'), " is a polymorphic content type;
- on the server it is just an HTML string (like ", (code 'text/html'), "),
- but on the client it is a JS DOM Element instance."
- fengari = a 'fengari.io', href: 'https://fengari.io'
- p "What you are viewing right now is a fileder that has a Lua/Moonscript function as a value which
- is rendering all this text. It returns a value whose type interface is known as ", mmmdom, ", which is
- basically an HTML subtree. The function can be run, and the results generated, statically on the server
- (resulting in an HTML file), or dynamically on the client (via ", fengari, ").", br!,
- "The function is passed the fileder itself (as a Lua table) and potentially also receives some other
- helpers for accessing it's environment (parent fileders, functions for querying the tree etc) or info
- specific to the function key/type, but I haven't built or thought about any of that yet. Sorry."
-
- append do
- github = footnote a 's-ol/mmm', href: 'https://github.com/s-ol/mmm/tree/master/app/mmmfs'
- p "Anyway, this node is set up as some sort of wiki/index thing and just lists its children-fileders' ", (code 'title: text/plain'),
- " values and ", (code 'preview: mmm/dom'), " previews (if set). Oh and also everything is on github and stuff", github,
- " if you care about that."
-
- append h3 "converts"
- append p "Well actually it's a bit more complex. You see, the code that renders these previews ", (html.i "asks"), " for those
- name/type pairs (", (code 'title: text/plain'), ', ', (code 'preview: mmm/dom'), "), but the values don't actually have to
- be ", (html.i "defined"), " as these types."
-
- append pre code [[
--- render a preview block
-preview = (title, content) -> div {
- h3 title, style: { ... },
- content or span '(no renderable content)', style: { ... },
- style: { ... }
-}
-
-append div for child in *@children
- -- get 'title' as 'text/plain' (error if no value or conversion possible)
- title = child\gett 'title', 'text/plain'
-
- -- get 'preview' as a DOM description (nil if no value or conversion possible)
- content = child\get 'preview', 'mmm/dom'
-
- preview title, content
- ]]
-
- append p "For example, the markdown child below only provides ", (code 'preview'), " as ", (code 'text/markdown'), ":"
-
- append pre code [[
-Fileder {
- 'title: text/plain': "I'm not even five lines of markdown but i render myself!",
- 'preview: text/markdown': "See I have like
-
-- a list of things
-- (two things)
-
-and some bold **text** and `code tags` with me.",
-}
- ]]
-
- append p "Then, globally, there are some conversion paths specified; such as one that maps from ",
- (code 'text/markdown'), " to ", (code 'mmm/dom'), ":"
-
- append pre code [[
-{
- inp: 'text/markdown',
- out: 'mmm/dom',
- transform: (md) ->
- -- polymorphic client/serverside implementation here,
- -- uses lua-discount on the server, marked.js on the client
-}
- ]]
-
- append h3 "type chains"
- append p "In addition, a property type can be encoded using multiple types in a ", (code 'type chain'), ".
- For example the root node you are viewing currently is defined as ", (code 'moon -> mmm/dom'), ",
- meaning it's value is a moonscript function returing a regular ", (code 'mmm/dom'), " value."
-
- append p "Both value chains and 'sideways' converts are resolved using the same mechanism,
- so this page is being rendered just using ", (code "append root\\get 'mmm/dom'"), " as well.
- The convert that resolves the moon type is defined as follows:"
-
- append pre code [[
-{
- inp: 'moon -> (.+)',
- out: '%1',
- transform: (val, fileder) -> val fileder
-}
- ]]
-
- append p "The example with the image is curious as well. In mmmfs, you might want to save a link to an image,
- without ever saving the actual image on your hard drive (or wherever the data may ever be stored - it is
- quite transient currently). The image Fileder below has it's main (unnamed) value tagged as ",
- (code 'URL -> image/png'), " - a png image, encoded as an URL. When accessed as ", (code 'image/png'), "
- the URL should be resolved, and the binary data provided in it's place (yeah right - I haven't build that yet)."
-
- append p "However, if a script is aware of URLs and knows a better way to handle them, then it can ask for and
- use the URL directly instead.
- This is what the image demo does in order to pass the URL to an ", (code 'img'), " tag's ", (code 'src'), " attribute:"
-
- append pre code [[
-Fileder {
- 'title: text/plain': "Hey I'm like a link to picture or smth",
- 'URL -> image/png': 'https://picsum.photos/200?random',
- 'preview: moon -> mmm/dom': =>
- import img from require 'lib.dom'
- img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
-}
- ]]
-
- append getnotes!
-
- 'text/markdown': "this is a markdown version or something.
-
-There's no content here so switch back to the real one!
-(Assuming there is a switching UI by the time you are reading this, which I assume since you are reading this at all.
-If you are reading this in the source, then c'mon, just scroll past and give me a break.)
-
-(the switching UI has now been built.)"
-
- Fileder {
- 'name: alpha': 'empty',
- 'title: text/plain': "Hey I'm an ad-hoc child with no content at all",
- }
-
- Fileder {
- 'name: alpha': 'image',
- 'title: text/plain': "Hey I'm like a link to picture or smth",
-
- -- main content is image/png, to be interpreted by URL to access
- 'URL -> image/png': 'https://picsum.photos/200?random',
-
- -- preview is a lua/moonscript function that neturns an mmm/dom value
- 'preview: moon -> mmm/dom': =>
- import img from require 'lib.dom'
- img src: @gett 'URL -> image/png' -- look for main content with 'URL to png' type
- }
-
- Fileder {
- 'name: alpha': 'markdown',
- 'title: text/plain': "I'm not even five lines of markdown but i render myself!",
-
- -- preview can be rendered using global convert
- 'preview: text/markdown': "See I have like
-
-- a list of things
-- (two things)
-
-and some bold **text** and `code tags` with me.",
- }
-
- require '.gallery',
-
- -- if we are on client, throw in twisted as a child
- if MODE == 'CLIENT' then require '.twisted'
-}
diff --git a/app/mmmfs/tree/twisted.moon b/app/mmmfs/twisted.moon
index ec3fa83..a122df9 100644
--- a/app/mmmfs/tree/twisted.moon
+++ b/app/mmmfs/twisted.moon
@@ -1,8 +1,9 @@
-Math = window.Math
-
+import Fileder from require 'lib.mmmfs'
import CanvasApp from require 'lib.canvasapp'
import hsl from require 'lib.color'
+Math = window.Math
+
class TwistedDemo extends CanvasApp
width: 500
height: 400