aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2020-12-03 16:38:43 +0000
committers-ol <s+removethis@s-ol.nu>2020-12-03 16:38:43 +0000
commite0a0b25f6586cdf1b1284d97bedadfce5535ba96 (patch)
tree50cf646dc673faeda648e7135d84e46f2dbd5262
parentfix typo break text/html+interactive (diff)
downloadmmm-e0a0b25f6586cdf1b1284d97bedadfce5535ba96.tar.gz
mmm-e0a0b25f6586cdf1b1284d97bedadfce5535ba96.zip
move plugins into root
-rw-r--r--mmm/mmmfs/browser.moon2
-rw-r--r--mmm/mmmfs/conversion.moon47
-rw-r--r--mmm/mmmfs/fileder.moon32
-rw-r--r--mmm/mmmfs/plugins/code.moon12
-rw-r--r--mmm/mmmfs/plugins/gltf.moon17
-rw-r--r--mmm/mmmfs/plugins/init.moon8
-rw-r--r--mmm/mmmfs/plugins/markdown.moon67
-rw-r--r--mmm/mmmfs/plugins/mermaid.moon27
-rw-r--r--mmm/mmmfs/plugins/static.moon33
-rw-r--r--mmm/mmmfs/plugins/twitter.moon25
-rw-r--r--mmm/mmmfs/plugins/youtube.moon27
-rw-r--r--mmm/mmmfs/stores/fs.moon29
-rw-r--r--root/$mmm/plugins/cites/converts: text$moonscript -> table.moon (renamed from mmm/mmmfs/plugins/cites.moon)28
-rw-r--r--root/$mmm/plugins/code/converts: text$moonscript -> table.moon90
-rw-r--r--root/$mmm/plugins/code/scripts: text$html+frag.html5
-rw-r--r--root/$mmm/plugins/gltf/converts: text$moonscript -> table.moon16
-rw-r--r--root/$mmm/plugins/gltf/scripts: text$html+frag.html2
-rw-r--r--root/$mmm/plugins/json/converts: text$moonscript -> table.moon (renamed from mmm/mmmfs/plugins/json.moon)24
-rw-r--r--root/$mmm/plugins/markdown/converts: text$moonscript -> table.moon67
-rw-r--r--root/$mmm/plugins/markdown/scripts: text$html+frag.html1
-rw-r--r--root/$mmm/plugins/mermaid/converts: text$moonscript -> table.moon29
-rw-r--r--root/$mmm/plugins/mermaid/scripts: text$html+frag.html1
-rw-r--r--root/$mmm/plugins/static/converts: text$moonscript -> table.moon34
-rw-r--r--root/$mmm/plugins/twitter/converts: text$moonscript -> table.moon21
-rw-r--r--root/$mmm/plugins/youtube/converts: text$moonscript -> table.moon25
-rw-r--r--root/$order2
26 files changed, 399 insertions, 272 deletions
diff --git a/mmm/mmmfs/browser.moon b/mmm/mmmfs/browser.moon
index 2cef8a4..2abe512 100644
--- a/mmm/mmmfs/browser.moon
+++ b/mmm/mmmfs/browser.moon
@@ -274,7 +274,7 @@ class Browser
value, key = fileder\get prop
assert key, "couldn't @get #{prop}"
- conversions = get_conversions 'mmm/dom', key.type, get_casts!
+ conversions = get_conversions fileder, 'mmm/dom', key.type, get_casts!
assert conversions, "cannot cast '#{key.type}'"
with res = apply_conversions conversions, value, fileder, prop
@editor\set if res.EDITOR then res
diff --git a/mmm/mmmfs/conversion.moon b/mmm/mmmfs/conversion.moon
index d0a6842..2d25793 100644
--- a/mmm/mmmfs/conversion.moon
+++ b/mmm/mmmfs/conversion.moon
@@ -11,8 +11,6 @@ escape_pattern = (inp) ->
"^#{inp\gsub '([^%w])', '%%%1'}$"
escape_inp = (inp) -> "^#{inp\gsub '([-/])', '%%%1'}$"
-local print_conversions
-
class MermaidDebugger
new: =>
nextid = 0
@@ -55,15 +53,43 @@ class MermaidDebugger
"graph TD\n" .. @buf
+get_converts = (fileder) ->
+ assert PLUGINS
+ assert BROWSER.root
+ converts = [c for c in *PLUGINS.converts]
+
+ -- search until closest non-meta ancestor
+ local guard_self
+ max_path = fileder.path
+ if closest = max_path\match('(.-)/$mmm')
+ max_path = closest
+ guard_self = true
+
+ for ancestor in coroutine.wrap -> BROWSER.root\walk_co max_path
+ if guard_self and ancestor.path == max_path
+ break
+
+ ancestor\load! if not ancestor.loaded
+
+ if meta = ancestor.meta
+ for plugin in *meta\walk('plugins').children
+ for c in *(plugin\get('converts: table') or {})
+ table.insert converts, c
+
+ converts
+
-- attempt to find a conversion path from 'have' to 'want'
+-- * fileder - fileder to start with
-- * have - start type string or list of type strings
-- * want - stop type pattern
-- * limit - limit conversion amount
-- * debug - a table with debug hooks
-- returns a list of conversion steps
-get_conversions = (want, have, converts=PLUGINS and PLUGINS.converts, limit=5, debug) ->
+get_conversions = (fileder, want, have, converts, limit=5, debug) ->
+ converts or= get_converts fileder
+
assert have, 'need starting type(s)'
- assert converts, 'need to pass list of converts'
+ assert converts, 'need to pass list of converts'
if 'string' == type have
have = { have }
@@ -143,15 +169,14 @@ print_conversions = (conversions) ->
-- * ... - other transform parameters (fileder, key)
-- returns converted value
err_and_trace = (msg) -> debug.traceback msg, 2
-apply_conversions = (conversions, value, ...) ->
+apply_conversions = (fileder, conversions, value, key) ->
for i=#conversions,1,-1
refs\push!
step = conversions[i]
- ok, value = xpcall step.convert.transform, err_and_trace, step, value, ...
+ ok, value = xpcall step.convert.transform, err_and_trace, step, value, fileder, key
refs\pop!
if not ok
- f, k = ...
- error "error while converting #{f} #{k} from '#{step.from}' to '#{step.to}':\n#{value}"
+ error "error while converting #{fileder} #{key} from '#{step.from}' to '#{step.to}':\n#{value}"
value
@@ -160,8 +185,8 @@ apply_conversions = (conversions, value, ...) ->
-- * want - stop type pattern
-- * value - value or map from have-types to values
-- returns converted value
-convert = (have, want, value, ...) ->
- conversions, start = get_conversions want, have
+convert = (have, want, value, fileder, key) ->
+ conversions, start = get_conversions fileder, want, have
if not conversions
warn "couldn't convert from '#{have}' to '#{want}'"
@@ -170,7 +195,7 @@ convert = (have, want, value, ...) ->
if 'string' ~= type have
value = value[start]
- apply_conversions conversions, value, ...
+ apply_conversions fileder, conversions, value, key
{
:MermaidDebugger
diff --git a/mmm/mmmfs/fileder.moon b/mmm/mmmfs/fileder.moon
index 871f46f..4dcc60b 100644
--- a/mmm/mmmfs/fileder.moon
+++ b/mmm/mmmfs/fileder.moon
@@ -160,16 +160,20 @@ class Fileder
-- load fact/children contents
-- called automatically by metamethods set up in constructor
- -- can take an index instance if it is already available,
+ -- can take an index instance if it is already available
load: (index) =>
assert not @loaded, "already loaded!"
@loaded = true
- if not index
- index = @store\get_index @path
+ index or= @store\get_index @path
for path_or_index in *index.children
- table.insert @children, Fileder @store, path_or_index
+ child = Fileder @store, path_or_index
+ name = child\get 'name: alpha'
+ if '$' != name\sub 1, 1
+ table.insert @children, child
+ elseif name == '$mmm'
+ @meta = child
for key in *index.facets
key = Key key
@@ -202,6 +206,22 @@ class Fileder
if match = child\walk path
return match
+ if match = @meta and @meta\walk path
+ return match
+
+ -- like :walk but yield all ancestors of path
+ -- * path - the path to walk to
+ walk_co: (path) =>
+ path = "#{@path}/#{path}" if '/' != path\sub 1, 1
+
+ return unless @path == path\sub 1, #@path
+ return if #path == #@path
+
+ coroutine.yield @
+
+ for child in *@children
+ child\walk_co path
+
-- recursively mount fileder and children at path
-- * path - the path to mount at
-- * mount_as - dont append own name to path
@@ -257,7 +277,7 @@ class Fileder
return unless #matching > 0
-- get shortest conversion path
- shortest_path, start = get_conversions want.type, [ key.type for key in *matching ], ...
+ shortest_path, start = get_conversions @, want.type, [ key.type for key in *matching ], ...
if start
for key in *matching
@@ -279,7 +299,7 @@ class Fileder
key, conversions = @find want
if key
- value = apply_conversions conversions, @facets[key], @, key
+ value = apply_conversions @, conversions, @facets[key], key
value, key
-- like @get, throw if no value or conversion path
diff --git a/mmm/mmmfs/plugins/code.moon b/mmm/mmmfs/plugins/code.moon
index 8ab760a..454f32f 100644
--- a/mmm/mmmfs/plugins/code.moon
+++ b/mmm/mmmfs/plugins/code.moon
@@ -43,7 +43,7 @@ class Editor
if @lastPreview and doc\isClean @lastPreview
-- no changes since last event
return
-
+
@lastPreview = doc\changeGeneration!
value = doc\getValue!
@@ -59,16 +59,6 @@ class Editor
-- syntax-highlighted code
{
- converts: {
- {
- inp: 'text/([^ ]*).*'
- out: 'mmm/dom'
- cost: 5
- transform: (val) =>
- lang = @from\match @convert.inp
- pre languages[lang] val
- }
- }
editors: if MODE == 'CLIENT' then {
{
inp: 'text/([^ ]*).*'
diff --git a/mmm/mmmfs/plugins/gltf.moon b/mmm/mmmfs/plugins/gltf.moon
index 28a6cf8..129a291 100644
--- a/mmm/mmmfs/plugins/gltf.moon
+++ b/mmm/mmmfs/plugins/gltf.moon
@@ -1,21 +1,4 @@
-dom = require 'mmm.dom'
-
{
- converts: {
- {
- inp: 'URL -> model/gltf-binary'
- out: 'mmm/dom'
- cost: 1
- transform: (href) =>
- dom['model-viewer'] {
- src: href
- 'auto-rotate': true
- 'camera-controls': true
- 'camera-orbit': "548.2deg 117deg 282.4m"
- }
- }
- }
-
scripts: [[
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
<script nomodule src="https://unpkg.com/@google/model-viewer/dist/model-viewer-legacy.js"></script>
diff --git a/mmm/mmmfs/plugins/init.moon b/mmm/mmmfs/plugins/init.moon
index d46e59c..c16cdfa 100644
--- a/mmm/mmmfs/plugins/init.moon
+++ b/mmm/mmmfs/plugins/init.moon
@@ -291,17 +291,11 @@ add_plugin = (module) ->
scripts ..= plugin.scripts
add_plugin 'code'
-add_plugin 'json'
add_plugin 'markdown'
add_plugin 'mermaid'
-add_plugin 'twitter'
-add_plugin 'youtube'
-add_plugin 'cites'
add_plugin 'gltf'
-if STATIC
- add_plugin 'static'
-else
+if not STATIC
table.insert converts, {
inp: '(.+)',
out: 'URL -> %1',
diff --git a/mmm/mmmfs/plugins/markdown.moon b/mmm/mmmfs/plugins/markdown.moon
index 680fdc4..c5a8f96 100644
--- a/mmm/mmmfs/plugins/markdown.moon
+++ b/mmm/mmmfs/plugins/markdown.moon
@@ -1,71 +1,4 @@
-markdown = if MODE == 'SERVER'
- success, discount = pcall require, 'discount'
- assert success, "couldn't require 'discount'"
-
- (md) ->
- res = assert discount.compile md, 'githubtags', 'fencedcode'
- res.body
-else
- assert window and window.marked, "marked.js not found"
-
- o = do
- mkobj = window\eval "(function () { return {}; })"
- (tbl) ->
- with obj = mkobj!
- for k,v in pairs(tbl)
- obj[k] = v
-
- trim = (str) -> str\match '^ *(..-) *$'
-
- window.marked\setOptions o {
- gfm: true
- smartypants: true
- langPrefix: 'lang-'
- highlight: (code, lang) =>
- code = trim code
- result = if lang and #lang > 0
- window.hljs\highlight lang, code, true
- else
- window.hljs\highlightAuto code
-
- result.value
- }
-
- window\marked
-
-assert markdown, "no markdown implementation found"
-
{
- converts: {
- {
- inp: 'text/markdown'
- out: 'text/html+frag'
- cost: 1
- transform: (md) => "<div class=\"markdown\">#{markdown md}</div>"
- }
- {
- inp: 'text/markdown%+sidenotes'
- out: 'text/html+frag'
- cost: 1
- transform: (md) => "<div class=\"markdown sidenote-container\">#{markdown md}</div>"
- }
- {
- inp: 'text/markdown%+wide'
- out: 'text/html+frag'
- cost: 1
- transform: (md) => "<div class=\"markdown wide\">#{markdown md}</div>"
- }
- {
- inp: 'text/markdown%+span'
- out: 'text/html+frag'
- cost: 1
- transform: (source) =>
- html = markdown source
- html = html\gsub '^%s*<p>%s*', '<span>'
- html = html\gsub '%s*</p>%s*$', '</span>'
- html
- }
- }
scripts: [[
<script type="text/javascript" src="//unpkg.com/marked@0.7.0/marked.min.js"></script>
]]
diff --git a/mmm/mmmfs/plugins/mermaid.moon b/mmm/mmmfs/plugins/mermaid.moon
index a5cbc7c..c076e7b 100644
--- a/mmm/mmmfs/plugins/mermaid.moon
+++ b/mmm/mmmfs/plugins/mermaid.moon
@@ -1,31 +1,4 @@
-assert window and window.mermaid, "mermaid.js not found"
-
-window.mermaid\initialize {
- startOnLoad: false
- fontFamily: 'monospace'
-}
-
-id_counter = 1
-
{
- converts: {
- {
- inp: 'text/mermaid-graph'
- out: 'mmm/dom'
- cost: 1
- transform: (source, fileder, key) =>
- id_counter += 1
- id = "mermaid-#{id_counter}"
- with container = document\createElement 'div'
- cb = (svg) =>
- .innerHTML = svg
- .firstElementChild.style.width = '100%'
- .firstElementChild.style.height = 'auto'
-
- window\setImmediate (_) ->
- window.mermaid\render id, source, cb, container
- }
- }
scripts: [[
<script type="text/javascript" src="//unpkg.com/mermaid@8.4.0/dist/mermaid.min.js"></script>
]]
diff --git a/mmm/mmmfs/plugins/static.moon b/mmm/mmmfs/plugins/static.moon
deleted file mode 100644
index 5bf9476..0000000
--- a/mmm/mmmfs/plugins/static.moon
+++ /dev/null
@@ -1,33 +0,0 @@
-extensions = {
- 'image/jpeg': 'jpg'
- 'image/png': 'png'
- 'image/svg+xml': 'svg'
-
- 'video/webm': 'webm'
- 'video/mp4': 'mp4'
-
- 'text/javascript': 'js'
- 'text/css': 'css'
-
- 'model/gltf-binary': 'glb'
-}
-
-{
- converts: {
- {
- inp: '(.+)',
- out: 'URL -> %1',
- cost: 5
- transform: (val, fileder, key) =>
- escaped_from = @from\gsub '/', '_'
- if ext = extensions[@from]
- escaped_from ..= ".#{ext}"
-
- prefix = STATIC.root or ''
-
- prefix .. with url = "#{fileder.path}/#{key.name}:#{escaped_from}"
- print " rendering asset #{url}"
- STATIC.spit url, val
- }
- }
-}
diff --git a/mmm/mmmfs/plugins/twitter.moon b/mmm/mmmfs/plugins/twitter.moon
deleted file mode 100644
index 7577076..0000000
--- a/mmm/mmmfs/plugins/twitter.moon
+++ /dev/null
@@ -1,25 +0,0 @@
-import div, blockquote, a from require 'mmm.dom'
-
-{
- converts: {
- {
- inp: 'URL -> twitter/tweet'
- out: 'mmm/dom'
- cost: -4
- transform: (href) =>
- id = assert (href\match 'twitter.com/[^/]-/status/(%d*)'), "couldn't parse twitter/tweet URL: '#{href}'"
- if MODE == 'CLIENT'
- with parent = div!
- window.twttr.widgets\createTweet id, parent
- else
- div blockquote {
- class: 'twitter-tweet'
- 'data-lang': 'en'
- a '(linked tweet)', :href
- }
- }
- }
- scripts: [[
- <script type="text/javascript" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
- ]]
-}
diff --git a/mmm/mmmfs/plugins/youtube.moon b/mmm/mmmfs/plugins/youtube.moon
deleted file mode 100644
index 9086041..0000000
--- a/mmm/mmmfs/plugins/youtube.moon
+++ /dev/null
@@ -1,27 +0,0 @@
-import iframe from require 'mmm.dom'
-
-{
- converts: {
- {
- inp: 'URL -> youtube/video'
- out: 'mmm/dom'
- cost: -4
- transform: (link) =>
- id = link\match 'youtu%.be/([^/]+)'
- id or= link\match 'youtube.com/watch.*[?&]v=([^&]+)'
- id or= link\match 'youtube.com/[ev]/([^/]+)'
- id or= link\match 'youtube.com/embed/([^/]+)'
-
- assert id, "couldn't parse youtube URL: '#{link}'"
-
- iframe {
- width: 560
- height: 315
- frameborder: 0
- allowfullscreen: true
- frameBorder: 0
- src: "//www.youtube.com/embed/#{id}"
- }
- }
- }
-}
diff --git a/mmm/mmmfs/stores/fs.moon b/mmm/mmmfs/stores/fs.moon
index 3d602c8..c1d613f 100644
--- a/mmm/mmmfs/stores/fs.moon
+++ b/mmm/mmmfs/stores/fs.moon
@@ -21,18 +21,24 @@ class FSStore extends Store
@log "opening '#{opts.root}'..."
-- fileders
- get_order: (path, forgiving=false) =>
+ get_order: (path, forgiving=false, include_meta=false) =>
entries = {}
+ sorted = {}
for name in lfs.dir @root .. path
- continue if '.' == name\sub 1, 1
- entry_path = @root .. "#{path}/#{name}"
+ continue if '.' == name\sub(1, 1)
+ continue if '$' == name\sub(1, 1) and not include_meta
+ entry_path = "#{@root}#{path}/#{name}"
if 'directory' ~= lfs.attributes entry_path, 'mode'
continue
- entries[name] = :name, path: "#{path}/#{name}"
+ entry = :name, path: "#{path}/#{name}"
+ entries[name] = entry
- sorted = {}
- order_file = @root .. "#{path}/$order"
+ if '$' == name\sub 1, 1
+ table.insert sorted, entry
+ sorted[name] = true
+
+ order_file = "#{@root}#{path}/$order"
if 'file' == lfs.attributes order_file, 'mode'
for line in io.lines order_file
entry = entries[line]
@@ -44,6 +50,8 @@ class FSStore extends Store
table.insert sorted, entry
sorted[line] = true
+ else
+ forgiving = true
unsorted = [entry for name, entry in pairs entries when not sorted[entry.name]]
if forgiving
@@ -56,7 +64,7 @@ class FSStore extends Store
sorted
write_order: (path, order=@get_order path, true) =>
- order_file = @root .. "#{path}/$order"
+ order_file = "#{@root}#{path}/$order"
if #order == 0
os.remove order_file
return
@@ -67,7 +75,7 @@ class FSStore extends Store
file\close!
list_fileders_in: (path='') =>
- sorted = @get_order path
+ sorted = @get_order path, nil, true
coroutine.wrap ->
for { :path } in *sorted
@@ -104,12 +112,12 @@ class FSStore extends Store
rename_fileder: (path, next_name) =>
@log "renaming fileder #{path} -> '#{next_name}'"
parent, name = dir_base path
- assert os.rename path, @root .. "#{parent}/#{next_name}"
+ assert os.rename path, "#{@root}#{parent}/#{next_name}"
move_fileder: (path, next_parent) =>
@log "moving fileder #{path} -> #{next_parent}/"
parent, name = dir_base path
- assert os.rename @root .. path, @root .. "#{next_parent}/#{name}"
+ assert os.rename @root .. path, "#{@root}#{next_parent}/#{name}"
-- swap two childrens' order
swap_fileders: (parent, name_a, name_b) =>
@@ -165,7 +173,6 @@ class FSStore extends Store
error "two files match #{name}: #{file_name} and #{entry_name}!"
file_name = entry_name
-
file_name and @root .. "#{path}/#{file_name}"
load_facet: (path, name, type) =>
diff --git a/mmm/mmmfs/plugins/cites.moon b/root/$mmm/plugins/cites/converts: text$moonscript -> table.moon
index 527416e..73a6580 100644
--- a/mmm/mmmfs/plugins/cites.moon
+++ b/root/$mmm/plugins/cites/converts: text$moonscript -> table.moon
@@ -56,20 +56,18 @@ format_full = () =>
\insert "#{dot} #{@publisher}" if @publisher
span tbl
{
- converts: {
- {
- inp: 'cite/doi'
- out: 'URL -> text/bibtex'
- cost: 0.1
- transform: (doi) =>
- doi = doi\match '(10%.%d%d%d%d%d?%d?%d?%d?%d?/[%d%w%.%-_:;%(%)]+)'
- "http://api.crossref.org/works/#{doi}/transform/application/x-bibtex"
- }
- {
- inp: 'text/bibtex'
- out: 'mmm/dom'
- cost: 1
- transform: (bib) => format_full parse_bibtex bib
- }
+ {
+ inp: 'cite/doi'
+ out: 'URL -> text/bibtex'
+ cost: 0.1
+ transform: (doi) =>
+ doi = doi\match '(10%.%d%d%d%d%d?%d?%d?%d?%d?/[%d%w%.%-_:;%(%)]+)'
+ "http://api.crossref.org/works/#{doi}/transform/application/x-bibtex"
+ }
+ {
+ inp: 'text/bibtex'
+ out: 'mmm/dom'
+ cost: 1
+ transform: (bib) => format_full parse_bibtex bib
}
}
diff --git a/root/$mmm/plugins/code/converts: text$moonscript -> table.moon b/root/$mmm/plugins/code/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..851efba
--- /dev/null
+++ b/root/$mmm/plugins/code/converts: text$moonscript -> table.moon
@@ -0,0 +1,90 @@
+import pre, div, button from require 'mmm.dom'
+import languages from require 'mmm.highlighting'
+
+class Editor
+ o = if MODE == 'CLIENT'
+ mkobj = window\eval "(function () { return {}; })"
+ (tbl) ->
+ with obj = mkobj!
+ for k,v in pairs(tbl)
+ obj[k] = v
+
+ EDITOR: true
+
+ new: (value, mode, @fileder, @key) =>
+ @node = div class: 'editor'
+
+ @saveBtn = with button 'save'
+ .disabled = true
+ .onclick = (_, e) -> @save e
+
+ @cm = window\CodeMirror @node, o {
+ :value
+ :mode
+ lineNumber: true
+ lineWrapping: true
+ autoRefresh: true
+ theme: 'hybrid'
+ }
+
+ @lastSave = @cm\getDoc!\changeGeneration true
+
+ @cm\on 'changes', (_, mirr) ->
+ doc = @cm\getDoc!
+ @saveBtn.disabled = doc\isClean @lastSave
+
+ window\clearTimeout @timeout if @timeout
+ @timeout = window\setTimeout (-> @change!), 300
+
+ change: =>
+ @timeout = nil
+ doc = @cm\getDoc!
+
+ if @lastPreview and doc\isClean @lastPreview
+ -- no changes since last event
+ return
+
+ @lastPreview = doc\changeGeneration!
+ value = doc\getValue!
+
+ @fileder.facets[@key] = value
+ BROWSER\refresh!
+
+ save: (e) =>
+ e\preventDefault!
+
+ doc = @cm\getDoc!
+ @fileder\set @key, doc\getValue!
+ @lastSave = doc\changeGeneration true
+
+[[
+ editors: if MODE == 'CLIENT' then {
+ {
+ inp: 'text/([^ ]*).*'
+ out: 'mmm/dom'
+ cost: 0
+ transform: (value, fileder, key) =>
+ mode = @from\match @convert.inp
+ Editor value, mode, fileder, key
+ }
+ {
+ inp: 'URL.*'
+ out: 'mmm/dom'
+ cost: 0
+ transform: (value, fileder, key) =>
+ Editor value, nil, fileder, key
+ }
+ }
+]]
+
+-- syntax-highlighted code
+{
+ {
+ inp: 'text/([^ ]*).*'
+ out: 'mmm/dom'
+ cost: 5
+ transform: (val) =>
+ lang = @from\match @convert.inp
+ pre languages[lang] val
+ }
+}
diff --git a/root/$mmm/plugins/code/scripts: text$html+frag.html b/root/$mmm/plugins/code/scripts: text$html+frag.html
new file mode 100644
index 0000000..68d780b
--- /dev/null
+++ b/root/$mmm/plugins/code/scripts: text$html+frag.html
@@ -0,0 +1,5 @@
+ <link rel="stylesheet" type="text/css" href="//unpkg.com/codemirror@5.49.2/lib/codemirror.css" />
+ <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/lib/codemirror.js"></script>
+ <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/mode/lua/lua.js"></script>
+ <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/mode/markdown/markdown.js"></script>
+ <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/addon/display/autorefresh.js"></script>
diff --git a/root/$mmm/plugins/gltf/converts: text$moonscript -> table.moon b/root/$mmm/plugins/gltf/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..1036eee
--- /dev/null
+++ b/root/$mmm/plugins/gltf/converts: text$moonscript -> table.moon
@@ -0,0 +1,16 @@
+dom = require 'mmm.dom'
+
+{
+ {
+ inp: 'URL -> model/gltf-binary'
+ out: 'mmm/dom'
+ cost: 1
+ transform: (href) =>
+ dom['model-viewer'] {
+ src: href
+ 'auto-rotate': true
+ 'camera-controls': true
+ 'camera-orbit': "548.2deg 117deg 282.4m"
+ }
+ }
+}
diff --git a/root/$mmm/plugins/gltf/scripts: text$html+frag.html b/root/$mmm/plugins/gltf/scripts: text$html+frag.html
new file mode 100644
index 0000000..d2b1e44
--- /dev/null
+++ b/root/$mmm/plugins/gltf/scripts: text$html+frag.html
@@ -0,0 +1,2 @@
+ <script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
+ <script nomodule src="https://unpkg.com/@google/model-viewer/dist/model-viewer-legacy.js"></script>
diff --git a/mmm/mmmfs/plugins/json.moon b/root/$mmm/plugins/json/converts: text$moonscript -> table.moon
index cbcff46..7b150a5 100644
--- a/mmm/mmmfs/plugins/json.moon
+++ b/root/$mmm/plugins/json/converts: text$moonscript -> table.moon
@@ -38,19 +38,17 @@ else
{
- converts: {
+ {
+ inp: 'table',
+ out: 'text/json',
+ cost: 2
+ transform: (val) => encode val
+ }
+ if decode
{
- inp: 'table',
- out: 'text/json',
- cost: 2
- transform: (val) => encode val
+ inp: 'text/json'
+ out: 'table'
+ cost: 1
+ transform: (val) => decode val
}
- if decode
- {
- inp: 'text/json'
- out: 'table'
- cost: 1
- transform: (val) => decode val
- }
- }
}
diff --git a/root/$mmm/plugins/markdown/converts: text$moonscript -> table.moon b/root/$mmm/plugins/markdown/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..4e0da31
--- /dev/null
+++ b/root/$mmm/plugins/markdown/converts: text$moonscript -> table.moon
@@ -0,0 +1,67 @@
+markdown = if MODE == 'SERVER'
+ success, discount = pcall require, 'discount'
+ assert success, "couldn't require 'discount'"
+
+ (md) ->
+ res = assert discount.compile md, 'githubtags', 'fencedcode'
+ res.body
+else
+ assert window and window.marked, "marked.js not found"
+
+ o = do
+ mkobj = window\eval "(function () { return {}; })"
+ (tbl) ->
+ with obj = mkobj!
+ for k,v in pairs(tbl)
+ obj[k] = v
+
+ trim = (str) -> str\match '^ *(..-) *$'
+
+ window.marked\setOptions o {
+ gfm: true
+ smartypants: true
+ langPrefix: 'lang-'
+ highlight: (code, lang) =>
+ code = trim code
+ result = if lang and #lang > 0
+ window.hljs\highlight lang, code, true
+ else
+ window.hljs\highlightAuto code
+
+ result.value
+ }
+
+ window\marked
+
+assert markdown, "no markdown implementation found"
+
+{
+ {
+ inp: 'text/markdown'
+ out: 'text/html+frag'
+ cost: 1
+ transform: (md) => "<div class=\"markdown\">#{markdown md}</div>"
+ }
+ {
+ inp: 'text/markdown%+sidenotes'
+ out: 'text/html+frag'
+ cost: 1
+ transform: (md) => "<div class=\"markdown sidenote-container\">#{markdown md}</div>"
+ }
+ {
+ inp: 'text/markdown%+wide'
+ out: 'text/html+frag'
+ cost: 1
+ transform: (md) => "<div class=\"markdown wide\">#{markdown md}</div>"
+ }
+ {
+ inp: 'text/markdown%+span'
+ out: 'text/html+frag'
+ cost: 1
+ transform: (source) =>
+ html = markdown source
+ html = html\gsub '^%s*<p>%s*', '<span>'
+ html = html\gsub '%s*</p>%s*$', '</span>'
+ html
+ }
+}
diff --git a/root/$mmm/plugins/markdown/scripts: text$html+frag.html b/root/$mmm/plugins/markdown/scripts: text$html+frag.html
new file mode 100644
index 0000000..5bfb275
--- /dev/null
+++ b/root/$mmm/plugins/markdown/scripts: text$html+frag.html
@@ -0,0 +1 @@
+ <script type="text/javascript" src="//unpkg.com/marked@0.7.0/marked.min.js"></script>
diff --git a/root/$mmm/plugins/mermaid/converts: text$moonscript -> table.moon b/root/$mmm/plugins/mermaid/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..1eb695e
--- /dev/null
+++ b/root/$mmm/plugins/mermaid/converts: text$moonscript -> table.moon
@@ -0,0 +1,29 @@
+-- assert window and window.mermaid, "mermaid.js not found"
+if not (window and window.mermaid)
+ return
+
+window.mermaid\initialize {
+ startOnLoad: false
+ fontFamily: 'monospace'
+}
+
+id_counter = 1
+
+{
+ {
+ inp: 'text/mermaid-graph'
+ out: 'mmm/dom'
+ cost: 1
+ transform: (source, fileder, key) =>
+ id_counter += 1
+ id = "mermaid-#{id_counter}"
+ with container = document\createElement 'div'
+ cb = (svg) =>
+ .innerHTML = svg
+ .firstElementChild.style.width = '100%'
+ .firstElementChild.style.height = 'auto'
+
+ window\setImmediate (_) ->
+ window.mermaid\render id, source, cb, container
+ }
+}
diff --git a/root/$mmm/plugins/mermaid/scripts: text$html+frag.html b/root/$mmm/plugins/mermaid/scripts: text$html+frag.html
new file mode 100644
index 0000000..282fbd5
--- /dev/null
+++ b/root/$mmm/plugins/mermaid/scripts: text$html+frag.html
@@ -0,0 +1 @@
+ <script type="text/javascript" src="//unpkg.com/mermaid@8.4.0/dist/mermaid.min.js"></script>
diff --git a/root/$mmm/plugins/static/converts: text$moonscript -> table.moon b/root/$mmm/plugins/static/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..e230856
--- /dev/null
+++ b/root/$mmm/plugins/static/converts: text$moonscript -> table.moon
@@ -0,0 +1,34 @@
+if not STATIC
+ return
+
+extensions = {
+ 'image/jpeg': 'jpg'
+ 'image/png': 'png'
+ 'image/svg+xml': 'svg'
+
+ 'video/webm': 'webm'
+ 'video/mp4': 'mp4'
+
+ 'text/javascript': 'js'
+ 'text/css': 'css'
+
+ 'model/gltf-binary': 'glb'
+}
+
+{
+ {
+ inp: '(.+)',
+ out: 'URL -> %1',
+ cost: 5
+ transform: (val, fileder, key) =>
+ escaped_from = @from\gsub '/', '_'
+ if ext = extensions[@from]
+ escaped_from ..= ".#{ext}"
+
+ prefix = STATIC.root or ''
+
+ prefix .. with url = "#{fileder.path}/#{key.name}:#{escaped_from}"
+ print " rendering asset #{url}"
+ STATIC.spit url, val
+ }
+}
diff --git a/root/$mmm/plugins/twitter/converts: text$moonscript -> table.moon b/root/$mmm/plugins/twitter/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..4821823
--- /dev/null
+++ b/root/$mmm/plugins/twitter/converts: text$moonscript -> table.moon
@@ -0,0 +1,21 @@
+import div, blockquote, a from require 'mmm.dom'
+import iframe from require 'mmm.dom'
+
+{
+ {
+ inp: 'URL -> twitter/tweet'
+ out: 'mmm/dom'
+ cost: -4
+ transform: (href) =>
+ user, id = assert (href\match 'twitter.com/([^/]-)/status/(%d*)'), "couldn't parse twitter/tweet URL: '#{href}'"
+
+ iframe {
+ width: 550
+ height: 560
+ border: 0
+ frameBorder: 0
+ allowfullscreen: true
+ src: "//twitframe.com/show?url=https%3A%2F%2Ftwitter.com%2F#{user}%2F#{id}"
+ }
+ }
+}
diff --git a/root/$mmm/plugins/youtube/converts: text$moonscript -> table.moon b/root/$mmm/plugins/youtube/converts: text$moonscript -> table.moon
new file mode 100644
index 0000000..8983730
--- /dev/null
+++ b/root/$mmm/plugins/youtube/converts: text$moonscript -> table.moon
@@ -0,0 +1,25 @@
+import iframe from require 'mmm.dom'
+
+{
+ {
+ inp: 'URL -> youtube/video'
+ out: 'mmm/dom'
+ cost: -4
+ transform: (link) =>
+ id = link\match 'youtu%.be/([^/]+)'
+ id or= link\match 'youtube.com/watch.*[?&]v=([^&]+)'
+ id or= link\match 'youtube.com/[ev]/([^/]+)'
+ id or= link\match 'youtube.com/embed/([^/]+)'
+
+ assert id, "couldn't parse youtube URL: '#{link}'"
+
+ iframe {
+ width: 560
+ height: 315
+ border: 0
+ frameborder: 0
+ allowfullscreen: true
+ src: "//www.youtube.com/embed/#{id}"
+ }
+ }
+}
diff --git a/root/$order b/root/$order
index 23c4745..4d1bfa6 100644
--- a/root/$order
+++ b/root/$order
@@ -6,5 +6,5 @@ games
projects
experiments
meta
-static
portfolio
+static