git.s-ol.nu mmm / 269d998
fix plugins in example root s-ol 4 months ago
11 changed file(s) with 560 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 local div, span, sup, a, i, b
1 do
2 local _obj_0 = require('mmm.dom')
3 div, span, sup, a, i, b = _obj_0.div, _obj_0.span, _obj_0.sup, _obj_0.a, _obj_0.i, _obj_0.b
4 end
5 local parse_bibtex
6 parse_bibtex = function(src)
7 local type, key, kv = src:match('@(%w+){(.-),(.*)}')
8 do
9 local info = {
10 _type = type,
11 _key = key
12 }
13 for key, val in kv:gmatch('([a-z]-)%s*=%s*(%b{})') do
14 val:sub(2, -2)
15 info[key] = val:gsub('[{}]', '')
16 end
17 for key, val in kv:gmatch('([a-z]-)%s*=%s*(%d+)') do
18 info[key] = val
19 end
20 return info
21 end
22 end
23 local title
24 title = function(self)
25 assert(self.title, "cite doesn't have title")
26 local inner = i(self.title)
27 if self.url then
28 return a(inner, {
29 href = self.url,
30 style = {
31 display = 'inline'
32 }
33 })
34 else
35 return b(inner)
36 end
37 end
38 local format_full
39 format_full = function(self)
40 local tt = title(self)
41 local dot, com
42 if self.title:match('[.?!]$') then
43 dot, com = '', ''
44 else
45 dot, com = '.', ','
46 end
47 self.author = self.author or 'N. N.'
48 local _exp_0 = self._type
49 if 'book' == _exp_0 or 'article' == _exp_0 then
50 return span((function()
51 do
52 local _with_0 = setmetatable({ }, {
53 __index = table
54 })
55 _with_0:insert(tostring(self.author) .. " (" .. tostring(self.year) .. "), ")
56 _with_0:insert(tt)
57 if self.journal then
58 _with_0:insert(tostring(dot) .. " ")
59 _with_0:insert(i(self.journal))
60 if self.volume then
61 _with_0:insert(", volume " .. tostring(self.volume))
62 end
63 else
64 if self.series then
65 _with_0:insert(tostring(dot) .. " ")
66 _with_0:insert(i(self.series))
67 if self.number then
68 _with_0:insert(", No. " .. tostring(self.number))
69 end
70 end
71 end
72 if self.pages then
73 _with_0:insert(", pages " .. tostring(self.pages))
74 end
75 if self.publisher then
76 _with_0:insert(tostring(dot) .. " " .. tostring(self.publisher))
77 end
78 if self.doi then
79 _with_0:insert(tostring(dot) .. " ")
80 _with_0:insert(a("doi:" .. tostring(self.doi), {
81 href = "https://doi.org/" .. tostring(self.doi)
82 }))
83 end
84 return _with_0
85 end
86 end)())
87 elseif 'web' == _exp_0 or 'online' == _exp_0 then
88 return span((function()
89 do
90 local _with_0 = setmetatable({ }, {
91 __index = table
92 })
93 _with_0:insert(tostring(self.author))
94 if self.year then
95 _with_0:insert(" (" .. tostring(self.year) .. ")")
96 end
97 _with_0:insert(", ")
98 _with_0:insert(tt)
99 _with_0:insert(tostring(com) .. " " .. tostring(self.url))
100 if self.visited then
101 _with_0:insert(" from " .. tostring(self.visited))
102 end
103 return _with_0
104 end
105 end)())
106 else
107 span((function()
108 do
109 local _with_0 = setmetatable({ }, {
110 __index = table
111 })
112 _with_0:insert(tostring(self.author) .. " (" .. tostring(self.year) .. "), ")
113 _with_0:insert(tt)
114 if self.publisher then
115 _with_0:insert(tostring(dot) .. " " .. tostring(self.publisher))
116 end
117 return _with_0
118 end
119 end)())
120 return span(tbl)
121 end
122 end
123 return {
124 {
125 inp = 'cite/doi',
126 out = 'URL -> text/bibtex',
127 cost = 0.1,
128 transform = function(self, doi)
129 doi = doi:match('(10%.%d%d%d%d%d?%d?%d?%d?%d?/[%d%w%.%-_:;%(%)]+)')
130 return "http://api.crossref.org/works/" .. tostring(doi) .. "/transform/application/x-bibtex"
131 end
132 },
133 {
134 inp = 'text/bibtex',
135 out = 'mmm/dom',
136 cost = 1,
137 transform = function(self, bib)
138 return format_full(parse_bibtex(bib))
139 end
140 }
141 }
0 local pre, div, button
1 do
2 local _obj_0 = require('mmm.dom')
3 pre, div, button = _obj_0.pre, _obj_0.div, _obj_0.button
4 end
5 local languages
6 languages = require('mmm.highlighting').languages
7 local Editor
8 do
9 local _class_0
10 local o
11 local _base_0 = {
12 EDITOR = true,
13 change = function(self)
14 self.timeout = nil
15 local doc = self.cm:getDoc()
16 if self.lastPreview and doc:isClean(self.lastPreview) then
17 return
18 end
19 self.lastPreview = doc:changeGeneration()
20 local value = doc:getValue()
21 self.fileder.facets[self.key] = value
22 return BROWSER:refresh()
23 end,
24 save = function(self, e)
25 e:preventDefault()
26 local doc = self.cm:getDoc()
27 self.fileder:set(self.key, doc:getValue())
28 self.lastSave = doc:changeGeneration(true)
29 end
30 }
31 _base_0.__index = _base_0
32 _class_0 = setmetatable({
33 __init = function(self, value, mode, fileder, key)
34 self.fileder, self.key = fileder, key
35 self.node = div({
36 class = 'editor'
37 })
38 do
39 local _with_0 = button('save')
40 _with_0.disabled = true
41 _with_0.onclick = function(_, e)
42 return self:save(e)
43 end
44 self.saveBtn = _with_0
45 end
46 self.cm = window:CodeMirror(self.node, o({
47 value = value,
48 mode = mode,
49 lineNumber = true,
50 lineWrapping = true,
51 autoRefresh = true,
52 theme = 'hybrid'
53 }))
54 self.lastSave = self.cm:getDoc():changeGeneration(true)
55 return self.cm:on('changes', function(_, mirr)
56 local doc = self.cm:getDoc()
57 self.saveBtn.disabled = doc:isClean(self.lastSave)
58 if self.timeout then
59 window:clearTimeout(self.timeout)
60 end
61 self.timeout = window:setTimeout((function()
62 return self:change()
63 end), 300)
64 end)
65 end,
66 __base = _base_0,
67 __name = "Editor"
68 }, {
69 __index = _base_0,
70 __call = function(cls, ...)
71 local _self_0 = setmetatable({}, _base_0)
72 cls.__init(_self_0, ...)
73 return _self_0
74 end
75 })
76 _base_0.__class = _class_0
77 local self = _class_0
78 if MODE == 'CLIENT' then
79 local mkobj = window:eval("(function () { return {}; })")
80 o = function(tbl)
81 do
82 local obj = mkobj()
83 for k, v in pairs(tbl) do
84 obj[k] = v
85 end
86 return obj
87 end
88 end
89 end
90 Editor = _class_0
91 end
92 local _ = [[ editors: if MODE == 'CLIENT' then {
93 {
94 inp: 'text/([^ ]*).*'
95 out: 'mmm/dom'
96 cost: 0
97 transform: (value, fileder, key) =>
98 mode = @from\match @convert.inp
99 Editor value, mode, fileder, key
100 }
101 {
102 inp: 'URL.*'
103 out: 'mmm/dom'
104 cost: 0
105 transform: (value, fileder, key) =>
106 Editor value, nil, fileder, key
107 }
108 }
109 ]]
110 return {
111 {
112 inp = 'text/([^ ]*).*',
113 out = 'mmm/dom',
114 cost = 5,
115 transform = function(self, val)
116 local lang = self.from:match(self.convert.inp)
117 return pre(languages[lang](val))
118 end
119 }
120 }
0 local tourl
1 tourl = (require('mmm.mmmfs.util'))({ }).tourl
2 return function(self)
3 return "\n <link rel=\"stylesheet\" type=\"text/css\" href=\"" .. tostring(self:gett('style: URL -> text/css')) .. "\" />" .. [[<!--
4 <link rel="stylesheet" type="text/css" href="//unpkg.com/codemirror@5.49.2/lib/codemirror.css" />
5 <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/lib/codemirror.js"></script>
6 <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/mode/lua/lua.js"></script>
7 <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/mode/markdown/markdown.js"></script>
8 <script type="text/javascript" src="//unpkg.com/codemirror@5.49.2/addon/display/autorefresh.js"></script>
9 -->
10 ]]
11 end
0 local dom = require('mmm.dom')
1 return {
2 {
3 inp = 'URL -> model/gltf-binary',
4 out = 'mmm/dom',
5 cost = 1,
6 transform = function(self, href)
7 return dom['model-viewer']({
8 src = href,
9 ['auto-rotate'] = true,
10 ['camera-controls'] = true,
11 ['camera-orbit'] = "548.2deg 117deg 282.4m"
12 })
13 end
14 }
15 }
0 local markdown
1 if MODE == 'SERVER' then
2 local success, discount = pcall(require, 'discount')
3 assert(success, "couldn't require 'discount'")
4 markdown = function(md)
5 local res = assert(discount.compile(md, 'githubtags', 'fencedcode'))
6 return res.body
7 end
8 else
9 assert(window and window.marked, "marked.js not found")
10 local o
11 do
12 local mkobj = window:eval("(function () { return {}; })")
13 o = function(tbl)
14 do
15 local obj = mkobj()
16 for k, v in pairs(tbl) do
17 obj[k] = v
18 end
19 return obj
20 end
21 end
22 end
23 local trim
24 trim = function(str)
25 return str:match('^ *(..-) *$')
26 end
27 window.marked:setOptions(o({
28 gfm = true,
29 smartypants = true,
30 langPrefix = 'lang-',
31 highlight = function(self, code, lang)
32 code = trim(code)
33 local result
34 if lang and #lang > 0 then
35 result = window.hljs:highlight(lang, code, true)
36 else
37 result = window.hljs:highlightAuto(code)
38 end
39 return result.value
40 end
41 }))
42 do
43 local _base_0 = window
44 local _fn_0 = _base_0.marked
45 markdown = function(...)
46 return _fn_0(_base_0, ...)
47 end
48 end
49 end
50 assert(markdown, "no markdown implementation found")
51 return {
52 {
53 inp = 'text/markdown',
54 out = 'text/html+frag',
55 cost = 1,
56 transform = function(self, md)
57 return "<div class=\"markdown\">" .. tostring(markdown(md)) .. "</div>"
58 end
59 },
60 {
61 inp = 'text/markdown%+sidenotes',
62 out = 'text/html+frag',
63 cost = 1,
64 transform = function(self, md)
65 return "<div class=\"markdown sidenote-container\">" .. tostring(markdown(md)) .. "</div>"
66 end
67 },
68 {
69 inp = 'text/markdown%+wide',
70 out = 'text/html+frag',
71 cost = 1,
72 transform = function(self, md)
73 return "<div class=\"markdown wide\">" .. tostring(markdown(md)) .. "</div>"
74 end
75 },
76 {
77 inp = 'text/markdown%+span',
78 out = 'text/html+frag',
79 cost = 1,
80 transform = function(self, source)
81 local html = markdown(source)
82 html = html:gsub('^%s*<p>%s*', '<span>')
83 html = html:gsub('%s*</p>%s*$', '</span>')
84 return html
85 end
86 }
87 }
0 if not (window and window.mermaid) then
1 return
2 end
3 window.mermaid:initialize({
4 startOnLoad = false,
5 fontFamily = 'monospace'
6 })
7 local id_counter = 1
8 return {
9 {
10 inp = 'text/mermaid-graph',
11 out = 'mmm/dom',
12 cost = 1,
13 transform = function(self, source, fileder, key)
14 id_counter = id_counter + 1
15 local id = "mermaid-" .. tostring(id_counter)
16 do
17 local container = document:createElement('div')
18 local cb
19 cb = function(self, svg)
20 container.innerHTML = svg
21 container.firstElementChild.style.width = '100%'
22 container.firstElementChild.style.height = 'auto'
23 end
24 window:setImmediate(function(_)
25 return window.mermaid:render(id, source, cb, container)
26 end)
27 return container
28 end
29 end
30 }
31 }
0 if MODE == 'CLIENT' then
1 return { }
2 end
3 local _, moon = assert(pcall(require, 'moonscript.base'))
4 local _load = moon.load or moon.loadstring
5 return {
6 {
7 inp = 'text/moonscript -> (.+)',
8 out = '%1',
9 cost = 1,
10 transform = function(self, val, fileder, key)
11 local func = _load(val, tostring(fileder) .. "#" .. tostring(key))
12 return func()
13 end
14 },
15 {
16 inp = 'text/moonscript -> (.+)',
17 out = 'text/lua -> %1',
18 cost = 2,
19 transform = function(self, val)
20 return moon.to_lua(val)
21 end
22 }
23 }
0 if MODE == 'CLIENT'
1 return {}
2
3 _, moon = assert pcall require, 'moonscript.base'
4 _load = moon.load or moon.loadstring
5
6 {
7 {
8 inp: 'text/moonscript -> (.+)',
9 out: '%1',
10 cost: 1
11 transform: (val, fileder, key) =>
12 func = _load val, "#{fileder}##{key}"
13 func!
14 },
15 {
16 inp: 'text/moonscript -> (.+)',
17 out: 'text/lua -> %1',
18 cost: 2
19 transform: (val) => moon.to_lua val
20 },
21 }
0 if MODE == 'CLIENT' then
1 return { }
2 end
3 local posix = require('posix')
4 return {
5 {
6 inp = 'text/x-scss',
7 out = 'text/css',
8 cost = 1,
9 transform = function(self, content)
10 local r0, w0 = posix.pipe()
11 local r1, w1 = posix.pipe()
12 local r2, w2 = posix.pipe()
13 local pid = assert(posix.fork())
14 if pid == 0 then
15 posix.close(w0)
16 posix.close(r1)
17 posix.close(r2)
18 posix.dup2(r0, posix.fileno(io.stdin))
19 posix.dup2(w1, posix.fileno(io.stdout))
20 posix.dup2(w2, posix.fileno(io.stderr))
21 posix.close(r0)
22 posix.close(w1)
23 posix.close(w2)
24 local err = assert(posix.execp('sassc', '-s'))
25 posix._exit(err)
26 return
27 else
28 posix.close(r0)
29 posix.close(w1)
30 posix.close(w2)
31 posix.write(w0, content)
32 posix.close(w0)
33 local _, status
34 _, _, status = posix.wait(pid)
35 local out
36 if status == 0 then
37 out = r1
38 else
39 out = r2
40 end
41 out = assert(posix.fdopen(out, 'r'))
42 out = out:read('a')
43 posix.close(r1)
44 posix.close(r2)
45 if status == 0 then
46 return out
47 else
48 return error(out)
49 end
50 end
51 end
52 }
53 }
0 local div, blockquote, a
1 do
2 local _obj_0 = require('mmm.dom')
3 div, blockquote, a = _obj_0.div, _obj_0.blockquote, _obj_0.a
4 end
5 local iframe
6 iframe = require('mmm.dom').iframe
7 return {
8 {
9 inp = 'URL -> twitter/tweet',
10 out = 'mmm/dom',
11 cost = -4,
12 transform = function(self, href)
13 local user, id = assert((href:match('twitter.com/([^/]-)/status/(%d*)')), "couldn't parse twitter/tweet URL: '" .. tostring(href) .. "'")
14 return iframe({
15 width = 550,
16 height = 560,
17 border = 0,
18 frameBorder = 0,
19 allowfullscreen = true,
20 src = "//twitframe.com/show?url=https%3A%2F%2Ftwitter.com%2F" .. tostring(user) .. "%2F" .. tostring(id)
21 })
22 end
23 }
24 }
0 local iframe
1 iframe = require('mmm.dom').iframe
2 return {
3 {
4 inp = 'URL -> youtube/video',
5 out = 'mmm/dom',
6 cost = -4,
7 transform = function(self, link)
8 local id = link:match('youtu%.be/([^/]+)')
9 id = id or link:match('youtube.com/watch.*[?&]v=([^&]+)')
10 id = id or link:match('youtube.com/[ev]/([^/]+)')
11 id = id or link:match('youtube.com/embed/([^/]+)')
12 assert(id, "couldn't parse youtube URL: '" .. tostring(link) .. "'")
13 return iframe({
14 width = 560,
15 height = 315,
16 border = 0,
17 frameborder = 0,
18 allowfullscreen = true,
19 src = "//www.youtube.com/embed/" .. tostring(id)
20 })
21 end
22 }
23 }