aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2019-09-21 13:34:39 +0000
committers-ol <s-ol@users.noreply.github.com>2019-09-21 13:34:39 +0000
commitfcff21bb78214790041cfc189c5c0c18a88b6d9e (patch)
treec63304302792b3a290b034ce3a0ca3b4902efeb0
parentfix code font (diff)
downloadmmm-fcff21bb78214790041cfc189c5c0c18a88b6d9e.tar.gz
mmm-fcff21bb78214790041cfc189c5c0c18a88b6d9e.zip
add btrktrl, parallax_panels
-rw-r--r--mmm/dom/init.server.moon6
-rw-r--r--mmm/mmmfs/browser.moon241
-rw-r--r--mmm/mmmfs/conversion.moon31
-rw-r--r--root/experiments/parallax_panels/description: text$plain1
-rw-r--r--root/experiments/parallax_panels/picture/URL -> twitter$tweet1
-rw-r--r--root/experiments/parallax_panels/text$markdown.md16
-rwxr-xr-xroot/experiments/parallax_panels/viewer/demo/video$mp4.mp4bin0 -> 8699675 bytes
-rw-r--r--root/experiments/parallax_panels/viewer/link: URL1
-rw-r--r--root/projects/btrktrl/$order13
-rw-r--r--root/projects/btrktrl/description: text$plain1
-rw-r--r--root/projects/btrktrl/knobs_all/description: text$plain1
-rw-r--r--root/projects/btrktrl/knobs_all/image$jpeg.jpgbin0 -> 2462470 bytes
-rw-r--r--root/projects/btrktrl/knobs_testing/description: text$plain1
-rw-r--r--root/projects/btrktrl/knobs_testing/image$jpeg.jpgbin0 -> 2266946 bytes
-rw-r--r--root/projects/btrktrl/pcb_dev_configuration/description: text$plain1
-rw-r--r--root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4bin0 -> 7002917 bytes
-rw-r--r--root/projects/btrktrl/pcb_dev_encoder/description: text$plain1
-rw-r--r--root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4bin0 -> 3094492 bytes
-rw-r--r--root/projects/btrktrl/pcb_glamour/image$jpeg.jpgbin0 -> 935947 bytes
-rw-r--r--root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpgbin0 -> 331299 bytes
-rw-r--r--root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpgbin0 -> 320858 bytes
-rw-r--r--root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpgbin0 -> 681312 bytes
-rw-r--r--root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpgbin0 -> 448678 bytes
-rw-r--r--root/projects/btrktrl/pcb_osc/description: text$plain1
-rw-r--r--root/projects/btrktrl/pcb_osc/video$mp4.mp4bin0 -> 8287372 bytes
-rw-r--r--root/projects/btrktrl/proto_encoder/description: text$plain1
-rw-r--r--root/projects/btrktrl/proto_encoder/video$mp4.mp4bin0 -> 3362613 bytes
-rw-r--r--root/projects/btrktrl/proto_rgb/description: text$plain1
-rw-r--r--root/projects/btrktrl/proto_rgb/video$mp4.mp4bin0 -> 1247898 bytes
-rw-r--r--root/projects/btrktrl/proto_spi/description: text$plain1
-rw-r--r--root/projects/btrktrl/proto_spi/image$jpeg.jpgbin0 -> 2441610 bytes
-rw-r--r--root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon62
-rw-r--r--scss/_content.scss5
33 files changed, 142 insertions, 244 deletions
diff --git a/mmm/dom/init.server.moon b/mmm/dom/init.server.moon
index fedd109..2ddce33 100644
--- a/mmm/dom/init.server.moon
+++ b/mmm/dom/init.server.moon
@@ -27,6 +27,12 @@ element = (element) -> (...) ->
if #children == 0
children = attributes
+ for i,v in ipairs children
+ if 'string' != type v
+ print v
+ error "wrong type: #{type v}"
+ children[i] = '' unless v
+
if void_tags[element]
assert #children == 0, "void tag #{element} cannot have children!"
b .. ">"
diff --git a/mmm/mmmfs/browser.moon b/mmm/mmmfs/browser.moon
deleted file mode 100644
index 379537e..0000000
--- a/mmm/mmmfs/browser.moon
+++ /dev/null
@@ -1,241 +0,0 @@
-require = relative ..., 1
-import Key from require '.fileder'
-import converts, get_conversions, apply_conversions from require '.conversion'
-import ReactiveVar, get_or_create, text, elements from require 'mmm.component'
-import pre, div, nav, span, button, a, select, option from elements
-import languages from require 'mmm.highlighting'
-
-keep = (var) ->
- last = var\get!
- var\map (val) ->
- last = val or last
- last
-
-code_cast = (lang) ->
- {
- inp: "text/#{lang}.*",
- out: 'mmm/dom',
- transform: (val) -> languages[lang] val
- }
-
-casts = {
- code_cast 'javascript',
- code_cast 'moonscript',
- code_cast 'lua',
- code_cast 'markdown',
- code_cast 'html',
- {
- inp: 'text/plain'
- out: 'mmm/dom'
- transform: (val) -> text val
- }
-}
-
-for convert in *converts
- table.insert casts, convert
-
-class Browser
- new: (@root, path='', rehydrate=false) =>
- -- root fileder
- assert @root, 'root fileder is nil'
-
- -- active path
- @path = ReactiveVar path
-
- -- update URL bar
- if MODE == 'CLIENT'
- logo = document\querySelector 'header h1 > svg'
- spin = ->
- logo.classList\add 'spin'
- logo.parentElement.offsetWidth
- logo.classList\remove 'spin'
- @path\subscribe (path) ->
- document.body.classList\add 'loading'
- spin!
-
- return if @skip
- vis_path = path .. (if '/' == path\sub -1 then '' else '/')
- window.history\pushState path, '', vis_path
-
- window.onpopstate = (_, event) ->
- if event.state
- @skip = true
- @path\set event.state
- @skip = nil
-
- -- active fileder
- -- (re)set every time @path changes
- @active = @path\map @root\walk
-
- -- currently active facet
- -- (re)set to default when @active changes
- @facet = @active\map (fileder) ->
- return unless fileder
- last = @facet and @facet\get!
- Key if last then last.type else 'mmm/dom'
-
- -- whether inspect tab is active
- @inspect = ReactiveVar (MODE == 'CLIENT' and window.location.search\match '[?&]inspect')
-
- -- retrieve or create the wrapper and main elements
- main = get_or_create 'div', 'browser-root', class: 'main view'
-
- -- prepend the navbar
- if MODE == 'SERVER'
- main\append nav { id: 'browser-navbar', span 'please stand by... interactivity loading :)' }
- else
- main\prepend with get_or_create 'nav', 'browser-navbar'
- .node.innerHTML = ''
- \append span 'path: ', @path\map (path) -> with div class: 'path', style: { display: 'inline-block' }
- path_segment = (name, href) ->
- a name, :href, onclick: (_, e) ->
- e\preventDefault!
- @navigate href
-
- href = ''
- path = path\match '^/(.*)'
-
- \append path_segment 'root', ''
-
- while path
- name, rest = path\match '^([%w%-_%.]+)/(.*)'
- if not name
- name = path
-
- path = rest
- href = "#{href}/#{name}"
-
- \append '/'
- \append path_segment name, href
-
- \append span 'view facet:', style: { 'margin-right': '0' }
- \append @active\map (fileder) ->
- onchange = (_, e) ->
- { :type } = @facet\get!
- @facet\set Key name: e.target.value, :type
-
- current = @facet\get!
- current = current and current.name
- with select :onchange, disabled: not fileder
- has_main = fileder and fileder\find current.name, '.*'
- \append option '(main)', value: '', disabled: not has_main, selected: current == ''
- if fileder
- for i, value in ipairs fileder\get_facets!
- continue if value == ''
- \append option value, :value, selected: value == current
- \append @inspect\map (enabled) ->
- if not enabled
- button 'inspect', onclick: (_, e) -> @inspect\set true
-
- @error = ReactiveVar!
- main\append with get_or_create 'div', 'browser-error', class: @error\map (e) -> if e then 'error-wrap' else 'error-wrap empty'
- \append (span "an error occured while rendering this view:"), (rehydrate and .node.firstChild)
- \append @error
-
- -- append or patch #browser-content
- main\append with get_or_create 'div', 'browser-content', class: 'content'
- content = ReactiveVar if rehydrate then .node.lastChild else @get_content @facet\get!
- \append keep content
- if MODE == 'CLIENT'
- @facet\subscribe (p) ->
- window\setTimeout (-> content\set @get_content p), 150
-
- if rehydrate
- -- force one rerender to set onclick handlers etc
- @facet\set @facet\get!
-
- inspector = @inspect\map (enabled) -> if enabled then @get_inspector!
-
- -- export mmm/component interface
- wrapper = get_or_create 'div', 'browser-wrapper', main, inspector, class: 'browser'
- @node = wrapper.node
- @render = wrapper\render
-
- err_and_trace = (err) -> err, debug.traceback!
- default_convert = (key) => @get key.name, 'mmm/dom'
-
- -- render #browser-content
- get_content: (prop, err=@error, convert=default_convert) =>
- clear_error = ->
- err\set! if MODE == 'CLIENT'
- disp_error = (msg) ->
- if MODE == 'CLIENT'
- err\set pre msg
- warn "ERROR rendering content: #{msg}"
- nil
-
- active = @active\get!
-
- return disp_error "fileder not found!" unless active
- return disp_error "facet not found!" unless prop
-
- ok, res, trace = xpcall convert, err_and_trace, active, prop
-
- document.body.classList\remove 'loading' if MODE == 'CLIENT'
-
- if ok and res
- clear_error!
- res
- elseif ok
- div "[no conversion path to #{prop.type}]"
- elseif res and res.match and res\match '%[nossr%]$'
- div "[this page could not be pre-rendered on the server]"
- else
- if trace
- res = "#{res}\n#{trace}"
- disp_error res
-
- get_inspector: =>
- -- active facet in inspect tab
- -- (re)set to match when @facet changes
- @inspect_prop = @facet\map (prop) ->
- active = @active\get!
- key = active and active\find prop
- key = key.original if key and key.original
- key
-
- @inspect_err = ReactiveVar!
-
- with div class: 'view inspector'
- \append nav {
- span 'inspector'
- @inspect_prop\map (current) ->
- current = current and current\tostring!
- fileder = @active\get!
-
- onchange = (_, e) ->
- return if e.target.value == ''
- { :name } = @facet\get!
- @inspect_prop\set Key e.target.value
-
- with select :onchange
- \append option '(none)', value: '', disabled: true, selected: not value
- if fileder
- for key, _ in pairs fileder.facets
- value = key\tostring!
- \append option value, :value, selected: value == current
- @inspect\map (enabled) ->
- if enabled
- button 'close', onclick: (_, e) -> @inspect\set false
- }
- \append with div class: @inspect_err\map (e) -> if e then 'error-wrap' else 'error-wrap empty'
- \append span "an error occured while rendering this view:"
- \append @inspect_err
- \append with pre class: 'content'
- \append keep @inspect_prop\map (prop, old) ->
- @get_content prop, @inspect_err, (prop) =>
- value, key = @get prop
- assert key, "couldn't @get #{prop}"
-
- conversions = get_conversions 'mmm/dom', key.type, casts
- assert conversions, "cannot cast '#{key.type}'"
- apply_conversions conversions, value, @, prop
-
- default_convert = (key) => @get key.name, 'mmm/dom'
-
- navigate: (new) =>
- @path\set new
-
-{
- :Browser
-}
diff --git a/mmm/mmmfs/conversion.moon b/mmm/mmmfs/conversion.moon
index a37ee0b..dc301eb 100644
--- a/mmm/mmmfs/conversion.moon
+++ b/mmm/mmmfs/conversion.moon
@@ -1,5 +1,5 @@
import div, code, img, video, blockquote, a, span, source, iframe from require 'mmm.dom'
-import find_fileder, embed from (require 'mmm.mmmfs.util') require 'mmm.dom'
+import find_fileder, link_to, embed from (require 'mmm.mmmfs.util') require 'mmm.dom'
import tohtml from require 'mmm.component'
-- fix JS null values
@@ -42,7 +42,24 @@ converts = {
out: 'mmm/dom',
transform: if MODE == 'SERVER'
(html, fileder) ->
- html\gsub '<mmm%-embed%s+(.-)></mmm%-embed>', (attrs) ->
+ html = html\gsub '<mmm%-link%s+(.-)>(.-)</mmm%-link>', (attrs, text) ->
+ text = nil if #text == 0
+ path = ''
+ while attrs and attrs != ''
+ key, val, _attrs = attrs\match '^(%w+)="([^"]-)"%s*(.*)'
+ if not key
+ key, _attrs = attrs\match '^(%w+)%s*(.*)$'
+ val = true
+
+ attrs = _attrs
+
+ switch key
+ when 'path' then path = val
+ else warn "unkown attribute '#{key}=\"#{val}\"' in <mmm-link>"
+
+ link_to path, text, fileder
+
+ html = html\gsub '<mmm%-embed%s+(.-)></mmm%-embed>', (attrs) ->
path, facet = '', ''
opts = {}
while attrs and attrs != ''
@@ -60,6 +77,8 @@ converts = {
else warn "unkown attribute '#{key}=\"#{val}\"' in <mmm-embed>"
embed path, facet, fileder, opts
+
+ html
else
(html, fileder) ->
parent = with document\createElement 'div'
@@ -75,6 +94,14 @@ converts = {
element\replaceWith embed path or '', facet or '', fileder, { :nolink }
+ embeds = \getElementsByTagName 'mmm-link'
+ embeds = [embeds[i] for i=0, embeds.length - 1]
+ for element in *embeds
+ text = js_fix element.innerText
+ path = js_fix element\getAttribute 'path'
+
+ element\replaceWith link_to path or '', text, fileder
+
assert 1 == parent.childElementCount, "text/html with more than one child!"
parent.firstElementChild
},
diff --git a/root/experiments/parallax_panels/description: text$plain b/root/experiments/parallax_panels/description: text$plain
new file mode 100644
index 0000000..0eed9db
--- /dev/null
+++ b/root/experiments/parallax_panels/description: text$plain
@@ -0,0 +1 @@
+A Parallax SVG Viewer, for Prototyping (Eurorack) Panels
diff --git a/root/experiments/parallax_panels/picture/URL -> twitter$tweet b/root/experiments/parallax_panels/picture/URL -> twitter$tweet
new file mode 100644
index 0000000..8d5bce2
--- /dev/null
+++ b/root/experiments/parallax_panels/picture/URL -> twitter$tweet
@@ -0,0 +1 @@
+https://twitter.com/S0lll0s/status/1141006444793405440
diff --git a/root/experiments/parallax_panels/text$markdown.md b/root/experiments/parallax_panels/text$markdown.md
new file mode 100644
index 0000000..7453762
--- /dev/null
+++ b/root/experiments/parallax_panels/text$markdown.md
@@ -0,0 +1,16 @@
+parallax-panels
+===============
+
+I'm prototyping an aesthetic for (eurorack) panels that relies on multiple layers of parallax visuals for dramatic effect.
+
+<mmm-embed path="picture" nolink></mmm-embed>
+
+parallax-viewer
+===============
+
+I built a little SVG viewer that stacks the layers and lets you view them in parallax.
+You can find it <mmm-link path="viewer">here</mmm-link>.
+
+And here's a little demonstration:
+
+<mmm-embed path="viewer/demo" nolink></mmm-embed>
diff --git a/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4 b/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4
new file mode 100755
index 0000000..f3600cc
--- /dev/null
+++ b/root/experiments/parallax_panels/viewer/demo/video$mp4.mp4
Binary files differ
diff --git a/root/experiments/parallax_panels/viewer/link: URL b/root/experiments/parallax_panels/viewer/link: URL
new file mode 100644
index 0000000..f1bc92e
--- /dev/null
+++ b/root/experiments/parallax_panels/viewer/link: URL
@@ -0,0 +1 @@
+https://codepen.io/s-ol/full/rExrey
diff --git a/root/projects/btrktrl/$order b/root/projects/btrktrl/$order
new file mode 100644
index 0000000..0520d1b
--- /dev/null
+++ b/root/projects/btrktrl/$order
@@ -0,0 +1,13 @@
+proto_rgb
+proto_encoder
+proto_spi
+knobs_all
+knobs_testing
+pcb_glamour_close
+pcb_glamour_far
+pcb_glamour_top
+pcb_glamour
+pcb_glamour_connector
+pcb_dev_configuration
+pcb_dev_encoder
+pcb_osc
diff --git a/root/projects/btrktrl/description: text$plain b/root/projects/btrktrl/description: text$plain
new file mode 100644
index 0000000..d7e3402
--- /dev/null
+++ b/root/projects/btrktrl/description: text$plain
@@ -0,0 +1 @@
+a FPGA-based modular MIDI/OSC control surface
diff --git a/root/projects/btrktrl/knobs_all/description: text$plain b/root/projects/btrktrl/knobs_all/description: text$plain
new file mode 100644
index 0000000..1a43de0
--- /dev/null
+++ b/root/projects/btrktrl/knobs_all/description: text$plain
@@ -0,0 +1 @@
+sampling machined aluminum knobs from chinese supplier
diff --git a/root/projects/btrktrl/knobs_all/image$jpeg.jpg b/root/projects/btrktrl/knobs_all/image$jpeg.jpg
new file mode 100644
index 0000000..c523f8f
--- /dev/null
+++ b/root/projects/btrktrl/knobs_all/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/knobs_testing/description: text$plain b/root/projects/btrktrl/knobs_testing/description: text$plain
new file mode 100644
index 0000000..9588122
--- /dev/null
+++ b/root/projects/btrktrl/knobs_testing/description: text$plain
@@ -0,0 +1 @@
+testing different knob spacings
diff --git a/root/projects/btrktrl/knobs_testing/image$jpeg.jpg b/root/projects/btrktrl/knobs_testing/image$jpeg.jpg
new file mode 100644
index 0000000..09ea47d
--- /dev/null
+++ b/root/projects/btrktrl/knobs_testing/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/pcb_dev_configuration/description: text$plain b/root/projects/btrktrl/pcb_dev_configuration/description: text$plain
new file mode 100644
index 0000000..b15f4f0
--- /dev/null
+++ b/root/projects/btrktrl/pcb_dev_configuration/description: text$plain
@@ -0,0 +1 @@
+configuring the FPGA on the custom PCB via an arduino for the first time
diff --git a/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4 b/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4
new file mode 100644
index 0000000..c8113cd
--- /dev/null
+++ b/root/projects/btrktrl/pcb_dev_configuration/video$mp4.mp4
Binary files differ
diff --git a/root/projects/btrktrl/pcb_dev_encoder/description: text$plain b/root/projects/btrktrl/pcb_dev_encoder/description: text$plain
new file mode 100644
index 0000000..530be5a
--- /dev/null
+++ b/root/projects/btrktrl/pcb_dev_encoder/description: text$plain
@@ -0,0 +1 @@
+encoder & capacitive sensing working on the custom PCB
diff --git a/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4 b/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4
new file mode 100644
index 0000000..fa41799
--- /dev/null
+++ b/root/projects/btrktrl/pcb_dev_encoder/video$mp4.mp4
Binary files differ
diff --git a/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg
new file mode 100644
index 0000000..5864822
--- /dev/null
+++ b/root/projects/btrktrl/pcb_glamour/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg
new file mode 100644
index 0000000..5d572aa
--- /dev/null
+++ b/root/projects/btrktrl/pcb_glamour_close/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg
new file mode 100644
index 0000000..6503f84
--- /dev/null
+++ b/root/projects/btrktrl/pcb_glamour_connector/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg
new file mode 100644
index 0000000..661f4fe
--- /dev/null
+++ b/root/projects/btrktrl/pcb_glamour_far/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg b/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg
new file mode 100644
index 0000000..bbefc13
--- /dev/null
+++ b/root/projects/btrktrl/pcb_glamour_top/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/pcb_osc/description: text$plain b/root/projects/btrktrl/pcb_osc/description: text$plain
new file mode 100644
index 0000000..2f0df00
--- /dev/null
+++ b/root/projects/btrktrl/pcb_osc/description: text$plain
@@ -0,0 +1 @@
+a browser application talking to the encoders through a websocket/serial OSC bridge (nodejs)
diff --git a/root/projects/btrktrl/pcb_osc/video$mp4.mp4 b/root/projects/btrktrl/pcb_osc/video$mp4.mp4
new file mode 100644
index 0000000..3562d43
--- /dev/null
+++ b/root/projects/btrktrl/pcb_osc/video$mp4.mp4
Binary files differ
diff --git a/root/projects/btrktrl/proto_encoder/description: text$plain b/root/projects/btrktrl/proto_encoder/description: text$plain
new file mode 100644
index 0000000..e0f620b
--- /dev/null
+++ b/root/projects/btrktrl/proto_encoder/description: text$plain
@@ -0,0 +1 @@
+getting the encoder and capacitive sensing working on the prototype
diff --git a/root/projects/btrktrl/proto_encoder/video$mp4.mp4 b/root/projects/btrktrl/proto_encoder/video$mp4.mp4
new file mode 100644
index 0000000..acb32c8
--- /dev/null
+++ b/root/projects/btrktrl/proto_encoder/video$mp4.mp4
Binary files differ
diff --git a/root/projects/btrktrl/proto_rgb/description: text$plain b/root/projects/btrktrl/proto_rgb/description: text$plain
new file mode 100644
index 0000000..43b7f69
--- /dev/null
+++ b/root/projects/btrktrl/proto_rgb/description: text$plain
@@ -0,0 +1 @@
+driving WS2812 RGB LEDs on the prototype board
diff --git a/root/projects/btrktrl/proto_rgb/video$mp4.mp4 b/root/projects/btrktrl/proto_rgb/video$mp4.mp4
new file mode 100644
index 0000000..8e06fcc
--- /dev/null
+++ b/root/projects/btrktrl/proto_rgb/video$mp4.mp4
Binary files differ
diff --git a/root/projects/btrktrl/proto_spi/description: text$plain b/root/projects/btrktrl/proto_spi/description: text$plain
new file mode 100644
index 0000000..c38b56e
--- /dev/null
+++ b/root/projects/btrktrl/proto_spi/description: text$plain
@@ -0,0 +1 @@
+developing and debugging the SPI protocol
diff --git a/root/projects/btrktrl/proto_spi/image$jpeg.jpg b/root/projects/btrktrl/proto_spi/image$jpeg.jpg
new file mode 100644
index 0000000..c89341c
--- /dev/null
+++ b/root/projects/btrktrl/proto_spi/image$jpeg.jpg
Binary files differ
diff --git a/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon b/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon
new file mode 100644
index 0000000..f7d8f9c
--- /dev/null
+++ b/root/projects/btrktrl/text$moonscript -> fn -> mmm$dom.moon
@@ -0,0 +1,62 @@
+import div, h3, p, a from require 'mmm.dom'
+import link_to from (require 'mmm.mmmfs.util') require 'mmm.dom'
+
+=>
+ text = (...) ->
+ div with for text in *{...}
+ p text
+ .style = { 'max-width': '900px' }
+
+ filtered_block = (pattern) ->
+ div with for child in *@children
+ continue unless (child\gett 'name: alpha')\match pattern
+
+ div {
+ style: {
+ display: 'inline-block'
+ width: '500px'
+ margin: '0.5em'
+ padding: '0.4em 1em'
+ background: 'var(--gray-bright)'
+ }
+ div (link_to child), style: { 'margin-bottom': '0.2em' }
+ child\gett 'mmm/dom'
+ (child\get 'description: mmm/dom')
+ }
+
+ .style = {
+ display: 'flex'
+ 'flex-wrap': 'wrap'
+ 'align-items': 'flex-start'
+ margin: '-0.5em'
+ }
+
+ div {
+ h3 @gett 'name: alpha'
+ text "For this project I am builiding a modular, FPGA powered MIDI/OSC Control Surface.",
+ "The setup consists of an arduino MCU as a master controller, that communicates to the PC over
+ SLIP-encoded Serial OSC messages. The controller talks to daughterboards over SPI.
+ Each daugherboard contains a rotary encoder, 8 RGB LEDs and does capacitive sensing on the knob.",
+ "This was the first time I worked with an FPGA, and the first time I designed my own PCBs as well.
+ The FPGA I used is an ICE40UP5k, it was targeted using the icestorm open toolchain and Verilog.
+ I started by prototyping using an UPduino v2 Prototyping board (orange), and my failed rev1 PCBs (green).
+ On the FPGAs I implemented capacitive sensing, the SPI slave and control logic before moving on."
+
+ filtered_block '^proto_'
+
+ text "Once I got everything working there I designed my custom boards with the FPGA integrated directly,
+ including power conditioning and configuration.
+ There is also a busboard that manages SPI addressing / multiplexing as well as latching the power state
+ for each daughterboard, so that they can be started and configured individually."
+
+ filtered_block '^pcb_glamour'
+ filtered_block '^pcb_dev'
+
+ text "The daughterboards and controller communicate over a custom SPI protocol I designed.
+ The controller configures the daughterboards on boot or request from the PC.
+ It sends and receives OSC messages over SLIP-encoded Serial.
+ On the PC a small nodejs application relays the OSC messages over UDP or WebSocket,
+ so that native and web applications can consume them and interact with the control surface."
+
+ filtered_block '^pcb_osc'
+ }
diff --git a/scss/_content.scss b/scss/_content.scss
index e4345ef..0bfc1e8 100644
--- a/scss/_content.scss
+++ b/scss/_content.scss
@@ -4,7 +4,10 @@
height: inherit;
}
- .markdown, .markdown > p, .markdown > p > a {
+ .markdown,
+ .markdown > p,
+ .markdown > p > a,
+ .markdown > a {
> img, > video {
display: block;
max-width: 100%;