git.s-ol.nu mmm / 6e568c6
move layout into user content s-ol 1 year, 2 months ago
5 changed file(s) with 391 addition(s) and 178 deletion(s). Raw diff Collapse all Expand all
1414 import dir_base, Key, Fileder from require 'mmm.mmmfs.fileder'
1515 import convert, MermaidDebugger from require 'mmm.mmmfs.conversion'
1616 import get_store from require 'mmm.mmmfs.stores'
17 import render from require 'mmm.mmmfs.layout'
1817 import Browser from require 'mmm.mmmfs.browser'
1918 import init_cache from require 'mmm.mmmfs.cache'
2019 import decodeURI from require 'http.util'
6261 root = @root or Fileder @store
6362 browser = Browser root, fileder.path, facet.name
6463
65 render browser\todom!, fileder, noview: true, scripts: "
64 scripts = "
6665 <script type=\"text/javascript\" src=\"//cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.6/svg.min.js\"></script>
6766 <script type=\"text/javascript\" src=\"/static/fengari-web/:text/javascript\"></script>
6867 <script type=\"text/lua\" src=\"/static/mmm/:text/lua\"></script>
8483 if not ok then error(browser) end
8584 end)
8685 </script>"
86 convert 'mmm/dom+noview', 'text/html', scripts .. browser\todom!, fileder, facet.name
8787
8888 handle_debug: (fileder, facet) =>
8989 debugger = MermaidDebugger!
00 import div, pre, code, img, video, span, source from require 'mmm.dom'
11 import find_fileder, link_to, embed from (require 'mmm.mmmfs.util') require 'mmm.dom'
2 import render from require 'mmm.mmmfs.layout'
32 import tohtml from require 'mmm.component'
43
54 -- fix JS null values
6968 out: 'text/html+frag',
7069 cost: 3
7170 transform: (node) => if MODE == 'SERVER' then node else node.outerHTML
72 }
73 {
74 -- inp: 'text/html%+frag',
75 -- @TODO: this doesn't feel right... maybe mmm/dom has to go?
76 inp: 'mmm/dom',
77 out: 'text/html',
78 cost: 3
79 transform: (html, fileder) => render html, fileder
8071 }
8172 {
8273 inp: 'text/html%+frag',
+0
-167
mmm/mmmfs/layout.moon less more
0 import header, aside, footer, div, svg, script, g, circle, h1, span, b, a, img from require 'mmm.dom'
1 import navigate_to from (require 'mmm.mmmfs.util') require 'mmm.dom'
2 import get_plugins from require 'mmm.mmmfs.meta'
3
4 pick = (...) ->
5 num = select '#', ...
6 i = math.ceil math.random! * num
7 (select i, ...)
8
9 iconlink = (href, src, alt, style) -> a {
10 class: 'iconlink',
11 target: '_blank',
12 rel: 'me',
13 :href,
14 img :src, :alt, :style
15 }
16
17 logo = svg {
18 class: 'sun'
19 viewBox: '-0.75 -1 1.5 2'
20 xmlns: 'http://www.w3.org/2000/svg'
21 baseProfile: 'full'
22 version: '1.1'
23
24 g {
25 transform: 'translate(0 .18)'
26
27 g { class: 'circle out', circle r: '.6', fill: 'none', 'stroke-width': '.12' }
28 g { class: 'circle in', circle r: '.2', stroke: 'none' }
29 }
30 }
31
32 gen_header = ->
33 header {
34 div {
35 h1 {
36 navigate_to '', logo
37 span {
38 span 'mmm', class: 'bold'
39 '&#8203;'
40 '.s&#8209;ol.nu'
41 }
42 }
43 -- span "fun stuff with code and wires"
44 table.concat {
45 pick 'fun', 'cool', 'weird', 'interesting', 'new', 'pleasant'
46 pick 'stuff', 'things', 'projects', 'experiments', 'visuals', 'ideas'
47 pick "with", 'and'
48 pick 'mostly code', 'code and wires', 'silicon', 'electronics', 'shaders',
49 'oscilloscopes', 'interfaces', 'hardware', 'FPGAs'
50 }, ' '
51 }
52 aside {
53 navigate_to '/about', 'about me'
54 navigate_to '/portfolio', 'portfolio'
55 navigate_to '/games', 'games'
56 navigate_to '/projects', 'other'
57 a {
58 href: 'mailto:s%20[removethis]%20[at]%20s-ol.nu'
59 'contact'
60 script "
61 var l = document.currentScript.parentElement;
62 l.href = l.href.replace('%20[at]%20', '@');
63 l.href = l.href.replace('%20[removethis]', '') + '?subject=Hey there :)';
64 "
65 }
66 }
67 }
68
69 footer = footer {
70 span {
71 'made with \xe2\x98\xbd by '
72 a 's-ol', href: 'https://twitter.com/S0lll0s'
73 ", #{os.date '%Y'}"
74 }
75 div {
76 class: 'icons',
77 iconlink 'https://github.com/s-ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg', 'github'
78 iconlink 'https://merveilles.town/@s_ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mastodon.svg', 'mastodon'
79 iconlink 'https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg', 'twitter'
80 iconlink 'https://webring.xxiivv.com/#random', 'https://webring.xxiivv.com/icon.black.svg', 'webring',
81 { height: '1.3em', 'margin-left': '.3em', 'margin-top': '-0.12em' }
82 }
83 }
84
85 get_header_tags = =>
86 title = (@get 'title: text/plain') or @gett 'name: alpha'
87
88 l = (str) ->
89 str = str\gsub '[%s\n]+$', ''
90 str\gsub '\n', ' '
91 e = (str) -> string.format '%q', l str
92
93 meta = "
94 <meta charset=\"UTF-8\">
95 <title>#{l title}</title>
96 "
97
98 if page_meta = @get '_meta: mmm/dom'
99 meta ..= page_meta
100 else
101 meta ..= "
102 <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
103
104 <meta property=\"og:title\" content=#{e title} />
105 <meta property=\"og:type\" content=\"website\" />
106 <meta property=\"og:url\" content=\"https://mmm.s-ol.nu#{@path}/\" />
107 <meta property=\"og:site_name\" content=\"mmm\" />"
108
109 if desc = @get 'description: text/plain'
110 meta ..= "
111 <meta property=\"og:description\" content=#{e desc} />"
112
113 meta
114
115 get_scripts = =>
116 scripts = ''
117 for plugin in get_plugins @
118 if snippet = plugin\get 'scripts: text/html+frag'
119 scripts ..= snippet
120
121 scripts
122
123 render = (content, fileder, opts={}) ->
124 opts.meta or= get_header_tags fileder
125 opts.scripts or= ''
126
127 unless opts.noview
128 content = [[
129 <div class="view main">
130 <div class="content">
131 ]] .. content .. [[
132 </div>
133 </div>
134 ]]
135
136 buf = [[
137 <!DOCTYPE html>
138 <html>
139 <head>]]
140 buf ..= if STATIC then STATIC.style else [[<link rel="stylesheet" type="text/css" href="/static/style/:text/css" />]]
141 buf ..= [[<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />]]
142 buf ..= "
143 #{opts.meta}
144 #{get_scripts fileder}
145 </head>
146 <body>
147 #{gen_header!}
148
149 #{content}
150
151 #{footer}"
152 buf ..= if STATIC then '' else [[
153 <script type="text/javascript" src="/static/highlight-pack/:text/javascript"></script>
154 <script type="text/javascript">hljs.initHighlighting()</script>]]
155
156 buf ..= opts.scripts
157 buf ..= STATIC.scripts if STATIC
158 buf ..= "
159 </body>
160 </html>"
161
162 buf
163
164 {
165 :render
166 }
0 local header, aside, footer, div, svg, script, g, circle, h1, span, b, a, img
1 do
2 local _obj_0 = require('mmm.dom')
3 header, aside, footer, div, svg, script, g, circle, h1, span, b, a, img = _obj_0.header, _obj_0.aside, _obj_0.footer, _obj_0.div, _obj_0.svg, _obj_0.script, _obj_0.g, _obj_0.circle, _obj_0.h1, _obj_0.span, _obj_0.b, _obj_0.a, _obj_0.img
4 end
5 local navigate_to
6 navigate_to = (require('mmm.mmmfs.util'))(require('mmm.dom')).navigate_to
7 local get_plugins
8 get_plugins = require('mmm.mmmfs.meta').get_plugins
9 local pick
10 pick = function(...)
11 local num = select('#', ...)
12 local i = math.ceil(math.random() * num)
13 return (select(i, ...))
14 end
15 local iconlink
16 iconlink = function(href, src, alt, style)
17 return a({
18 class = 'iconlink',
19 target = '_blank',
20 rel = 'me',
21 href = href,
22 img({
23 src = src,
24 alt = alt,
25 style = style
26 })
27 })
28 end
29 local logo = svg({
30 class = 'sun',
31 viewBox = '-0.75 -1 1.5 2',
32 xmlns = 'http://www.w3.org/2000/svg',
33 baseProfile = 'full',
34 version = '1.1',
35 g({
36 transform = 'translate(0 .18)',
37 g({
38 class = 'circle out',
39 circle({
40 r = '.6',
41 fill = 'none',
42 ['stroke-width'] = '.12'
43 })
44 }),
45 g({
46 class = 'circle in',
47 circle({
48 r = '.2',
49 stroke = 'none'
50 })
51 })
52 })
53 })
54 local gen_header
55 gen_header = function()
56 return header({
57 div({
58 h1({
59 navigate_to('', logo),
60 span({
61 span('mmm', {
62 class = 'bold'
63 }),
64 '&#8203;',
65 '.s&#8209;ol.nu'
66 })
67 }),
68 table.concat({
69 pick('fun', 'cool', 'weird', 'interesting', 'new', 'pleasant'),
70 pick('stuff', 'things', 'projects', 'experiments', 'visuals', 'ideas'),
71 pick("with", 'and'),
72 pick('mostly code', 'code and wires', 'silicon', 'electronics', 'shaders', 'oscilloscopes', 'interfaces', 'hardware', 'FPGAs')
73 }, ' ')
74 }),
75 aside({
76 navigate_to('/about', 'about me'),
77 navigate_to('/portfolio', 'portfolio'),
78 navigate_to('/games', 'games'),
79 navigate_to('/projects', 'other'),
80 a({
81 href = 'mailto:s%20[removethis]%20[at]%20s-ol.nu',
82 'contact',
83 script("\n var l = document.currentScript.parentElement;\n l.href = l.href.replace('%20[at]%20', '@');\n l.href = l.href.replace('%20[removethis]', '') + '?subject=Hey there :)';\n ")
84 })
85 })
86 })
87 end
88 footer = footer({
89 span({
90 'made with \xe2\x98\xbd by ',
91 a('s-ol', {
92 href = 'https://twitter.com/S0lll0s'
93 }),
94 ", " .. tostring(os.date('%Y'))
95 }),
96 div({
97 class = 'icons',
98 iconlink('https://github.com/s-ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg', 'github'),
99 iconlink('https://merveilles.town/@s_ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mastodon.svg', 'mastodon'),
100 iconlink('https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg', 'twitter'),
101 iconlink('https://webring.xxiivv.com/#random', 'https://webring.xxiivv.com/icon.black.svg', 'webring', {
102 height = '1.3em',
103 ['margin-left'] = '.3em',
104 ['margin-top'] = '-0.12em'
105 })
106 })
107 })
108 local get_header_tags
109 get_header_tags = function(self)
110 local title = (self:get('title: text/plain')) or self:gett('name: alpha')
111 local l
112 l = function(str)
113 str = str:gsub('[%s\n]+$', '')
114 return str:gsub('\n', ' ')
115 end
116 local e
117 e = function(str)
118 return string.format('%q', l(str))
119 end
120 local meta = "\n <meta charset=\"UTF-8\">\n <title>" .. tostring(l(title)) .. "</title>\n "
121 do
122 local page_meta = self:get('_meta: mmm/dom')
123 if page_meta then
124 meta = meta .. page_meta
125 else
126 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://mmm.s-ol.nu" .. tostring(self.path) .. "/\" />\n <meta property=\"og:site_name\" content=\"mmm\" />"
127 do
128 local desc = self:get('description: text/plain')
129 if desc then
130 meta = meta .. "\n <meta property=\"og:description\" content=" .. tostring(e(desc)) .. " />"
131 end
132 end
133 end
134 end
135 return meta
136 end
137 local get_scripts
138 get_scripts = function(self)
139 local scripts = ''
140 for plugin in get_plugins(self) do
141 do
142 local snippet = plugin:get('scripts: text/html+frag')
143 if snippet then
144 scripts = scripts .. snippet
145 end
146 end
147 end
148 return scripts
149 end
150 local render
151 render = function(content, fileder, opts)
152 if opts == nil then
153 opts = { }
154 end
155 opts.meta = opts.meta or get_header_tags(fileder)
156 opts.scripts = opts.scripts or ''
157 if not (opts.noview) then
158 content = [[ <div class="view main">
159 <div class="content">
160 ]] .. content .. [[ </div>
161 </div>
162 ]]
163 end
164 local buf = [[<!DOCTYPE html>
165 <html>
166 <head>]]
167 buf = buf .. (function()
168 if STATIC then
169 return STATIC.style
170 else
171 return [[<link rel="stylesheet" type="text/css" href="/static/style/:text/css" />]]
172 end
173 end)()
174 buf = buf .. [[<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />]]
175 buf = buf .. "\n " .. tostring(opts.meta) .. "\n " .. tostring(get_scripts(fileder)) .. "\n </head>\n <body>\n " .. tostring(gen_header()) .. "\n\n " .. tostring(content) .. "\n\n " .. tostring(footer)
176 buf = buf .. (function()
177 if STATIC then
178 return ''
179 else
180 return [[ <script type="text/javascript" src="/static/highlight-pack/:text/javascript"></script>
181 <script type="text/javascript">hljs.initHighlighting()</script>]]
182 end
183 end)()
184 buf = buf .. opts.scripts
185 if STATIC then
186 buf = buf .. STATIC.scripts
187 end
188 buf = buf .. "\n </body>\n</html>"
189 return buf
190 end
191 return {
192 {
193 inp = 'mmm/dom',
194 out = 'text/html',
195 cost = 3,
196 transform = function(self, html, fileder)
197 return render(html, fileder)
198 end
199 },
200 {
201 inp = 'mmm/dom%+noview',
202 out = 'text/html',
203 cost = 3,
204 transform = function(self, html, fileder)
205 return render(html, fileder, { noview = true })
206 end
207 }
208 }
0 import header, aside, footer, div, svg, script, g, circle, h1, span, b, a, img from require 'mmm.dom'
1 import navigate_to from (require 'mmm.mmmfs.util') require 'mmm.dom'
2 import get_plugins from require 'mmm.mmmfs.meta'
3
4 pick = (...) ->
5 num = select '#', ...
6 i = math.ceil math.random! * num
7 (select i, ...)
8
9 iconlink = (href, src, alt, style) -> a {
10 class: 'iconlink',
11 target: '_blank',
12 rel: 'me',
13 :href,
14 img :src, :alt, :style
15 }
16
17 logo = svg {
18 class: 'sun'
19 viewBox: '-0.75 -1 1.5 2'
20 xmlns: 'http://www.w3.org/2000/svg'
21 baseProfile: 'full'
22 version: '1.1'
23
24 g {
25 transform: 'translate(0 .18)'
26
27 g { class: 'circle out', circle r: '.6', fill: 'none', 'stroke-width': '.12' }
28 g { class: 'circle in', circle r: '.2', stroke: 'none' }
29 }
30 }
31
32 gen_header = ->
33 header {
34 div {
35 h1 {
36 navigate_to '', logo
37 span {
38 span 'mmm', class: 'bold'
39 '&#8203;'
40 '.s&#8209;ol.nu'
41 }
42 }
43 -- span "fun stuff with code and wires"
44 table.concat {
45 pick 'fun', 'cool', 'weird', 'interesting', 'new', 'pleasant'
46 pick 'stuff', 'things', 'projects', 'experiments', 'visuals', 'ideas'
47 pick "with", 'and'
48 pick 'mostly code', 'code and wires', 'silicon', 'electronics', 'shaders',
49 'oscilloscopes', 'interfaces', 'hardware', 'FPGAs'
50 }, ' '
51 }
52 aside {
53 navigate_to '/about', 'about me'
54 navigate_to '/portfolio', 'portfolio'
55 navigate_to '/games', 'games'
56 navigate_to '/projects', 'other'
57 a {
58 href: 'mailto:s%20[removethis]%20[at]%20s-ol.nu'
59 'contact'
60 script "
61 var l = document.currentScript.parentElement;
62 l.href = l.href.replace('%20[at]%20', '@');
63 l.href = l.href.replace('%20[removethis]', '') + '?subject=Hey there :)';
64 "
65 }
66 }
67 }
68
69 footer = footer {
70 span {
71 'made with \xe2\x98\xbd by '
72 a 's-ol', href: 'https://twitter.com/S0lll0s'
73 ", #{os.date '%Y'}"
74 }
75 div {
76 class: 'icons',
77 iconlink 'https://github.com/s-ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/github.svg', 'github'
78 iconlink 'https://merveilles.town/@s_ol', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/mastodon.svg', 'mastodon'
79 iconlink 'https://twitter.com/S0lll0s', 'https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/twitter.svg', 'twitter'
80 iconlink 'https://webring.xxiivv.com/#random', 'https://webring.xxiivv.com/icon.black.svg', 'webring',
81 { height: '1.3em', 'margin-left': '.3em', 'margin-top': '-0.12em' }
82 }
83 }
84
85 get_header_tags = =>
86 title = (@get 'title: text/plain') or @gett 'name: alpha'
87
88 l = (str) ->
89 str = str\gsub '[%s\n]+$', ''
90 str\gsub '\n', ' '
91 e = (str) -> string.format '%q', l str
92
93 meta = "
94 <meta charset=\"UTF-8\">
95 <title>#{l title}</title>
96 "
97
98 if page_meta = @get '_meta: mmm/dom'
99 meta ..= page_meta
100 else
101 meta ..= "
102 <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
103
104 <meta property=\"og:title\" content=#{e title} />
105 <meta property=\"og:type\" content=\"website\" />
106 <meta property=\"og:url\" content=\"https://mmm.s-ol.nu#{@path}/\" />
107 <meta property=\"og:site_name\" content=\"mmm\" />"
108
109 if desc = @get 'description: text/plain'
110 meta ..= "
111 <meta property=\"og:description\" content=#{e desc} />"
112
113 meta
114
115 get_scripts = =>
116 scripts = ''
117 for plugin in get_plugins @
118 if snippet = plugin\get 'scripts: text/html+frag'
119 scripts ..= snippet
120
121 scripts
122
123 render = (content, fileder, opts={}) ->
124 opts.meta or= get_header_tags fileder
125 opts.scripts or= ''
126
127 unless opts.noview
128 content = [[
129 <div class="view main">
130 <div class="content">
131 ]] .. content .. [[
132 </div>
133 </div>
134 ]]
135
136 buf = [[
137 <!DOCTYPE html>
138 <html>
139 <head>]]
140 buf ..= if STATIC then STATIC.style else [[<link rel="stylesheet" type="text/css" href="/static/style/:text/css" />]]
141 buf ..= [[<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,600" />]]
142 buf ..= "
143 #{opts.meta}
144 #{get_scripts fileder}
145 </head>
146 <body>
147 #{gen_header!}
148
149 #{content}
150
151 #{footer}"
152 buf ..= if STATIC then '' else [[
153 <script type="text/javascript" src="/static/highlight-pack/:text/javascript"></script>
154 <script type="text/javascript">hljs.initHighlighting()</script>]]
155
156 buf ..= opts.scripts
157 buf ..= STATIC.scripts if STATIC
158 buf ..= "
159 </body>
160 </html>"
161
162 buf
163
164 {
165 {
166 -- inp: 'text/html%+frag',
167 -- @TODO: this doesn't feel right... maybe mmm/dom has to go?
168 inp: 'mmm/dom',
169 out: 'text/html',
170 cost: 3
171 transform: (html, fileder) => render html, fileder
172 },
173 {
174 inp: 'mmm/dom%+noview',
175 out: 'text/html',
176 cost: 3
177 transform: (html, fileder) => render html, fileder, noview: true
178 }
179 }