diff options
| author | s-ol <s+removethis@s-ol.nu> | 2022-05-08 19:14:58 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2022-05-20 08:38:41 +0000 |
| commit | b615a7cf0fc9d81b4b905a9d4e1db0beebdebd3d (patch) | |
| tree | 2bf24f2da1aa80df2534637de10e0fe45aeb80f0 /$mmm/plugins | |
| download | hw.s-ol.nu-b615a7cf0fc9d81b4b905a9d4e1db0beebdebd3d.tar.gz hw.s-ol.nu-b615a7cf0fc9d81b4b905a9d4e1db0beebdebd3d.zip | |
initial commit
Diffstat (limited to '$mmm/plugins')
19 files changed, 1098 insertions, 0 deletions
diff --git a/$mmm/plugins/code/converts: text$lua -> table.lua b/$mmm/plugins/code/converts: text$lua -> table.lua new file mode 100644 index 0000000..c578a69 --- /dev/null +++ b/$mmm/plugins/code/converts: text$lua -> table.lua @@ -0,0 +1,121 @@ +local pre, div, button +do + local _obj_0 = require('mmm.dom') + pre, div, button = _obj_0.pre, _obj_0.div, _obj_0.button +end +local languages +languages = require('mmm.highlighting').languages +local Editor +do + local _class_0 + local o + local _base_0 = { + EDITOR = true, + change = function(self) + self.timeout = nil + local doc = self.cm:getDoc() + if self.lastPreview and doc:isClean(self.lastPreview) then + return + end + self.lastPreview = doc:changeGeneration() + local value = doc:getValue() + self.fileder.facets[self.key] = value + return BROWSER:refresh() + end, + save = function(self, e) + e:preventDefault() + local doc = self.cm:getDoc() + self.fileder:set(self.key, doc:getValue()) + self.lastSave = doc:changeGeneration(true) + end + } + _base_0.__index = _base_0 + _class_0 = setmetatable({ + __init = function(self, value, mode, fileder, key) + self.fileder, self.key = fileder, key + self.node = div({ + class = 'editor' + }) + do + local _with_0 = button('save') + _with_0.disabled = true + _with_0.onclick = function(_, e) + return self:save(e) + end + self.saveBtn = _with_0 + end + self.cm = window:CodeMirror(self.node, o({ + value = value, + mode = mode, + lineNumber = true, + lineWrapping = true, + autoRefresh = true, + theme = 'hybrid' + })) + self.lastSave = self.cm:getDoc():changeGeneration(true) + return self.cm:on('changes', function(_, mirr) + local doc = self.cm:getDoc() + self.saveBtn.disabled = doc:isClean(self.lastSave) + if self.timeout then + window:clearTimeout(self.timeout) + end + self.timeout = window:setTimeout((function() + return self:change() + end), 300) + end) + end, + __base = _base_0, + __name = "Editor" + }, { + __index = _base_0, + __call = function(cls, ...) + local _self_0 = setmetatable({}, _base_0) + cls.__init(_self_0, ...) + return _self_0 + end + }) + _base_0.__class = _class_0 + local self = _class_0 + if MODE == 'CLIENT' then + local mkobj = window:eval("(function () { return {}; })") + o = function(tbl) + do + local obj = mkobj() + for k, v in pairs(tbl) do + obj[k] = v + end + return obj + end + end + end + Editor = _class_0 +end +local _ = [[ 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 + } + } +]] +return { + { + inp = 'text/([^ ]*).*', + out = 'mmm/dom', + cost = 5, + transform = function(self, val) + local lang = self.from:match(self.convert.inp) + return pre(languages[lang](val)) + end + } +} diff --git a/$mmm/plugins/code/converts: text$moonscript -> table.moon b/$mmm/plugins/code/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..851efba --- /dev/null +++ b/$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/$mmm/plugins/code/scripts: text$lua -> fn -> text$html+frag.lua b/$mmm/plugins/code/scripts: text$lua -> fn -> text$html+frag.lua new file mode 100644 index 0000000..87a182f --- /dev/null +++ b/$mmm/plugins/code/scripts: text$lua -> fn -> text$html+frag.lua @@ -0,0 +1,12 @@ +local tourl +tourl = (require('mmm.mmmfs.util'))({ }).tourl +return function(self) + return "\n <link rel=\"stylesheet\" type=\"text/css\" href=\"" .. tostring(self:gett('style: URL -> text/css')) .. "\" />" .. [[<!-- + <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> +--> + ]] +end diff --git a/$mmm/plugins/code/scripts: text$moonscript -> fn -> text$html+frag.moon b/$mmm/plugins/code/scripts: text$moonscript -> fn -> text$html+frag.moon new file mode 100644 index 0000000..9799ac6 --- /dev/null +++ b/$mmm/plugins/code/scripts: text$moonscript -> fn -> text$html+frag.moon @@ -0,0 +1,14 @@ +import tourl from (require 'mmm.mmmfs.util') {} + +=> + " + <link rel=\"stylesheet\" type=\"text/css\" href=\"#{@gett 'style: URL -> text/css'}\" />" .. + [[ +<!-- + <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/$mmm/plugins/code/style: text$css.css b/$mmm/plugins/code/style: text$css.css new file mode 100644 index 0000000..0acf4a2 --- /dev/null +++ b/$mmm/plugins/code/style: text$css.css @@ -0,0 +1,110 @@ +/* + +vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid) + +*/ + +/*background color*/ +.hljs { + background: #1d1f21; + border-radius: 6px; + padding: 0.2em 0.5em; + white-space: nowrap; +} + +pre > .hljs { + display: block; + overflow-x: auto; + padding: 1em; + white-space: pre-wrap; + margin: 0 2em; +} + +/*selection color*/ +.hljs::selection, +.hljs span::selection { + background: #373b41; +} + +.hljs::-moz-selection, +.hljs span::-moz-selection { + background: #373b41; +} + +/*foreground color*/ +.hljs { + color: #c5c8c6; +} + +/*color: fg_yellow*/ +.hljs-title, +.hljs-name { + color: #f0c674; +} + +/*color: fg_comment*/ +.hljs-comment, +.hljs-meta, +.hljs-meta .hljs-keyword { + color: #707880; +} + +/*color: fg_red*/ +.hljs-number, +.hljs-symbol, +.hljs-literal, +.hljs-deletion, +.hljs-link { + color: #cc6666 +} + +/*color: fg_green*/ +.hljs-string, +.hljs-doctag, +.hljs-addition, +.hljs-regexp, +.hljs-selector-attr, +.hljs-selector-pseudo { + color: #b5bd68; +} + +/*color: fg_purple*/ +.hljs-attribute, +.hljs-code, +.hljs-selector-id { + color: #b294bb; +} + +/*color: fg_blue*/ +.hljs-keyword, +.hljs-selector-tag, +.hljs-bullet, +.hljs-tag { + color: #81a2be; +} + +/*color: fg_aqua*/ +.hljs-subst, +.hljs-variable, +.hljs-template-tag, +.hljs-template-variable { + color: #8abeb7; +} + +/*color: fg_orange*/ +.hljs-type, +.hljs-built_in, +.hljs-builtin-name, +.hljs-quote, +.hljs-section, +.hljs-selector-class { + color: #de935f; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} diff --git a/$mmm/plugins/gltf/converts: text$lua -> table.lua b/$mmm/plugins/gltf/converts: text$lua -> table.lua new file mode 100644 index 0000000..5a7869f --- /dev/null +++ b/$mmm/plugins/gltf/converts: text$lua -> table.lua @@ -0,0 +1,16 @@ +local dom = require('mmm.dom') +return { + { + inp = 'URL -> model/gltf-binary', + out = 'mmm/dom', + cost = 1, + transform = function(self, href) + return dom['model-viewer']({ + src = href, + ['auto-rotate'] = true, + ['camera-controls'] = true, + ['camera-orbit'] = "548.2deg 117deg 282.4m" + }) + end + } +} diff --git a/$mmm/plugins/gltf/converts: text$moonscript -> table.moon b/$mmm/plugins/gltf/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..1036eee --- /dev/null +++ b/$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/$mmm/plugins/gltf/scripts: text$html+frag.html b/$mmm/plugins/gltf/scripts: text$html+frag.html new file mode 100644 index 0000000..d2b1e44 --- /dev/null +++ b/$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/plugins/layout/converts: text$lua -> table.lua b/$mmm/plugins/layout/converts: text$lua -> table.lua new file mode 100644 index 0000000..2acf8b7 --- /dev/null +++ b/$mmm/plugins/layout/converts: text$lua -> table.lua @@ -0,0 +1,193 @@ +local header, aside, footer, nav, div, svg, script, g, path, ul, li, h1, span, b, a, img +do + local _obj_0 = require('mmm.dom') + header, aside, footer, nav, div, svg, script, g, path, ul, li, h1, span, b, a, img = _obj_0.header, _obj_0.aside, _obj_0.footer, _obj_0.nav, _obj_0.div, _obj_0.svg, _obj_0.script, _obj_0.g, _obj_0.path, _obj_0.ul, _obj_0.li, _obj_0.h1, _obj_0.span, _obj_0.b, _obj_0.a, _obj_0.img +end +local navigate_to +navigate_to = (require('mmm.mmmfs.util'))(require('mmm.dom')).navigate_to +local get_plugins +get_plugins = require('mmm.mmmfs.meta').get_plugins +local unpack = unpack or table.unpack +local pick +pick = function(...) + local num = select('#', ...) + local i = math.ceil(math.random() * num) + return (select(i, ...)) +end +local iconlink +iconlink = function(href, src, alt, style) + return a({ + class = 'iconlink', + target = '_blank', + rel = 'me', + href = href, + img({ + src = src, + alt = alt, + style = style + }) + }) +end +local logo = svg({ + class = 'sun', + viewBox = '0 0 1 1', + xmlns = 'http://www.w3.org/2000/svg', + baseProfile = 'full', + version = '1.1', + g({ + transform = 'translate(0.5, 0.52)', + g({ + class = 'circle out', + path({ + fill = 'none', + ['stroke-width'] = 0.053, + d = 'M 0.5 0.15625 C 0.44839986 0.15625 0.22697194 0.28343797 0.20117188 0.328125 C 0.17537181 0.37281203 0.1753718 0.62718797 0.20117188 0.671875 C 0.22697195 0.71656203 0.44839986 0.84375 0.5 0.84375 C 0.55160014 0.84375 0.77302806 0.71656203 0.79882812 0.671875 C 0.82462819 0.62718797 0.8246282 0.37281203 0.79882812 0.328125 C 0.77302805 0.28343797 0.55160014 0.15625 0.5 0.15625 z', + transform = 'translate(-0.5, -0.5)' + }) + }), + g({ + class = 'circle in', + path({ + stroke = 'none', + d = 'M 0.50195312 0.38476562 C 0.4851293 0.38476563 0.41466191 0.42683639 0.40625 0.44140625 C 0.39783809 0.45597611 0.39783809 0.53816452 0.40625 0.55273438 C 0.41466191 0.56730423 0.4851293 0.609375 0.50195312 0.609375 C 0.51877695 0.609375 0.59119746 0.56730423 0.59960938 0.55273438 C 0.60802129 0.53816452 0.60802129 0.45597611 0.59960938 0.44140625 C 0.59119746 0.42683639 0.51877695 0.38476562 0.50195312 0.38476562 z', + transform = 'translate(-0.5, -0.5)' + }) + }) + }) +}) +local gen_header +gen_header = function(self) + return header({ + div({ + h1({ + navigate_to('', logo), + span({ + span('kb', { + class = 'bold' + }), + '​', + '.s‑ol.nu' + }) + }), + "low-profile hexagon keyboards." + }) + }) +end +footer = footer({ + span({ + 'made with \xe2\x98\xbd by ', + a('s-ol', { + href = 'https://s-ol.nu' + }), + ", " .. tostring(os.date('%Y')) + }), + div({ + class = 'icons', + iconlink('https://github.com/s-ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg', 'github'), + iconlink('https://merveilles.town/@s_ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mastodon.svg', 'mastodon'), + iconlink('https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg', 'twitter') + }) +}) +local get_header_tags +get_header_tags = function(self) + local title = (self:get('title: text/plain')) or self:gett('name: alpha') + local l + l = function(str) + str = str:gsub('[%s\n]+$', '') + return str:gsub('\n', ' ') + end + local e + e = function(str) + return string.format('%q', l(str)) + end + local meta = "\n <meta charset=\"UTF-8\">\n <title>" .. tostring(l(title)) .. "</title>\n " + do + local page_meta = self:get('_meta: mmm/dom') + if page_meta then + meta = meta .. page_meta + else + meta = meta .. "\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n <meta property=\"og:title\" content=" .. tostring(e(title)) .. " />\n <meta property=\"og:type\" content=\"website\" />\n <meta property=\"og:url\" content=\"https://kb.s-ol.nu" .. tostring(self.path) .. "/\" />\n <meta property=\"og:site_name\" content=\"mmm\" />" + do + local desc = self:get('description: text/plain') + if desc then + meta = meta .. "\n <meta property=\"og:description\" content=" .. tostring(e(desc)) .. " />" + end + end + end + end + return meta +end +local get_scripts +get_scripts = function(self) + local scripts = '' + for plugin in get_plugins(self) do + do + local snippet = plugin:get('scripts: text/html+frag') + if snippet then + scripts = scripts .. snippet + end + end + end + return scripts +end +local render +render = function(content, fileder, opts) + if opts == nil then + opts = { } + end + opts.meta = opts.meta or get_header_tags(fileder) + opts.scripts = opts.scripts or '' + if not (opts.noview) then + content = [[ <div class="view main"> + <div class="content"> + ]] .. content .. [[ </div> + </div> + ]] + end + local buf = [[<!DOCTYPE html> +<html> + <head>]] + buf = buf .. (function() + if STATIC then + return STATIC.style + else + return "<link rel=\"stylesheet\" type=\"text/css\" href=\"/static/style/:text/css\" />" + end + end)() + buf = buf .. [[<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />]] + buf = buf .. "\n " .. tostring(opts.meta) .. "\n " .. tostring(get_scripts(fileder)) .. "\n </head>\n <body>\n " .. tostring(gen_header(fileder)) .. "\n\n " .. tostring(content) .. "\n\n " .. tostring(footer) + buf = buf .. (function() + if STATIC then + return '' + else + return [[ <script type="text/javascript" src="/static/highlight-pack/:text/javascript"></script> + <script type="text/javascript">hljs.initHighlighting()</script>]] + end + end)() + buf = buf .. opts.scripts + if STATIC then + buf = buf .. STATIC.scripts + end + buf = buf .. "\n </body>\n</html>" + return buf +end +return { + { + inp = 'mmm/dom', + out = 'text/html', + cost = 3, + transform = function(self, html, fileder) + return render(html, fileder) + end + }, + { + inp = 'mmm/dom%+noview', + out = 'text/html', + cost = 3, + transform = function(self, html, fileder) + return render(html, fileder, { + noview = true + }) + end + } +} diff --git a/$mmm/plugins/layout/converts: text$moonscript -> table.moon b/$mmm/plugins/layout/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..cde34a4 --- /dev/null +++ b/$mmm/plugins/layout/converts: text$moonscript -> table.moon @@ -0,0 +1,164 @@ +import header, aside, footer, nav, div, svg, script, g, path, ul, li, h1, span, b, a, img from require 'mmm.dom' +import navigate_to from (require 'mmm.mmmfs.util') require 'mmm.dom' +import get_plugins from require 'mmm.mmmfs.meta' + +unpack or= table.unpack + +pick = (...) -> + num = select '#', ... + i = math.ceil math.random! * num + (select i, ...) + +iconlink = (href, src, alt, style) -> a { + class: 'iconlink', + target: '_blank', + rel: 'me', + :href, + img :src, :alt, :style +} + +logo = svg { + class: 'sun' + viewBox: '0 0 1 1' + xmlns: 'http://www.w3.org/2000/svg' + baseProfile: 'full' + version: '1.1' + + g { + transform: 'translate(0.5, 0.52)' + g { + class: 'circle out', + path fill: 'none', 'stroke-width': 0.053, d: 'M 0.5 0.15625 C 0.44839986 0.15625 0.22697194 0.28343797 0.20117188 0.328125 C 0.17537181 0.37281203 0.1753718 0.62718797 0.20117188 0.671875 C 0.22697195 0.71656203 0.44839986 0.84375 0.5 0.84375 C 0.55160014 0.84375 0.77302806 0.71656203 0.79882812 0.671875 C 0.82462819 0.62718797 0.8246282 0.37281203 0.79882812 0.328125 C 0.77302805 0.28343797 0.55160014 0.15625 0.5 0.15625 z', transform: 'translate(-0.5, -0.5)' + } + + g { + class: 'circle in', + path stroke: 'none', d: 'M 0.50195312 0.38476562 C 0.4851293 0.38476563 0.41466191 0.42683639 0.40625 0.44140625 C 0.39783809 0.45597611 0.39783809 0.53816452 0.40625 0.55273438 C 0.41466191 0.56730423 0.4851293 0.609375 0.50195312 0.609375 C 0.51877695 0.609375 0.59119746 0.56730423 0.59960938 0.55273438 C 0.60802129 0.53816452 0.60802129 0.45597611 0.59960938 0.44140625 C 0.59119746 0.42683639 0.51877695 0.38476562 0.50195312 0.38476562 z', transform: 'translate(-0.5, -0.5)' + } + } +} + +gen_header = => + header { + div { + h1 { + navigate_to '', logo + span { + span 'kb', class: 'bold' + '​' + '.s‑ol.nu' + } + } + "low-profile hexagon keyboards." + }, + } + +footer = footer { + span { + 'made with \xe2\x98\xbd by ' + a 's-ol', href: 'https://s-ol.nu' + ", #{os.date '%Y'}" + } + div { + class: 'icons', + iconlink 'https://github.com/s-ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg', 'github' + iconlink 'https://merveilles.town/@s_ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mastodon.svg', 'mastodon' + iconlink 'https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg', 'twitter' + } +} + +get_header_tags = => + title = (@get 'title: text/plain') or @gett 'name: alpha' + + l = (str) -> + str = str\gsub '[%s\n]+$', '' + str\gsub '\n', ' ' + e = (str) -> string.format '%q', l str + + meta = " + <meta charset=\"UTF-8\"> + <title>#{l title}</title> + " + + if page_meta = @get '_meta: mmm/dom' + meta ..= page_meta + else + meta ..= " + <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> + + <meta property=\"og:title\" content=#{e title} /> + <meta property=\"og:type\" content=\"website\" /> + <meta property=\"og:url\" content=\"https://kb.s-ol.nu#{@path}/\" /> + <meta property=\"og:site_name\" content=\"mmm\" />" + + if desc = @get 'description: text/plain' + meta ..= " + <meta property=\"og:description\" content=#{e desc} />" + + meta + +get_scripts = => + scripts = '' + for plugin in get_plugins @ + if snippet = plugin\get 'scripts: text/html+frag' + scripts ..= snippet + + scripts + +render = (content, fileder, opts={}) -> + opts.meta or= get_header_tags fileder + opts.scripts or= '' + + unless opts.noview + content = [[ + <div class="view main"> + <div class="content"> + ]] .. content .. [[ + </div> + </div> + ]] + + buf = [[ +<!DOCTYPE html> +<html> + <head>]] + buf ..= if STATIC then STATIC.style else "<link rel=\"stylesheet\" type=\"text/css\" href=\"/static/style/:text/css\" />" + buf ..= [[<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />]] + buf ..= " + #{opts.meta} + #{get_scripts fileder} + </head> + <body> + #{gen_header fileder} + + #{content} + + #{footer}" + buf ..= if STATIC then '' else [[ + <script type="text/javascript" src="/static/highlight-pack/:text/javascript"></script> + <script type="text/javascript">hljs.initHighlighting()</script>]] + + buf ..= opts.scripts + buf ..= STATIC.scripts if STATIC + buf ..= " + </body> +</html>" + + buf + +{ + { + -- inp: 'text/html%+frag', + -- @TODO: this doesn't feel right... maybe mmm/dom has to go? + inp: 'mmm/dom', + out: 'text/html', + cost: 3 + transform: (html, fileder) => render html, fileder + }, + { + inp: 'mmm/dom%+noview', + out: 'text/html', + cost: 3 + transform: (html, fileder) => render html, fileder, noview: true + } +} diff --git a/$mmm/plugins/markdown/converts: text$lua -> table.lua b/$mmm/plugins/markdown/converts: text$lua -> table.lua new file mode 100644 index 0000000..5d33b62 --- /dev/null +++ b/$mmm/plugins/markdown/converts: text$lua -> table.lua @@ -0,0 +1,88 @@ +local markdown +if MODE == 'SERVER' then + local success, discount = pcall(require, 'discount') + assert(success, "couldn't require 'discount'") + markdown = function(md) + local res = assert(discount.compile(md, 'githubtags', 'fencedcode')) + return res.body + end +else + assert(window and window.marked, "marked.js not found") + local o + do + local mkobj = window:eval("(function () { return {}; })") + o = function(tbl) + do + local obj = mkobj() + for k, v in pairs(tbl) do + obj[k] = v + end + return obj + end + end + end + local trim + trim = function(str) + return str:match('^ *(..-) *$') + end + window.marked:setOptions(o({ + gfm = true, + smartypants = true, + langPrefix = 'lang-', + highlight = function(self, code, lang) + code = trim(code) + local result + if lang and #lang > 0 then + result = window.hljs:highlight(lang, code, true) + else + result = window.hljs:highlightAuto(code) + end + return result.value + end + })) + do + local _base_0 = window + local _fn_0 = _base_0.marked + markdown = function(...) + return _fn_0(_base_0, ...) + end + end +end +assert(markdown, "no markdown implementation found") +return { + { + inp = 'text/markdown', + out = 'text/html+frag', + cost = 1, + transform = function(self, md) + return "<div class=\"markdown\">" .. tostring(markdown(md)) .. "</div>" + end + }, + { + inp = 'text/markdown%+sidenotes', + out = 'text/html+frag', + cost = 1, + transform = function(self, md) + return "<div class=\"markdown sidenote-container\">" .. tostring(markdown(md)) .. "</div>" + end + }, + { + inp = 'text/markdown%+wide', + out = 'text/html+frag', + cost = 1, + transform = function(self, md) + return "<div class=\"markdown wide\">" .. tostring(markdown(md)) .. "</div>" + end + }, + { + inp = 'text/markdown%+span', + out = 'text/html+frag', + cost = 1, + transform = function(self, source) + local html = markdown(source) + html = html:gsub('^%s*<p>%s*', '<span>') + html = html:gsub('%s*</p>%s*$', '</span>') + return html + end + } +} diff --git a/$mmm/plugins/markdown/converts: text$moonscript -> table.moon b/$mmm/plugins/markdown/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..4e0da31 --- /dev/null +++ b/$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/$mmm/plugins/markdown/scripts: text$html+frag.html b/$mmm/plugins/markdown/scripts: text$html+frag.html new file mode 100644 index 0000000..5bfb275 --- /dev/null +++ b/$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/$mmm/plugins/moonscript/converts: text$lua -> table.lua b/$mmm/plugins/moonscript/converts: text$lua -> table.lua new file mode 100644 index 0000000..1ac91b4 --- /dev/null +++ b/$mmm/plugins/moonscript/converts: text$lua -> table.lua @@ -0,0 +1,24 @@ +if MODE == 'CLIENT' then + return { } +end +local _, moon = assert(pcall(require, 'moonscript.base')) +local _load = moon.load or moon.loadstring +return { + { + inp = 'text/moonscript -> (.+)', + out = '%1', + cost = 1, + transform = function(self, val, fileder, key) + local func = _load(val, tostring(fileder) .. "#" .. tostring(key)) + return func() + end + }, + { + inp = 'text/moonscript -> (.+)', + out = 'text/lua -> %1', + cost = 2, + transform = function(self, val) + return moon.to_lua(val) + end + } +} diff --git a/$mmm/plugins/moonscript/converts: text$moonscript -> table.moon b/$mmm/plugins/moonscript/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..2e5652c --- /dev/null +++ b/$mmm/plugins/moonscript/converts: text$moonscript -> table.moon @@ -0,0 +1,22 @@ +if MODE == 'CLIENT' + return {} + +_, moon = assert pcall require, 'moonscript.base' +_load = moon.load or moon.loadstring + +{ + { + inp: 'text/moonscript -> (.+)', + out: '%1', + cost: 1 + transform: (val, fileder, key) => + func = _load val, "#{fileder}##{key}" + func! + }, + { + inp: 'text/moonscript -> (.+)', + out: 'text/lua -> %1', + cost: 2 + transform: (val) => moon.to_lua val + }, +} diff --git a/$mmm/plugins/sass/converts: text$lua -> table.lua b/$mmm/plugins/sass/converts: text$lua -> table.lua new file mode 100644 index 0000000..f2887e3 --- /dev/null +++ b/$mmm/plugins/sass/converts: text$lua -> table.lua @@ -0,0 +1,54 @@ +if MODE == 'CLIENT' then + return { } +end +local posix = require('posix') +return { + { + inp = 'text/x-scss', + out = 'text/css', + cost = 1, + transform = function(self, content) + local r0, w0 = posix.pipe() + local r1, w1 = posix.pipe() + local r2, w2 = posix.pipe() + local pid = assert(posix.fork()) + if pid == 0 then + posix.close(w0) + posix.close(r1) + posix.close(r2) + posix.dup2(r0, posix.fileno(io.stdin)) + posix.dup2(w1, posix.fileno(io.stdout)) + posix.dup2(w2, posix.fileno(io.stderr)) + posix.close(r0) + posix.close(w1) + posix.close(w2) + local err = assert(posix.execp('sassc', '-s')) + posix._exit(err) + return + else + posix.close(r0) + posix.close(w1) + posix.close(w2) + posix.write(w0, content) + posix.close(w0) + local _, status + _, _, status = posix.wait(pid) + local out + if status == 0 then + out = r1 + else + out = r2 + end + out = assert(posix.fdopen(out, 'r')) + out = out:read('a') + posix.close(r1) + posix.close(r2) + if status == 0 then + return out + else + return error(out) + end + end + end + } +} diff --git a/$mmm/plugins/sass/converts: text$moonscript -> table.moon b/$mmm/plugins/sass/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..e353c53 --- /dev/null +++ b/$mmm/plugins/sass/converts: text$moonscript -> table.moon @@ -0,0 +1,55 @@ +if MODE == 'CLIENT' + return {} + +posix = require 'posix' + +{ + { + inp: 'text/x-scss' + out: 'text/css' + cost: 1 + transform: (content) => + r0, w0 = posix.pipe! + r1, w1 = posix.pipe! + r2, w2 = posix.pipe! + + pid = assert posix.fork! + if pid == 0 + posix.close w0 + posix.close r1 + posix.close r2 + + posix.dup2 r0, posix.fileno io.stdin + posix.dup2 w1, posix.fileno io.stdout + posix.dup2 w2, posix.fileno io.stderr + + posix.close r0 + posix.close w1 + posix.close w2 + + err = assert posix.execp 'sassc', '-s' + posix._exit err + return + else + posix.close r0 + posix.close w1 + posix.close w2 + + posix.write w0, content + posix.close w0 + + _, _, status = posix.wait pid + + out = if status == 0 then r1 else r2 + out = assert posix.fdopen out, 'r' + out = out\read 'a' + + posix.close r1 + posix.close r2 + + if status == 0 + out + else + error out + } +} diff --git a/$mmm/plugins/youtube/converts: text$lua -> table.lua b/$mmm/plugins/youtube/converts: text$lua -> table.lua new file mode 100644 index 0000000..de5b8a8 --- /dev/null +++ b/$mmm/plugins/youtube/converts: text$lua -> table.lua @@ -0,0 +1,24 @@ +local iframe +iframe = require('mmm.dom').iframe +return { + { + inp = 'URL -> youtube/video', + out = 'mmm/dom', + cost = -4, + transform = function(self, link) + local id = link:match('youtu%.be/([^/]+)') + id = id or link:match('youtube.com/watch.*[?&]v=([^&]+)') + id = id or link:match('youtube.com/[ev]/([^/]+)') + id = id or link:match('youtube.com/embed/([^/]+)') + assert(id, "couldn't parse youtube URL: '" .. tostring(link) .. "'") + return iframe({ + width = 560, + height = 315, + border = 0, + frameborder = 0, + allowfullscreen = true, + src = "//www.youtube.com/embed/" .. tostring(id) + }) + end + } +} diff --git a/$mmm/plugins/youtube/converts: text$moonscript -> table.moon b/$mmm/plugins/youtube/converts: text$moonscript -> table.moon new file mode 100644 index 0000000..8983730 --- /dev/null +++ b/$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}" + } + } +} |
