diff options
| author | s-ol <s+removethis@s-ol.nu> | 2020-12-03 16:38:43 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2020-12-03 16:38:43 +0000 |
| commit | e0a0b25f6586cdf1b1284d97bedadfce5535ba96 (patch) | |
| tree | 50cf646dc673faeda648e7135d84e46f2dbd5262 | |
| parent | fix typo break text/html+interactive (diff) | |
| download | mmm-e0a0b25f6586cdf1b1284d97bedadfce5535ba96.tar.gz mmm-e0a0b25f6586cdf1b1284d97bedadfce5535ba96.zip | |
move plugins into root
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 |
