cleanup after moving to MDwiki

This commit is contained in:
dreat 2026-02-16 15:24:59 +01:00
parent 65fe90341a
commit c36b9c2be0
No known key found for this signature in database
GPG key ID: B24F8F4D3724EE54
52 changed files with 5 additions and 3882 deletions

View file

@ -1,11 +0,0 @@
---
permalink: 404.html
layout: default
title: "404"
id: "not-found"
---
<div>
<h1>Oops, that's a 404. 🙈</h1>
<p>Looks like this page doesn't exist. <a href="/">Return home</a> to get a fresh start.</p>
</div>

View file

@ -1,13 +0,0 @@
FROM ruby:3.1.1 AS builder
RUN apt-get update -qq && apt-get install -y build-essential nodejs
WORKDIR /srv/jekyll
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
RUN chown 1000:1000 -R /srv/jekyll
RUN bundle exec jekyll build -d /srv/jekyll/_site
FROM nginx:alpine
COPY --from=builder /srv/jekyll/_site /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

10
Gemfile
View file

@ -1,10 +0,0 @@
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "jekyll", "~> 4.3"
gem "jekyll-last-modified-at", git: "https://github.com/maximevaillancourt/jekyll-last-modified-at", branch: "add-support-for-files-in-git-submodules"
gem "webrick", "~> 1.7"
gem "nokogiri"

View file

@ -1,90 +0,0 @@
GIT
remote: https://github.com/maximevaillancourt/jekyll-last-modified-at
revision: b7f1164861ba589660af3dc096dcbdff75d67145
branch: add-support-for-files-in-git-submodules
specs:
jekyll-last-modified-at (1.3.2)
jekyll (>= 3.7, < 5.0)
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
colorator (1.1.0)
concurrent-ruby (1.3.4)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
ffi (1.17.0-arm64-darwin)
ffi (1.17.0-x86_64-darwin)
forwardable-extended (2.6.0)
google-protobuf (3.23.4-arm64-darwin)
google-protobuf (3.23.4-x86_64-darwin)
http_parser.rb (0.8.0)
i18n (1.14.6)
concurrent-ruby (~> 1.0)
jekyll (4.3.4)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 1.0)
jekyll-sass-converter (>= 2.0, < 4.0)
jekyll-watch (~> 2.0)
kramdown (~> 2.3, >= 2.3.1)
kramdown-parser-gfm (~> 1.0)
liquid (~> 4.0)
mercenary (>= 0.3.6, < 0.5)
pathutil (~> 0.9)
rouge (>= 3.0, < 5.0)
safe_yaml (~> 1.0)
terminal-table (>= 1.8, < 4.0)
webrick (~> 1.7)
jekyll-sass-converter (3.0.0)
sass-embedded (~> 1.54)
jekyll-watch (2.2.1)
listen (~> 3.0)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
liquid (4.0.4)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.4.0)
nokogiri (1.13.10-arm64-darwin)
racc (~> 1.4)
nokogiri (1.13.10-x86_64-darwin)
racc (~> 1.4)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (5.1.1)
racc (1.8.1)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.3.7)
rouge (3.30.0)
safe_yaml (1.0.5)
sass-embedded (1.58.3-arm64-darwin)
google-protobuf (~> 3.21)
sass-embedded (1.58.3-x86_64-darwin)
google-protobuf (~> 3.21)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
unicode-display_width (2.6.0)
webrick (1.8.2)
PLATFORMS
universal-darwin-23
DEPENDENCIES
jekyll (~> 4.0)
jekyll-last-modified-at!
nokogiri
webrick (~> 1.7)
BUNDLED WITH
2.2.3

View file

@ -1,9 +0,0 @@
# Released under MIT License
Copyright (c) 2020 Maxime Vaillancourt.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View file

@ -5,10 +5,5 @@ This marks second attempt at digital garden. This time I chose something with lo
As evertyhing in repo is work in progress and will grow overtime, so will this readme. As evertyhing in repo is work in progress and will grow overtime, so will this readme.
**Code forked from repo in this tutorial: [Setting up your own digital garden with Jekyll](https://maximevaillancourt.com/blog/setting-up-your-own-digital-garden-with-jekyll)** **Digital garden runs on [MDwiki](https://dynalon.github.io/mdwiki/#!index.md)**
[link to GitHub template](https://github.com/maximevaillancourt/digital-garden-jekyll-template).
## License
Source code is available under the [MIT license](LICENSE.md).

View file

@ -1,45 +0,0 @@
title: Entropic Jungle
include: ['_pages']
exclude: ['_includes/notes_graph.json']
# You may need to change the base URL depending on your deploy configuration.
# Specifically, when using GitHub Pages, the baseurl should point to where GitHub
# Pages deploys your repository (which is usually the repository name).
baseurl: ''
# If you are using a host that cannot resolve URLs that do
# not end with .html (such as Neocities), set this to 'true'.
use_html_extension: false
# Set to `true` to open non-internal links in new tabs, or
# set to `false` to open non-internal links in current tab.
open_external_links_in_new_tab: true
# Set to `true` to replace tweet URLs with Twitter embeds.
# Note that doing so will negatively the reader's privacy
# as their browser will communicate with Twitter's servers.
embed_tweets: false
permalink: pretty
relative_permalinks: false
plugins:
- jekyll-last-modified-at
sass:
sass_dir: _sass
style: :compressed
collections:
notes:
output: true
permalink: /:slug
defaults:
- scope:
path: "**/*"
values:
layout: "default"
- scope:
path: "_notes/**/*.md"
values:
layout: "note"

View file

@ -1,4 +0,0 @@
<a class="internal-link" href="/about">about</a>
<br />
<br />
made with entropy by dreat.

View file

@ -1,48 +0,0 @@
<head>
<meta charset="UTF-8">
<link rel="canonical" href="{{ site.url }}{{ page.url }}" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{% if page.excerpt %}{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}{% else %}{{ site.title }}{% endif %}">
<meta property="og:site_name" content="{{ site.title }}">
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
<link rel="stylesheet" href="{{ site.baseurl }}/styles.css">
{% if page.excerpt %}
<meta property="og:description" content="{{ page.excerpt | strip_html | strip_newlines | truncate: 160 }}"/>
{% else %}
<meta property="og:description" content="{{ site.title | strip_html | strip_newlines | truncate: 160 }}"/>
{% endif %}
{% if page.title %}
<meta property="og:title" content="{{ page.title }}">
<meta property="og:type" content="article">
{% else %}
<meta property="og:title" content="{{ site.title }}">
<meta property="og:type" content="website">
{% endif %}
{% if page.date %}
<meta property="article:published_time" content="{{ page.date | date_to_xmlschema }}">
<meta property="article:author" content="{{ site.url }}/">
{% endif %}
<meta property="og:url" content="{{ site.url }}{{ page.url }}" />
{% if page.image %}
<meta property="og:image" content="{{ site.url }}{{ page.image }}">
{% endif %}
<title>
{% if page.id == "home" %}
{{ site.title }}
{% else %}
{{ page.title }} &mdash; {{ site.title }}
{% endif %}
</title>
</head>

View file

@ -1,140 +0,0 @@
<!-- That file is not particularly elegant. This will need a refactor at some point. -->
<style>
content a.internal-link {
border-color: #8b88e6;
background-color: #efefff;
}
#tooltip-wrapper {
background: white;
padding: 1em;
border: 1px solid #ddd;
border-radius: 4px;
overflow: hidden;
position: absolute;
width: 400px;
height: 250px;
font-size: 0.8em;
box-shadow: 0 5px 10px rgba(0,0,0,0.1);
opacity: 0;
transition: opacity 100ms;
}
#tooltip-wrapper:after {
content: "";
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
pointer-events: none;
background-image: linear-gradient(to bottom, rgba(255,255,255, 0), rgba(255,255,255, 1) 90%);
width: 100%;
height: 75px;
}
</style>
<div style="opacity: 0; display: none;" id='tooltip-wrapper'>
<div id='tooltip-content'>
</div>
</div>
<iframe style="display: none; height: 0; width: 0;" id='link-preview-iframe' src="">
</iframe>
<script>
var opacityTimeout;
var contentTimeout;
var transitionDurationMs = 100;
var iframe = document.getElementById('link-preview-iframe')
var tooltipWrapper = document.getElementById('tooltip-wrapper')
var tooltipContent = document.getElementById('tooltip-content')
var linkHistories = {};
function hideTooltip() {
opacityTimeout = setTimeout(function() {
tooltipWrapper.style.opacity = 0;
contentTimeout = setTimeout(function() {
tooltipContent.innerHTML = '';
tooltipWrapper.style.display = 'none';
}, transitionDurationMs + 1);
}, transitionDurationMs)
}
function showTooltip(event) {
var elem = event.target;
var elem_props = elem.getClientRects()[elem.getClientRects().length - 1];
var top = window.pageYOffset || document.documentElement.scrollTop
if (event.target.host === window.location.host) {
if (!linkHistories[event.target.href]) {
iframe.src = event.target.href
iframe.onload = function() {
tooltipContentHtml = ''
tooltipContentHtml += '<div style="font-weight: bold;">' + iframe.contentWindow.document.querySelector('h1').innerHTML + '</div>'
tooltipContentHtml += iframe.contentWindow.document.querySelector('content').innerHTML
tooltipContent.innerHTML = tooltipContentHtml
linkHistories[event.target.href] = tooltipContentHtml
tooltipWrapper.style.display = 'block';
setTimeout(function() {
tooltipWrapper.style.opacity = 1;
}, 1)
}
} else {
tooltipContent.innerHTML = linkHistories[event.target.href]
tooltipWrapper.style.display = 'block';
setTimeout(function() {
tooltipWrapper.style.opacity = 1;
}, 1)
}
tooltipWrapper.style.left = elem_props.left - (tooltipWrapper.offsetWidth / 2) + (elem_props.width / 2) + "px";
if ((window.innerHeight - elem_props.top) < (tooltipWrapper.offsetHeight)) {
tooltipWrapper.style.top = elem_props.top + top - tooltipWrapper.offsetHeight - 10 + "px";
} else if ((window.innerHeight - elem_props.top) > (tooltipWrapper.offsetHeight)) {
tooltipWrapper.style.top = elem_props.top + top + 35 + "px";
}
if ((elem_props.left + (elem_props.width / 2)) < (tooltipWrapper.offsetWidth / 2)) {
tooltipWrapper.style.left = "10px";
} else if ((document.body.clientWidth - elem_props.left - (elem_props.width / 2)) < (tooltipWrapper.offsetWidth / 2)) {
tooltipWrapper.style.left = document.body.clientWidth - tooltipWrapper.offsetWidth - 20 + "px";
}
}
}
function setupListeners(linkElement) {
linkElement.addEventListener('mouseleave', function(_event) {
hideTooltip();
});
tooltipWrapper.addEventListener('mouseleave', function(_event) {
hideTooltip();
});
linkElement.addEventListener('touchend', function(_event) {
hideTooltip();
});
tooltipWrapper.addEventListener('touchend', function(_event) {
hideTooltip();
});
linkElement.addEventListener('mouseenter', function(event) {
clearTimeout(opacityTimeout);
clearTimeout(contentTimeout);
showTooltip(event);
});
tooltipWrapper.addEventListener('mouseenter', function(event) {
clearTimeout(opacityTimeout);
clearTimeout(contentTimeout);
});
}
document.querySelectorAll('{{ include.wrapperQuerySelector }} a').forEach(setupListeners);
</script>

View file

@ -1,3 +0,0 @@
<div>
<a class="internal-link" href="{{ site.baseurl }}/"><b>{{ site.title }}</b></a>
</div>

View file

@ -1,315 +0,0 @@
<style>
.links line {
stroke: #ccc;
opacity: 0.5;
}
.nodes circle {
cursor: pointer;
fill: #8b88e6;
transition: all 0.15s ease-out;
}
.text text {
cursor: pointer;
fill: #333;
text-shadow: -1px -1px 0 #fafafabb, 1px -1px 0 #fafafabb, -1px 1px 0 #fafafabb, 1px 1px 0 #fafafabb;
}
.nodes [active],
.text [active] {
cursor: pointer;
fill: black;
}
.inactive {
opacity: 0.1;
transition: all 0.15s ease-out;
}
#graph-wrapper {
background: #fcfcfc;
border-radius: 4px;
height: auto;
}
</style>
<div id="graph-wrapper">
<script>
var commentFlag = true;
window.addEventListener("load", loadGraph);
window.addEventListener("scroll", loadGraph);
function loadGraph() {
if (!( document.getElementById("graph-wrapper").getBoundingClientRect().top <
window.innerHeight * 1.5 &&
commentFlag)){
return;
}
var oScript = document.createElement("script");
oScript.src = "https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js";
oScript.crossOrigin = 'anonymous';
oScript.integrity =
"sha512-FHsFVKQ/T1KWJDGSbrUhTJyS1ph3eRrxI228ND0EGaEp6v4a/vGwPWd3Dtd/+9cI7ccofZvl/wulICEurHN1pg==";
document.body.appendChild(oScript);
oScript.onload = () => {
const MINIMAL_NODE_SIZE = 8;
const MAX_NODE_SIZE = 12;
const ACTIVE_RADIUS_FACTOR = 1.5;
const STROKE = 1;
const FONT_SIZE = 16;
const TICKS = 200;
const FONT_BASELINE = 40;
const MAX_LABEL_LENGTH = 50;
const graphData = {% include notes_graph.json %}
let nodesData = graphData.nodes;
let linksData = graphData.edges;
const nodeSize = {};
const updateNodeSize = () => {
nodesData.forEach((el) => {
let weight =
3 *
Math.sqrt(
linksData.filter((l) => l.source.id === el.id || l.target.id === el.id)
.length + 1
);
if (weight < MINIMAL_NODE_SIZE) {
weight = MINIMAL_NODE_SIZE;
} else if (weight > MAX_NODE_SIZE) {
weight = MAX_NODE_SIZE;
}
nodeSize[el.id] = weight;
});
};
const onClick = (d) => {
window.location = d.path
};
const onMouseover = function (d) {
const relatedNodesSet = new Set();
linksData
.filter((n) => n.target.id == d.id || n.source.id == d.id)
.forEach((n) => {
relatedNodesSet.add(n.target.id);
relatedNodesSet.add(n.source.id);
});
node.attr("class", (node_d) => {
if (node_d.id !== d.id && !relatedNodesSet.has(node_d.id)) {
return "inactive";
}
return "";
});
link.attr("class", (link_d) => {
if (link_d.source.id !== d.id && link_d.target.id !== d.id) {
return "inactive";
}
return "";
});
link.attr("stroke-width", (link_d) => {
if (link_d.source.id === d.id || link_d.target.id === d.id) {
return STROKE * 4;
}
return STROKE;
});
text.attr("class", (text_d) => {
if (text_d.id !== d.id && !relatedNodesSet.has(text_d.id)) {
return "inactive";
}
return "";
});
};
const onMouseout = function (d) {
node.attr("class", "");
link.attr("class", "");
text.attr("class", "");
link.attr("stroke-width", STROKE);
};
const sameNodes = (previous, next) => {
if (next.length !== previous.length) {
return false;
}
const map = new Map();
for (const node of previous) {
map.set(node.id, node.label);
}
for (const node of next) {
const found = map.get(node.id);
if (!found || found !== node.title) {
return false;
}
}
return true;
};
const sameEdges = (previous, next) => {
if (next.length !== previous.length) {
return false;
}
const set = new Set();
for (const edge of previous) {
set.add(`${edge.source.id}-${edge.target.id}`);
}
for (const edge of next) {
if (!set.has(`${edge.source.id}-${edge.target.id}`)) {
return false;
}
}
return true;
};
const graphWrapper = document.getElementById('graph-wrapper')
const element = document.createElementNS("http://www.w3.org/2000/svg", "svg");
element.setAttribute("width", graphWrapper.getBoundingClientRect().width);
element.setAttribute("height", window.innerHeight * 0.8);
graphWrapper.appendChild(element);
const reportWindowSize = () => {
element.setAttribute("width", window.innerWidth);
element.setAttribute("height", window.innerHeight);
};
window.onresize = reportWindowSize;
const svg = d3.select("svg");
const width = Number(svg.attr("width"));
const height = Number(svg.attr("height"));
let zoomLevel = 1;
const simulation = d3
.forceSimulation(nodesData)
.force("forceX", d3.forceX().x(width / 2))
.force("forceY", d3.forceY().y(height / 2))
.force("charge", d3.forceManyBody())
.force(
"link",
d3
.forceLink(linksData)
.id((d) => d.id)
.distance(70)
)
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collision", d3.forceCollide().radius(80))
.stop();
const g = svg.append("g");
let link = g.append("g").attr("class", "links").selectAll(".link");
let node = g.append("g").attr("class", "nodes").selectAll(".node");
let text = g.append("g").attr("class", "text").selectAll(".text");
const resize = () => {
if (d3.event) {
const scale = d3.event.transform;
zoomLevel = scale.k;
g.attr("transform", scale);
}
const zoomOrKeep = (value) => (zoomLevel >= 1 ? value / zoomLevel : value);
const font = Math.max(Math.round(zoomOrKeep(FONT_SIZE)), 1);
text.attr("font-size", (d) => font);
text.attr("y", (d) => d.y - zoomOrKeep(FONT_BASELINE) + 8);
link.attr("stroke-width", zoomOrKeep(STROKE));
node.attr("r", (d) => {
return zoomOrKeep(nodeSize[d.id]);
});
svg
.selectAll("circle")
.filter((_d, i, nodes) => d3.select(nodes[i]).attr("active"))
.attr("r", (d) => zoomOrKeep(ACTIVE_RADIUS_FACTOR * nodeSize[d.id]));
};
const ticked = () => {
node.attr("cx", (d) => d.x).attr("cy", (d) => d.y);
text
.attr("x", (d) => d.x)
.attr("y", (d) => d.y - (FONT_BASELINE - nodeSize[d.id]) / zoomLevel);
link
.attr("x1", (d) => d.source.x)
.attr("y1", (d) => d.source.y)
.attr("x2", (d) => d.target.x)
.attr("y2", (d) => d.target.y);
};
const restart = () => {
updateNodeSize();
node = node.data(nodesData, (d) => d.id);
node.exit().remove();
node = node
.enter()
.append("circle")
.attr("r", (d) => {
return nodeSize[d.id];
})
.on("click", onClick)
.on("mouseover", onMouseover)
.on("mouseout", onMouseout)
.merge(node);
link = link.data(linksData, (d) => `${d.source.id}-${d.target.id}`);
link.exit().remove();
link = link.enter().append("line").attr("stroke-width", STROKE).merge(link);
text = text.data(nodesData, (d) => d.label);
text.exit().remove();
text = text
.enter()
.append("text")
.text((d) => shorten(d.label.replace(/_*/g, ""), MAX_LABEL_LENGTH))
.attr("font-size", `${FONT_SIZE}px`)
.attr("text-anchor", "middle")
.attr("alignment-baseline", "central")
.on("click", onClick)
.on("mouseover", onMouseover)
.on("mouseout", onMouseout)
.merge(text);
node.attr("active", (d) => isCurrentPath(d.path) ? true : null);
text.attr("active", (d) => isCurrentPath(d.path) ? true : null);
simulation.nodes(nodesData);
simulation.force("link").links(linksData);
simulation.alpha(1).restart();
simulation.stop();
for (let i = 0; i < TICKS; i++) {
simulation.tick();
}
ticked();
};
const zoomHandler = d3.zoom().scaleExtent([0.2, 3]).on("zoom", resize);
zoomHandler(svg);
restart();
function isCurrentPath(notePath) {
return window.location.pathname.includes(notePath)
}
function shorten(str, maxLen, separator = ' ') {
if (str.length <= maxLen) return str;
return str.substr(0, str.lastIndexOf(separator, maxLen)) + '...';
}
commentFlag = false;
}
}
</script>
</div>

View file

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
{% include head.html %}
<body>
<nav>{% include nav.html %}</nav>
<div class="wrapper">
<main>{{ content }}</main>
<hr>
<graph>Here are all the notes in this jungle, along with their links, visualized as a graph.</graph>
{% include notes_graph.html %}
<footer>{% include footer.html %}</footer>
</div>
{% include link-previews.html wrapperQuerySelector="content" %}
</body>
</html>

View file

@ -1,42 +0,0 @@
---
layout: default
---
<article>
<div>
<h1>{{ page.title }}</h1>
<time datetime="{{ page.last_modified_at | date_to_xmlschema }}">{% if page.type != 'pages' %}
Last updated on {{ page.last_modified_at | date: "%B %-d, %Y" }}
{% endif %}
</time>
</div>
<div id="notes-entry-container">
<content>
{{ content }}
</content>
<side style="font-size: 0.9em">
<h3 style="margin-bottom: 1em">Notes mentioning this note</h3>
{% if page.backlinks.size > 0 %}
<div style="display: grid; grid-gap: 1em; grid-template-columns: repeat(1fr);">
{% for backlink in page.backlinks %}
<div class="backlink-box">
<a class="internal-link" href="{{ site.baseurl }}{{ backlink.url }}{%- if site.use_html_extension -%}.html{%- endif -%}">{{ backlink.title }}</a><br>
<div style="font-size: 0.9em">{{ backlink.excerpt | strip_html | truncatewords: 20 }}</div>
</div>
{% endfor %}
</div>
{% else %}
<div style="font-size: 0.9em">
<p>
There are no notes linking to this note.
</p>
</div>
{% endif %}
</side>
</div>
</article>

View file

@ -1,7 +0,0 @@
---
layout: default
---
<content>
{{ content }}
</content>

BIN
_notes/.DS_Store vendored

Binary file not shown.

View file

@ -1,148 +0,0 @@
---
title: Hidden Mineral World
tags: music
---
_written in the middle of making this_
<a class="external-link" href="https://open.spotify.com/album/33RZuDk2Ov47TVWEGgEGQ2?si=KvgLf1gxSLekgBTlrmf-2w">Spotify Link</a>
### Intro
Hidden Mineral World EP (or HMW for short) started out as a challenge from my friend. He generated this:
<img src="/assets/hmw.png"/>
using StableDiffusion and I jokingly said I will do a dark techno/glitch EP for that.
==and the game was on==
### First try
I started dabbling in Ableton Live but with no real progress. After some short loops I kinda forgot about this.
### Second try
As I saw the cover again, I decided to give it another go. This time I used ChatGPT4 to write the song structure, bpm and track titles. It came up with
1. Subterranean Frequency
2. Crystal Resonance
3. Geode Rift
4. Iron Vein
I also got BPMs and tracks structures, but, having more draw into Ambient stuff it, again, got forgotten
### Third try
Third time's the charm, right?
I may have neglected this, but this EP kept coming back to my mind, so I decided to give it a final try, this time with extra challenge - I will work on it for 15min daily. No more, no less. I open up Ableton Live, start the timer and save&quit when timer gets off.
And, surprisingly, this works. Works so well, that I have force myself to stop.
As of the time of writing this I have a premix versions of tracks 1 & 2 and track 3 is in progress.
#### Subterranean Frequency
This is what I got from ChatGPT4
```
BPM: 125
- 0:00-1:15: Opening with a pulsating sub-bass drone, the sound of distant drilling emerges to introduce the thematic elements of the track.
- 1:15-2:30: The sub-bass transforms into a steady, dark techno beat as the percussion intensifies. Metallic glitches layer over the rhythm.
- 2:30-4:00: A breakdown in the middle introduces distorted synth elements, building tension.
- 4:00-5:00: The track closes by revisiting the initial rhythm, while the drilling and glitches fade, leaving only the deep echoes of the bass.
```
I started with marking the timestamps (which I had to move a bit to align with bars) and named locators after the defined structure. This helped me a lot, as I exactly saw how long each section is, what it is and what comes after another. I also added "end" locator to have a clear indication where the track ends.
It was a nice challenge, I used some CC0 industrial samples (drills, pickaxes, stones etc), learned a lot about wavetable. Used some more samples for glitchy beats above kicks, needed to use parallel compression to make it work properly.
This was the first one, I think the quickest one.
Going on for 15 minutes and with set structure was a bit of a challenge, but did help greatly move forward. If you have only 15 min to do work, you make every second count.
#### Crystal Resonance
This is what I got from ChatGPT4
```
BPM: 132
- 0:00-1:00: Introduction with ethereal pads, a soft, minimalistic drum beat enters to set the tempo.
- 1:00-2:15: Glitchy beats are layered over the pads, the tempo increases. Synths mimic the sound of crystals resonating.
- 2:15-3:30: The final section features a crescendo of resonant sounds, ending with a series of glitchy echoes that fade out to silence.
```
Again, I started with location markers, and, again, I had to adjust them to align with the beat. Here I added extra one for "echoes" before "end" - to show the time of the echoes to decay.
Another dive into wavetable. A lot of youtube diving into understanding this tool more definitely helped.
I tried to make "glass needles" sound for `crystal resonance` here and I actually decided to use a MIDI drum clips from Ableton's packs. I did eventually change them a bit, partially to maintain `techno` feel.
Here I had a huge clash of frequencies and had to use a lot of parallel compression to make it sound good. It's actually even better than I've wanted and had an extreme case study of clashing instruments.
#### Geode Rift
This is what I got from ChatGPT4
```
BPM: 128
- 0:00-1:00: A heavy bassline starts the track, suggesting the outer shell of the geode.
- 1:00-2:15: The track 'cracks open' with sparkling arpeggios and expansive synths, replicating the awe of discovering the geode's interior.
- 2:15-3:45: Techno beats enter, increasing in intensity to represent the geode's harsh formation environment.
- 3:45-4:30: The music reduces to a soft, twinkling outro, mirroring the closing of the geode and leaving the listener with a sense of intrigue.
```
This one is still in progress, so this entry may actually start being interesting.
As usual, I started with location markers.
Then I used operator -> noise with some processing (EQ, filters, erosions etc) to create cracking noise to simulate "cracking open". LFO helped give it some rhythm.
Quick heavy bassline in wavetable, quick synth arpeggios and some beats.
Challenge here was that it was the most melodic track yet. I started with some scale to help me - continued to use that for other stuff, but I knew it was not working.
Actually after initial bass I went into designing fading outro, with automated autofilter and freeze from reverb.
I actually broke from the scale suggestions and went with what sounds cool to me (and arpeggiated). Grouping wavetable with second, more plucky one, did help to get more pleasing sound as well.
I changed previous midi clips to new melody and added new synth for a bass line for the "cracking open" part, that will stay with the song till the end.
Initial bass is automated to get to `-inf dB` slowly over the course of the second part.
I though that I need some pads, so I whipped out wavetable to create something lush. I duplicated the track, froze two chords (first one from pattern and very last one), reversed audio clips and used them as smooth transition. It works especially well if you have reverse audio going into the synth when there's a transition between parts. It makes it all glue together, and sounds really well.
After rendering and listening to it, I may go back to it and add something in first part, as, right now, it's a bit boring.
#### Iron Vein
This is what I got from ChatGPT4
```
BPM: 130
- 0:00-0:45: A steady, driving beat starts, metallic synths layer over to build tension.
- 0:45-2:00: The intensity increases, bringing the raw energy of iron extraction to life.
- 2:00-3:30: The track breaks down into a quieter passage, with softer sounds representing the depleting vein.
- 3:30-4:15: A somber, atmospheric outro, symbolizing the aftermath of extraction.
```
I spent first session, trying to make synths that are `metallic enough`. I decided to switch things a bit, and went with Ashlight from NI for some dark pad paired with quiet `metallic` operator with some echo.
Turns out that first part is divisible by 6, not 4 (given the length of patterns I created), so this makes things a bit more interesting.
Afterwards I added a standard 808 kick that slowly appears. Synth has parallel compression to make that kick stand out, but this time I did 50% wet (instead of 100%), and, I must say, it sounds great.
I managed to create simple hihat pattern and got `time outed` when trying to find next percussive sounds.
While playing around with `bongo` sound I managed to create great accents using sparse two hits at a same time (with some reverb on some of the hits) and found great rhythmic pattern with second preset. I actually made it quicker to test some effects and realised that it sounds great as a background sound, so I kept it there.
I stole the idea of "arpeggiating" 5 notes to create rhythmic variety - put a long 5 note MIDI with arpeggio on operator bell sounds. To enforce the melody, in third section of a song I used the same notes, just slower, going up with first note as a pedal note. I just found a nice Vital preset that fit the mood. Moving it around a bit made "progression" that was supported with sustained bass.
As LLM suggested track slowly fading away I started getting more sparse with bongos (to the point it was removed), slowly removing layers. Track ends with reverb tail from bass and Vital.
#### Final touches
I went around the tracks and did some small fixes here and there. Also I mixed it quickly (limiter on master maybe is not advanced technique but did the job) and added a little, barely audible, heavy processed sample in Geode Rift. Afterwards I uploaded it to streaming services. And now only thing left is to wait for it to be processed.
### Random thoughts
- As said many times, both image and text generative AIs give "raw material" rather than finished product. Cover was worked on in PhotoShop after it was generated. I did interpret the song structure in my own way.
- OTOH, not having a blank page to start with is a great help. While here it's way more constraining that I would use for something else, LLMs can be great for ideation and getting some concrete starting points.
- I still deviated from some of the suggestions after banging my head against the wall, but, many of those were helpful, or made me try out and learn new things

View file

@ -1,16 +0,0 @@
---
title: Jaurim - Damn! I've Been Living Like This
---
<status>Status: 🌱 </status>
| section | Korean | English |
| -------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| title | 자우림 "**그래 제길** 나 이렇게 살았어" | Jaurim - "**(ok? eh?) damn!** I lived/been living like this" |
| verse 1 | 그래 제길 나 이렇게 살았어 <br>*보다시피* **볼 것** 없이 살았어 <br>해놓은 것 없이, 가진 것 하나 없이 <br>그럭저럭 되는대로, 그런 하루, 하루 | eh, damn, I've been living like this<br>*as you see* I lived without **seeing**<br>without doing anything, without having one thing / anything<br>somehow anyhow(?), like that, day by day(?) |
| chorus 1 | 나도 간절하게 바랬던 게 있어 <br>나도 맘을 다해 했던 일이 있어 <br>내 뜻대로 되준 일은 없어 <br>결국 아무것도 나에게는 쉽지 않아 | I too desperately faded there<br>I too used up my feelings on things that happen<br>My own way does not exist(?)<br>In the end nothing is easy for me<br> |
| verse 2 | 그래 제길 나 이렇게 살았어 <br>보다시피 볼 것 없이 살았어 <br>믿는 사람 없이, 진짜 사랑 한 번 없이 <br>그럭저럭 되는대로, 그런 하루, 하루 | |
| bridge | 그래 제길 나 이렇게 살았어 <br>보다시피 볼 것 없이 살았어 | |
| chorus 2 | 간절하게 바랬던 게 있어 <br>맘을 다해 했던 일이 있어 <br>내 뜻대로 되준 일은 없어 <br>결국 아무것도 나에게는 쉽지 않아 <br>간절하게 바랬던 게 있어 <br>맘을 다해 했던 일이 있어 | |

File diff suppressed because it is too large Load diff

View file

@ -1,499 +0,0 @@
---
title: Korean phrases
---
<status>Status: 🌿 </status>
### Thank you
from most to least formal
- 감사합니다
- 고맙습니다
- 감사해요
- 고마워요
- _casual territory_
- 고마워
- 감사 (texting)
- ㄱㅅ (= thx)
### Please give me
주세요
### Here you go
여기요
### Goodbye
안녕히 계세요 - literally "stay in peace". Used when person you're saying "bye" to is staying and you're leaving
안녕히 가세요 - literally "go in peace". Used when other person is leaving (regardless if you're staying or going as well).
### Sorry (apology)
those are used as an apology, not "I'm sorry to hear that"
Phrases below mean "I am sorry I did X".
from most to least formal
- 죄송합니다
- 미안합니다
- 죄송해요
- 미안해요
- _casual territory_
- 미안해
- 미안
- ㅁㅇ (for textchat, but can be used as "sorry not sorry")
### Sorry (I'm sorry to hear that)
괜찮아질 거에요 = it's gonna be okay
너무 걱정 말아요 = don't worry too much
건강 관리 잘 해요 = take care of your health
### It's okay/I'm okay
괜찮아요
### Excuse me
죄송합니다 - "excuse me"/"I'm sorry" - often used when passing through the crows of people or when bumping into someone
실례합니다 - excuse me
### Here you go
여기요
### To like
좋아하다 = to like
### See you next time
- 다음에 봐요
- 봐요 - see you
- 다음 - next time
- 에 - time marker
### Time
- 몆시 = what time
- 지금 = now
- 내일 = tomorrow
- 오늘 = today
- 어제 = yesterday
- 정오 = midday
- 자정 = midnight
- 아까 = earlier
- 이따가 / 나중에 = later
- 이따가 집에 가고 싶어요 = I want to go home soon
- 나중에 집에 가고 싶어요 = I don't want to go home/go as late as possible
- 오래 전에 = long time ago
- -번 = -times (몇 번 = how many times)
- 자주 = often
- 얼마나 자주 = how often
- 얼마나 오래 = how long
- 항상 = always
### Days of the week
1. 월요일
2. 화요일
3. 수요일
4. 목요일
5. 금요일
6. 토요일
7. 일요일
### 계절 Season
- 봄 - spring
- 여름 - summer
- 가을 - fall, autumn
- 겨울 - winter
### This/that
#### 이 (this)
- 이 - this
- 이 물 - this water
- 이거 - this/this thing
#### 저 (that)
- 저 - that
- 저 커피 - that coffee
- 커거 - that/that thing
#### 그 (the)
- 그 - the
- 그 가방 - the bag
- 그거 - it/the one
### 날씨 Weather
- 날씨 어때요? - how is the weather?
- 하늘 - sky
- 기상예보 - weather forecast
- 첫눈 - first snow
- 화창하다 - sunny
- 흐리다 - cloudy
- 이슬비(가) 내리다/오다 - drizzle
- 바람(이) 불다 - wind/windy
- 덥다 - hot
- 따뜻하다 - warm
- 춥다 - cold
- 시원하다 - cool
- 비(가) 오다/내리다 - to rain
- 번개(가) 치다 - lightning
- 일출 - sunrise
- 일몰 - sunset
- 도 - degrees
- 13.9도 = 십삼 쩜 구 도 = 13.9C
- 저온 - low temperature
- 고온 - high temperature
- 영하 - below zero (for C)
- 습도 - humidity
- 건조하다 - dry
- 습하다 - humid
- 쌀쌀하다 - chilly
- 비가 그치다 - to stop raining
### Questions
- X + -은/는 요? - How about X?
- 누구 - who
- 누가 - which person
- 누구 예요? - who is it?
- 누가 했어요? - who did it?
- 언제 - when
- 알다 -to know
- 모르다 - to not know
- 어디 - where
- 어디 예요? - where is it?
- 네? - what?
- 뭐 - what
- 왜? - why?
- 어떻게 + verb = how + verb
- 얼마 = how much
- 얼마나 + adj = how + adj
### Really
- 조금 - a little, a bit
- 정말 - really, truly
- 진짜 - real(ly)
- 아주 - very, truly
- 별로 - (not) really (only with neg sentences)
- 전혀 - (not) at all (only with neg sentences)
### In front of/Behind/etc
- 앞 = front
- 뒤 = back
- 옆 = side
- 위 = top
- 밑, 아래 = bottom
### to be alike/the same
같다 = to be like
noun + (이)랑 = to be the same
_(with verbs)_
-(으)ㄴ/는/(으)ㄹ 것 같다
### 색, 색깔 - Colour
| colour | option1 | option2 |
| ------------ | ----------- | ------------------ |
| black | **검정**색 | 블랙 |
| blue | 파란색, 파랑 | 블루 |
| navy blue | 남색 | 네이비 |
| sky blue | 하늘색 | 연(light) 블루 |
| brown | 갈색 | 브라운 |
| dark brown | 진 갈색, 밤색 | 진 (deep, dark) 브라운 |
| gold | 금색 | 골드 |
| silver | 은색 | 실버 |
| gray | 회색 | 그레이 |
| purple | 보라색 | 퍼플 |
| green | 초록색 | 그린 |
| light green | 연두색 | |
| blue-green | 청록색, 민트색 | |
| orange | 주황색 | 오렌지 |
| pink | 분홍색 | 핑크 |
| red | 빨간색, 빨강 | 레드 |
| white | 하얀색, 흰색, 백색 | 화이트 |
| yellow | 노란색, 노랑 | 옐로우 |
| light yellow | 연노란색 | |
### Korean words similar to English
(word - 단어)
| Korean | English |
| ----------- | ------------------------------ |
| 크로와상 | croissant |
| 카페 | cafe |
| 카페 라떼 | cafe latte |
| 바닐라 라떼 | vanilla latte |
| 카라멜 라떼 | caramel latte |
| 스트로베리 프라프치노 | strawberry frappuccino |
| 카푸치노 | cappuccino |
| 아메리카노 | americano |
| 에스프레소 | espresso |
| 시나몬 롤 | cinammon roll |
| 콩글리쉬 | Konglish (Korean + English) |
| 아이쇼핑 | window shopping (eye shopping) |
| 아르바이트 | part-time job (Arbeit) |
| 모닝콜 | wake-up call (morning call) |
| 서비스 | one the house (service) |
| 린스 | har conditioner (rinse) |
### Exchanging Numbers
번호교환
- to be glad (to meet) = 반갑다
- to let (someone) know = 알려 주다 (알리다 + -아/어/여 주다)
- to let (someone) know (honorific) = 알려 드리다
- business card = 명함
- number = 번호 (specific number ex. phone, house, bus number), 숫자 (any number, ex. number 4)
- mobile phone = 핸드폰, 휴대폰, 스마트폰
- contact information = 연락처
- to save = 저장하다
- to see, to meet (honorific) = 뷥다
### 당신 (you)
Use with caution in real life conversations - "you" is rarely used, especially when speaking 존댓말 or more format language.
Uses of `당신`
1. you are **angry at someone** and do not mind fighting or arguing with that person
1. 당신 뭐야? / 너 뭐야? = who do you think you are? what are you?
2. 당신 뭐가 문제야? / 너 뭐가 문제야? = what is your problem?
2. you are **translating a foreign language** and you absolutely must have *a word for "you"*
3. you are **writing or singing a song**, or using indirect language in general
1. (both 2 and 3)
2. 당신의 눈은 참 아름다워요 = your eyes are so beautiful
3. 당신에게 이 노래를 바칩니다 = I dedicate this song to you
4. you are addressing your spouse (commonly used among middle-aged or older people)[^1]
1. 당신 지금 어디예요? = honey, where are you?
2. 당신 지금 어디야? = honey, where are you?
5. (rare case) you are talking about someone (**who is not present**) in an honorific way and *want to say "he" or "she"*
### 괜찮아요
1. Present tense = 괜찮아요
2. Past tense = 괜찮았어요
3. Future tense = 괜찮을 거예요
uses:
1. I am okay / I am alright / Everything is fine [^4]
2. Do not worry [^5]
3. It is good [^6]
4. I'm good / I'm cool/ No, thanks [^7]
### Slang
- 맞을래? - do you want to be hit? [^8]
- 죽을래? - do you want to die? [^8]
### Sometimes, Often, Always, Seldom, Never, Almost
Usually they go right before the verb, but their position is very flexible. As long as the meaning of the sentence is clear, it does not matter where they are placed, **but** certain part of a sentence can be emphasized.
- 가끔 - sometimes
- 자주 - often
- 항상 - always
- 맨날 - (lit. every day) all the time, always[^13]
- 매일 - every day
- 별로 - seldom, rarely, not much
- 전혀 = not at all
- 거의 = almost (but) not at all[^14]
### Word contractions
Used to make speech faster. If used in text - very informal
#### -은/-는
- 저는 -> 전[^15]
- 나는 -> 난
- 우리는 -> 우린
- 이것은 (v formal) -> 이거는 (casual) -> 이건 (casual)
- 서울에는 -> 서울엔
- 어제는 -> 어젠
#### 것이
- 이것이 -> 이게
- 저것이 -> 저게
- 그것ㅣ -> 그게
### Word builder
#### 학
**학** is related to "learning", "studying", "school"
- 학 + 생 (person, member, participant) = 학생 = student
- 학 + 교 (school) = 학교 = school
- 학 + 원 (house, garden) = 학원 = private academy
- 수 (number) + 학 = 수학 = mathematics
- 과 (subject, class, species) + 학 = 과학 = science
- 어 (word) + 학 = 어학 = language learning
- 언어 (word + word) + 학 = 언어학 = linguistics
- 경제 (economy) + 학 = 경제학 = economics
- 학 + 년 (year) = 학년 = school year (grade)
- 학 + 기 (period) = 학기 = semester
- 방 (to release, let go) + 학 = 방학 = school vacation
- 장학금 = scholarship
- 장학생 = student on a scholarship
- 복학생 = student who has returned to school (usually) after a long break, returning student
- 독학 = self-study, studying by oneself
#### 실
**실** is related to "room"
- 교 (school, teach) + 실 = 교실 = classroom
- 연습 (practice) + 실 = 연습실 = practice room
- 사무 (office work, desk job) + 실 = 사무실 = office
- 병 (disease) + 실 = 병실 = hospital room, patient's room
- 대기 (wait) + 실 = 대기실 = waiting room
- 화장 (makeup) + 실 = 화장실 = toilet, bathroom
- 분장 ((stage/theatre)makeup) + 실 = 분장실 = dressing room, backstage room (specific to stage/theatre makeup)
- 회의 (meet) + 실 = 회의실 = meeting room, conference room
- 실 + 장 (head, leader) = 실장 = head of the office
- 실 + 내 (inside) = 실내 = indoors
- 실 + 외 (outside) = 실외 = outdoors, outside
[^1]: other words that can replace 당신 in this usage are 여보 (most common) and 자기 (more common among young couples)
#### 동
동 is related to movement, move, to move
- 운 (to tranport) + 동 = 운동 = exercise, workout
- 작 (to make) + 동 = 작동 = operation (of a device)
- 활 (to flow, to be alive) + 동 = 활동 = activity[^2]
- 연 (to connect) + 동 = 연동 = linkage, interlocking[^3]
- 동 + 영(to project) + 상(image) = 동영상 = video
#### 중
중 means "center" or "middle"
- 중 + 학교 (school) = 중학교 (middle school)
- 중 + 식 (eat) = 중식 (format name for "lunch")
- 회의 (meeting, conference) + 중 = 회의중 (meeting in progress)
- 공사 (construction) + 중 = 공사중 (under construction)
[^2]: 온라인 활동 = online activities
[^3]: ex: 페이스복 연동
[^4]: ex You slip and fall and someone asks you if you are alright
[^5]: ex: your friend is worrying about something and you want to tell them to not worry
[^6]: you refer to something as "cool", "good" or "recommendable"
[^7]: your friend offers you a drink and you want to politely refuse it
[^8]: not literally, used to express annoyance or "don't" in informal way
#### 불
`부/불` means "not"
- 불 (not) + 안 (comfortable) = 불안 = anxiety, anxious[^12]
- 불안하다 >> action >> 불안하 + 아/어/여하다 = 불안해하다
- 불안해하지 마세요 = Don't be anxious
- 불 (not) + 편 (comfortable, convenient) = 불편 = inconvenient, uncomfortable
- 불 (not) + 완전 (complete) = 불완전 = incomplete
- 불 (not) + 균형 (balance) = 불균형 = imbalance
- 불 (not) + 만 (full) = 불만 = complaint[^9][^10]
- 부 (not) + 정확 (correct) = 부정확[^11] = incorrect/inaccurate
- 부 (not) + 주의 (attention) = 부주의[^11] = carelessness
- 제 부주의로 사고가 났어요 = I was careless, so it caused an accident
- 부 (not) + 당 (correct, right) = 부당[^11] = wrong, unfair, unjust
- 부 (not) + 적절 (proper) = 부적걸 = inappropriate, improper
#### 가
`가` means "family"
- 가족 = family
- 가구 = furniture
- 외가 = one's mother's paretns' home
- 가전제품 = hosehold electrical appliance
#### 장
`장` means "first" or "head"
- 부장 = department head
- 사장 = president
- 장녀 = the oldest daughter
- 회장 = chairman
#### 인
`인` means "person"
- 부인 - wife
- 연예인 - celebrity
- 인형 - doll
- 애인 - lover
#### 심
`심` means "heart"
- 관심 = interest
- 조심 = caution
- 의심 = doubt
- 자전심 = self-esteem
#### 외
`외` means "outside"
- 시외 = countryside
- 외국 = foreign country
- 외출 = go out
- 해외 = foreign country
#### 력
`력` means "power"
- 능력 = ability
- 경력 = career
- 노력 = effort
- 실력 = skill
[^9]: 저한테 불만 있어요? = Do you have any complaints against me?/Do you have a problem with me?
[^10]: 만죽 = satisfaction/be pleased
[^11]: 불 is pronounced and written as 부 when the consonant that follis is ㄷ or ㅈ
[^12]: can also mean `unstable` for example 불안해요 = It doesn't look stable
[^13]: more common in spoken
[^14]: can join other words for different meanings, e.g.: 거의 맨날 = almost every day
[^15]: warning! also a pancake

View file

@ -1,8 +0,0 @@
---
title: Korean translations
---
<status>Status: 🌱 </status>
As an attempt to boost my learning, my plan is to do some translations of media I enjoy or have gotten access to.
- [[Jaurim - Damn Ive Been Living Like This]]

View file

@ -1,9 +0,0 @@
---
title: Korean
---
<status>Status: 🌱 </status>
- [[Korean phrases]]
- [[Korean grammar]]
- [[Korean translations]]

View file

@ -1,9 +0,0 @@
<status>Status: 🌱 </status>
A bit of context:
I gotten my hands on a course that was intro to writing games with C++. While it wasn't perfect, I got some starting point and inspiration - Raylib seems low level enough to get me with "all the fun", but high enough so I don't need to manually manage all OpenGL, which felt a bit too much at a time.
I'm documenting my journey, all with wins, fails and lessons I got along the way.
1. [[make setup]]

View file

@ -1,159 +0,0 @@
---
title: Music Composition
---
<status>Status: 🌱 </status>
<details>
<summary>Table of contents</summary>
<ul>
<li><a href="#motivesphrases" class="internal-link">Motives and Phrases</a>
</li>
<li><a href="#harmonicfunction" class="internal-link">Harmonic Function</a>
</li>
<li><a href="#sentenceperiod" class="internal-link">Sentence and Period</a>
</li>
<li><a href="#harmonicrhythmseq" class="internal-link">Harmonic Rhythm and Sequence</a>
</li>
<li><a href="#secondarydominants" class="internal-link">Secondary Dominants</a>
</li>
</ul>
</details>
### Motives and Phrases {#motivesphrases}
##### Motives
- "smallest musical idea"
- usually 2-7 notes[^1]
- motive is a seed/DNA of things to come
- motives are developed
2 parts of a good motive:
1. distinct interval/shape[^2]
2. distinct rhythm
[^1]: rule of thumb - can be more, but difficult to pull off. Same with 1 note, very exceptional cases.
[^2]: distinct doesn't necessarily mean never heard before - just something that is recognisable in a piece
#### Phrases
- "complete expression of that idea[^3]"
- consists of motives
- standard phrase is 2 bars long
3 parts of a good phrase:
1. motive - no more than 3 motives
2. peak - the most something; can be lowest/highest, loudest, most disonant, etc[^4]
3. punctuation - as in writing, simplest is rest or hold a note[^5]. Important to give listener a pause
[^3]: idea = motive
[^4]: it needs to stand out and it's best to hit it only once
[^5]: good idea is to visualise someone singing and needing to take a breath
### Harmonic Function {#harmonicfunction}
Each chord in a key has a function.
For major key
| Tonic | Subdominant | Dominant |
| ----- | ----------- | -------- |
| I | ii | V |
| iii | IV | vii[^6] |
| vi | | |
C Dm Em F G Am Bdim can change to
Cmaj7 Dm7 Em7 Fmaj7 G7 Am7 Bm7(b5)
in minor key
Am Bdim C Dm Em F G
Am7 Bm7(b5)[^7] Cmaj7 Dm Em7[^8] Fmaj7 G7[^8]
[^6]: very spicy in major, beginner should avoid
[^7]: dimished here is more useful in minor, as it can be seen as "spicy subdominant chord to v"
[^8]: can be changed to E/E7 and G#dim/G#dim7 to give more pull into tonic
### Period and sentence forms {#sentenceperiod}
#### Period
- 8 bar phrase
- **basic idea**[^9] - 2 bars
- **antecedent** = basic idea + 2bars that end with half cadence[^10] - 4 bars
- **consequent** - basic idea[^11] + 2 bars that end with authentic cadence - 4 bars
- period = antecedent + consequent. It's bit like question and answer, or saying basic idea, "not sure where to go", repeat basic idea and lead somewhere satisfying.
Period is a very balanced form. ABAC is good representation of it.
#### Sentence
- also 8 bar form
- more forward directed than period
- 4 first bars -> basic idea x2[^11]
- bars 5&6 -> **continuation** -> there's "more something"[^12]
- bars 7&8 -> any cadence
because of open end it is easy to move on, but more difficult to use repetition to extend beyond 8 bars due to repetitive nature of beginning. AABC is good representation of it
[^9]: pretty harmonically stable
[^10]: contrasting idea
[^11]: can be copypaste, can introduce variation, but familiar melody **needs** to be repeated
[^12]: no matter what more, but more. Bit like with peak. Can be more chords in a bar. Can be idea expressed in 1 bar instead of 2. Can be more notes.
### Harmonic Rhythm and Sequence {#harmonicrhythmseq}
#### Harmonic rhythm
`how many chords per bar` [^13]
#### Sequence (in melody)
Take a small pattern and shift in N steps, for example
`def efg fga`[^14]
#### Harmonic Sequence
`tl;dr the same but for chords`
Examples:
- chords going down by 3rds: `C Am F Dm`
- ii V I that goes forever: `Dm7 G7 Cmaj7 Cm7 F7 Bbmaj7 Bbm7 Eb7 Abmaj7...`
very useful in continuation of sentence form
[^13]: use similar chord functions to increate chord count
[^14]: even if we shift diatonically, not exactly by the same amount, so it fits the scale, if overall shape is the same - it still counts as a sequence
### Secondary Dominants {#secondarydominants}
`tl;dr borrowing V chords from other keys that tonics are present in our key`
example:
1. in key of C we have Dm chord
2. in key of D we have A(A7) as dominant chord
3. we can "borrow" that A7 and lead into Dm even in a context of C
Basically, we can create a "pull" into any chord[^15] and add some extra color (C# in A in example above)
[^15]: except vii°

View file

@ -1,24 +0,0 @@
---
title: Signals
tags: se
---
<status>Status: 🌿 </status>
Signals, as <a class="external-link" href="https://sandimetz.com">Sandi Metz</a> calls them (not sure if she came up with the name or just passed along) is obvious in hindsight but brilliant programming tool.
Here examples will describe best what they are, so:
1. Prime/large numbers - pick arbitrary prime/large number, so it signals insignificance of a number. For example, in tests, you can write 5000 where any other number is not bigger than 10; this is a **signal** for others to not search for a meaning behind a number. Personally, I prefer `0` or large numbers instead of primes, as they are more clear on intent.
2. Strings. Same as with numbers, but there's more flexibility. For example, if I need to pass a user ETH wallet address, but it's irrelevant for testing I will go with `"0xfakeaddress"` - so it's clear that it's there just as it's needed and there's no special meaning. If it was a legit address it could make someone believe it's important.
Signals can also imply meaning. While I'm yet to find this usecase, Sandi shown this example
In Ruby code blocks can be in `{ }` or `do end`
1. code in `do end` has side effects
2. code in `{ }` has no side effects
*(note that it's not any official standard and it's not enforced by anyone or any tool)*
This is example of syntax based signal that gives clear understanding of a code (outside tests) to show what's happening even before reading the code in the code block.

View file

@ -1,42 +0,0 @@
---
title: Spectral Forge
tags: music
---
_postmortem_
Second solo ambient live I ever did.
May 2023 at <a class="external-link" href="https://festiwalswiatla.hs3.pl/ ">Festiwal Światła</a>
I took some lessons from [[Stellar Chant]] and had some more time. Biggest change was that I decided to make my own visuals (and it kinda worked, more on that later).
This time I went with 4 tracks and setup with PC (mainly due to visuals). I still had one point of failure, but had everything backed to iCloud/Dropbox so I could recover if I had at least some time.
Setup for this year:
1. Laptop with Ableton Live 11 Suite. I had samples and instruments there. I `bounced` (aka "make this an audio") almost everything I decided not to play and had MIDI clips just in case if anything goes wrong with MIDI keyboard
2. Arturia Keystep connected to laptop and Ableton to control MIDI. First concept was to change MIDI tracks for different instruments, but was scrapped.
3. SOMA Lyra-8 connected to Ableton with huge convolution reverb for basically whole 2nd track. I did a photo of Lyra setup so I could replicate it if any knob would be changed.
4. Focusright Scarlett Solo as an audio interface and output.
5. MIDI over (50m 🤯) ethernet cable to send MIDI data to change visuals.
### What went right
- I managed to learn Blender enough to do 1/4 of the visuals and they were cool
- My friend helped me with amazing AI-gen visuals for the rest of the show
- Everything worked perfectly, including MIDI over ethernet
- I had killer outfit to "transform" into MonoChromancer. This seems silly, but helped me a lot to "play character".
- Had a proper soundcheck
- Have better photo/video than last year
- <a class="external-link" href="https://album.link/s/2YVFDSW2w99MUYaijNaytQ">Actually released Spectral Forge as debut album! (even if it's not mixed as well as I would like, it's still a huge lock out of my head)</a>
- A lot of my stickers found new home
- Discovered I can manipulate volume "kinda as an extra instrument" - small changes in volume for some parts really did enhance the show
### What went wrong
- Still, even with soundcheck with folks I was too quiet. Not as bad as last time, but turns out that a lot of people do dampen the sound a lot.
- I tried rehearsing playing on Arturia before show and it turns out that by far my best take was at home composing. So I decided to ditch whole live playing for 3 tracks out of 4 - so for most part I stayed there trying to look like I'm doing something
- Out of stress I did turn wrong know on Lyra for a while and had to recover quickly during stress. It made the track bit worse
Lastly, I think I focused too much on "let's make something that will be playable live" and lost track somewhere along the lines. I kinda got lost in a quest to "make live for a festival" that I made a bit compromised version of music. At least it was eye-opening afterwards to change direction and go back to the "proper path" (aka path that actually is fun for me).
Also, it made me rethink my "all live" approach. I may come from local rock bands background, which may not necessarily translate 1:1 to ambient music.
Overall a huge net positive, especially with release out and a "wake-up call".

View file

@ -1,51 +0,0 @@
---
title: Stellar Chant
tags: music
---
_postmortem_
This was my first ever solo live and first ever ambient live.
May 2022 at <a class="external-link" href="https://festiwalswiatla.hs3.pl/ ">Festiwal Światła</a>
### How I prepared
- I talked a lot with folks and gathered informations and inspirations
- I was thinking about using Number Stations sample and got nice SkyKing recording link from my friend - decided to go with it, as it was great even without processing
- Decided to go PC-less, so I took Deluge, Korg NTS-1, looper, singing bowl and drums
- I decided to split whole thing into 3 parts:
- first, most `dark ambient` like with the sample
- second, more energy focused, with live drums
- third, more `casual generative ambient` to calm down and finish off
- I still prepared a lot of sounds in my DAW and exported WAV files to Deluge, where I would set them up in a song
- I got idea for underlying beat for part 2 from listening to clipping.
- I bounced demos with friends to get early feedback
- Got in touch with friend to create visuals and control lights
- Got in touch with other friends to do a fireshow during the second part
- Printed (in multiple copies) a "cheat sheet" to know when and what to do
### The setup
Deluge was the main "brain" of the operation. It had the whole song arranged, so I had to do there is to press play. I had one track with noisy synth to play at the end of part 2. It was connected directly to the mixer.
I had a contact mic on snare drum, that I played using brushes. This mic went to a looper (so I could do other things) that went into Korg NTS-1. Korg NTS-1 had `ensemble` effect on (to make mono signal stereo again) and heavy reverb with riser delay. I played with delay time and amount to create texture. It went to mixer as well.
I had a single mic for singing bowl, went straight into the mixer.
Lastly, there was a floor tom with cymbals (and mic to gather the sound) to play during the second part.
### What went right
- I survived
- Visuals and fireshow added a lot to the live perfomance
- I did learn a lot during all this time (more on that later)
- I managed to do it all in under a month
- I created a set that I actually really liked
- PC-less setup was actually working great. Deluge may be a small cheat thou, as it's basically a hardware DAW
### What went wrong
- I was too quiet. Definitely don't soundcheck without external help.
- I didn't test how singing bowl sounds on larger scale. Hitting it was really meh and I was to stressed to do proper sound in any other way. Quickly ditched it
- I heard myself not good enough - to the point where I lost programmed beat and was playing unevenly on drums to it.
- Fireshow was great, but when it ended and quiet, simple music slowly started to appear, many people thought it was already over.
- Visuals were on a laptop that died day before the show, so I had quickly made up ones. Lesson - always back up those. And have them with you, so you don't have to rely on external folks
- I let the momentum go away and didn't finish up live version to release as studio album. And, at this point, I will probably never will - unless I revisit it
That's it as my memory is bit fuzzy.
It was great experience, great first barrier broken and I've learned a lot to make [[Spectral Forge]] better.

View file

@ -1,12 +0,0 @@
---
title: Categories
---
<status>Status: 🌱 </status>
This is a starting point of a `graph`, I list all categories I write about here
- [[software engineering]]
- [[music]]
- [[random]]
- [[learning]]

View file

@ -1,25 +0,0 @@
---
title: Codex Vitae
tag: personal
---
<status>Status: 🌱 </status>
This is my Codex Vitae, a list of things I believe/follow in life. Feel free to take anything that resonates, but please remember those are things that work for me and may not necessarily work for you.
## people
- Don't be a dick
- Give everyone a chance, but if they turn out to be not worth the time - remove from life
- Remember about [[excuse hydra]] and avoid it.
- If you can give some value to someone with low/zero cost - do it.
- Unsolicited help/advice is worse than lack of it
## philosophy
- Stoicism seems to work really well
- Don't suffer imagined troubles - if something bad has not happened yet, it's not terrible.
- You can prepare for the bad thing thou - just don't get stressed about something
- Happiness comes from things you have control over - from the inside
- You don't have control over other people's reactions
- You do have control over your own reaction - anger is easily managed by stopping for a second before reacting
- Treat every situation like a hand in a card game - you try to play best what you're given, not complain about what you got.
- There's no "inherent fairness" to the world, some people will have better/worse start than you had - don't waste time and energy complaining about it

View file

@ -1,18 +0,0 @@
---
title: Excuse Hydra
tag: opinions
---
<status>Status: 🌱 </status>
Sometimes people will have an excuse for not doing **the thing**.
The natural instinct here is to help them dissolve the excuse, to help them. If that happens and they say "thanks!" and go their way, then good job, you did something good.
But sometimes other thing will happen - they will have another excuse ready. You cut it down too, and there's another one. That's something I call "excuse hydra" -> no matter how many excuses you defeat, there's always a new one.
My hunch here is that folks who do that don't actually want/need help - just attention. By being there and fighting with hydra, you give them that while wasting your energy and time.
While I'm not sure if that's the (only) reason for hydra to appear, what I'm sure that one should not engage with excuse hydra. As soon as you notice it - just stop fighting with it. Change topic, or end conversation. It's a waste of time and energy.
Note: there may be a lot of excuses and it will not be excuse hydra - what I've encourtered the most is excuses being "provided" very quickly, right after you get one down. If you talk with someone for 3 hrs and during that time you get 5 excuses, with some timespan in between, chances are that it's not excuse hydra.

View file

@ -1,14 +0,0 @@
---
title: Just do it
tags:
- opinions
---
<status>Status: 🌱 </status>
I have noticed interesting pattern. While two examples are not entirely enough, I decided to try to test this hypothesis when opportunity arises.
Long time ago, I decided to start writing in mirror mode. Because it's way easier for a left-handed person to write that way. I approached the challenge very `logically`. I started practicing letters, but kinda got nowhere after a while. Then I just started writing. It went way better than "dry exercise" and I've been writing like this ever since.
Second case: Korean keyboard. Same thing, I started with typing exercises etc, but then just started writing, even without Korean layout visible. I still make mistakes, but I've seen huge improvement once I started writing and not just doing rewrites.
My hypothesis here is there are skills (maybe even all?) that benefit greatly from "real world" and not "isolated exercises". Don't write letters. Write text.

View file

@ -1,11 +0,0 @@
---
title: Learning
---
<status>Status: 🌱 </status>
Here is a list of my notes done during learning various things
[[Korean]]
[[Making a game with C++ and Raylib]]
[[Music composition]]

View file

@ -1,102 +0,0 @@
<status>Status: 🌿 </status>
Because I'm a weirdo, I decided to go with terminal only development. That means no `easy mode` of going with VSCode and pressing `build` to make it work.
But it turns out (at least for start) it's not as difficult to do:
### Step one - Install Raylib
I'm on MacOS, so I just typed `brew install raylib`. You can easily get it on official website as well - https://www.raylib.com
### Step two - Prepare build
I went with a very simple Makefile, that I prepared during the course and was using for all projects there
```bash
.Phony: format
files := main.cpp
build: $(files)
clang++ -o game $(files) -Wall -std=c++14 -g -O0 -I. -I/opt/homebrew/include -L. -L/opt/homebrew/lib -lraylib -framework OpenGL
format:
clang-format -i *.cpp
clang-format -i *.h
```
(You will need clang-format to use `format` target).
Now, when I type `make`, my code is compiled and I can type `./game` to mess around.
When I type `make format` my code get's formatted.
For a brief explanation what's happening here:
- This is a Makefile, which `tldr` "helps building software"
- `.Phony:` is used to say "hey, run it always"
- `files := main.cpp` is where you define files for your c++ project
- `clang++ ...` is the compiling step
- output `game` executable, so it's possible to run `./game` and mess around
- show warnings, use c++14, all that jazz
- include all files from current directory as well as `/opt/homebrew/include`
- link all libs from current directory as well as `opt/homebrew/lib`
- (if brew was not used to install raylib, obviously the paths will change)
- `I want raylib`
- `use OpenGl`
- and `format` -> with `make format` I get formatted code, `clang-format` is needed, obviously
### Step three - render something
With following `main.cpp`
```cpp
#include "raylib.h"
int main() {
const int windowWidth = 300;
const int windowHeight = 300;
InitWindow(windowWidth, windowHeight, "Hello Raylib");
unsigned char red = 0;
unsigned char green = 117;
unsigned char blue = 44;
Color color = {};
SetTargetFPS(60);
while (!WindowShouldClose()) {
red = (red + 1) % 128;
green = (green + 2) % 128 + 128;
blue = (blue + 3) % 128;
color = {red, green, blue, 255};
BeginDrawing();
ClearBackground(WHITE);
DrawCircle(windowWidth / 2, windowWidth / 2, 50, color);
EndDrawing();
}
CloseWindow();
return 0;
}
```
Code is not pretty, but will get the job done.
So; what's happening here?
1. Creating window. Width, height and title.
2. Then, I decided to be a bit fancy and (had to look into Raylib cheatsheet) created manually a color that I will manipulate.
- Yes, those are unsigned chars, probably not most convenient way of doing that
- `Color color = {};` seems like pretty recent addition - simple, but default initialisation is something I really enjoy
4. `SetTargetFPS(60)` set's the maximum FPS the game will run.
5. `while` loop with check if `esc` was pressed or `close window` button was pressed. Pretty handy, thou for game I would have not just kill everything on simple `esc` press.
6. Do wonky color manipulation.
7. `BeginDrawing()` and `EndDrawing()` are required, to easily show what goes into a frame.
8. `ClearBackground(WHITE);`
- `WHITE` is Raylib's built in `Color` that we can use.
- this method is used to prevent screen flickering
9. Draw our circle in the middle of the screen. Left right edge is {0,0} and it increases down and right. We give it `color`, so it is `animated`.
10. Once we're out of the loop, close window and be on own's merry way.
That should give a solid headstart for some simple experimentation with Raylib - if you know how to code it should be fun exploring how this can be extended.

View file

@ -1,11 +0,0 @@
---
title: Music
---
<status>Status: 🌱 </status>
While there may be some things I will have to share about music making, this category starts as a "journaling" of my music making I may add some more stuff in the future.
- [[Stellar Chant]]
- [[Spectral Forge]]
- [[Hidden Mineral World]]

View file

@ -1,10 +0,0 @@
---
title: random
---
<status>Status: 🌱 </status>
(At least for now) a bag for all thoughts that do not fit other categories
- [[excuse hydra]]
- [[just do it]]

View file

@ -1,8 +0,0 @@
---
title: Software Engineering
---
During my years working with code I stumbled upon stories to share and some thoughts to explore. All of those will be put here
[[SOLID for FP]]
[[Signals]]

View file

@ -1,16 +0,0 @@
---
title: SOLID for FP
tags: se, fp
---
<status>Status: 🌱 </status>
I have OOP brackground and used SOLID and other OOP techniques to make my code better.
Since then I switched to FP and feel like there's not enough `guidelines` for writing FP code. At the same time I have a hunch that some of the OOP wisdom can be applied here.
- **S**ingle Responsibility Principle - this one is easy and free to take. Just make sure that your methods have "one reason to change" - a single responsobility. Make them small and specialized. Anything with `and` in name can be a sign that there's too much going on
- **O**pen Close Principle - this one is trickier, but if we say that refactoring is flow of making code open to extension - this makes things easier to adapt. Basically you want to be able to add new functionalities withtout altering existing code - and this can be achieved in FP.
- **L**iskov Substitution Principle -
- **I**nterface Segregation Principle -
- **D**ependency Inversion Principle - can be argued to go with "top level module" as main dependency, instead of more specialized ones.

View file

@ -1,27 +0,0 @@
---
layout: page
title: Home
id: home
permalink: /
---
# Welcome!
Hello! Welcome to my take on digital gardening, an entropic jungle.
Feel free to explore my brain dumps.
You may want to take a look at [[categories]]
Small legend that can be useful:
- 🌱 - very early stage - probably just dumping an idea/thought
- 🌿 - some effort put - some cleanup/clarification done
- 🌳 - "finished" - this *does not* mean that this won't be ever edited. But it means I spent a lot of time and **probably** won't touch it
<style>
.wrapper {
max-width: 46em;
}
</style>

View file

@ -1,111 +0,0 @@
# frozen_string_literal: true
class BidirectionalLinksGenerator < Jekyll::Generator
def generate(site)
graph_nodes = []
graph_edges = []
all_notes = site.collections['notes'].docs
all_pages = site.pages
all_docs = all_notes + all_pages
link_extension = !!site.config["use_html_extension"] ? '.html' : ''
# Convert all Wiki/Roam-style double-bracket link syntax to plain HTML
# anchor tag elements (<a>) with "internal-link" CSS class
all_docs.each do |current_note|
all_docs.each do |note_potentially_linked_to|
note_title_regexp_pattern = Regexp.escape(
File.basename(
note_potentially_linked_to.basename,
File.extname(note_potentially_linked_to.basename)
)
).gsub('\_', '[ _]').gsub('\-', '[ -]').capitalize
title_from_data = note_potentially_linked_to.data['title']
if title_from_data
title_from_data = Regexp.escape(title_from_data)
end
new_href = "#{site.baseurl}#{note_potentially_linked_to.url}#{link_extension}"
anchor_tag = "<a class='internal-link' href='#{new_href}'>\\1</a>"
# Replace double-bracketed links with label using note title
# [[A note about cats|this is a link to the note about cats]]
current_note.content.gsub!(
/\[\[#{note_title_regexp_pattern}\|(.+?)(?=\])\]\]/i,
anchor_tag
)
# Replace double-bracketed links with label using note filename
# [[cats|this is a link to the note about cats]]
current_note.content.gsub!(
/\[\[#{title_from_data}\|(.+?)(?=\])\]\]/i,
anchor_tag
)
# Replace double-bracketed links using note title
# [[a note about cats]]
current_note.content.gsub!(
/\[\[(#{title_from_data})\]\]/i,
anchor_tag
)
# Replace double-bracketed links using note filename
# [[cats]]
current_note.content.gsub!(
/\[\[(#{note_title_regexp_pattern})\]\]/i,
anchor_tag
)
end
# At this point, all remaining double-bracket-wrapped words are
# pointing to non-existing pages, so let's turn them into disabled
# links by greying them out and changing the cursor
current_note.content = current_note.content.gsub(
/\[\[([^\]]+)\]\]/i, # match on the remaining double-bracket links
<<~HTML.delete("\n") # replace with this HTML (\\1 is what was inside the brackets)
<span title='There is no note that matches this link.' class='invalid-link'>
<span class='invalid-link-brackets'>[[</span>
\\1
<span class='invalid-link-brackets'>]]</span></span>
HTML
)
end
# Identify note backlinks and add them to each note
all_notes.each do |current_note|
# Nodes: Jekyll
notes_linking_to_current_note = all_notes.filter do |e|
e.content.include?(current_note.url)
end
# Nodes: Graph
graph_nodes << {
id: note_id_from_note(current_note),
path: "#{site.baseurl}#{current_note.url}#{link_extension}",
label: current_note.data['title'],
} unless current_note.path.include?('_notes/index.html')
# Edges: Jekyll
current_note.data['backlinks'] = notes_linking_to_current_note
# Edges: Graph
notes_linking_to_current_note.each do |n|
graph_edges << {
source: note_id_from_note(n),
target: note_id_from_note(current_note),
}
end
end
File.write('_includes/notes_graph.json', JSON.dump({
edges: graph_edges,
nodes: graph_nodes,
}))
end
def note_id_from_note(note)
note.data['title'].bytes.join
end
end

View file

@ -1,22 +0,0 @@
# frozen_string_literal: true
class TweetEmbedGenerator < Jekyll::Generator
def generate(site)
return if !site.config["embed_tweets"]
all_notes = site.collections['notes'].docs
all_pages = site.pages
all_docs = all_notes + all_pages
all_docs.each do |current_note|
current_note.content.gsub!(
/^https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(\d+)$/i,
<<~HTML
<blockquote class="twitter-tweet">
This tweet could not be embedded. <a href="#{'\0'}">View it on Twitter instead.</a>
</blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
HTML
)
end
end
end

View file

@ -1,18 +0,0 @@
# frozen_string_literal: true
EMPTY_FRONT_MATTER = <<~JEKYLL
---
---
JEKYLL
# Inject empty front matter in notes that don't have any
Jekyll::Hooks.register :site, :after_init do |site|
Dir.glob(site.collections['notes'].relative_directory + '/**/*.md').each do |filename|
raw_note_content = File.read(filename)
unless raw_note_content.start_with?('---')
raw_note_content.prepend(EMPTY_FRONT_MATTER)
File.write(filename, raw_note_content)
end
end
end

View file

@ -1,18 +0,0 @@
# frozen_string_literal: true
# Turns ==something== in Markdown to <mark>something</mark> in output HTML
Jekyll::Hooks.register [:notes], :post_convert do |doc|
replace(doc)
end
Jekyll::Hooks.register [:pages], :post_convert do |doc|
# jekyll considers anything at the root as a page,
# we only want to consider actual pages
next unless doc.path.start_with?('_pages/')
replace(doc)
end
def replace(doc)
doc.content.gsub!(/==+([^ ](.*?)?[^ .=]?)==+/, "<mark>\\1</mark>")
end

View file

@ -1,28 +0,0 @@
# If the configuration sets `open_external_links_in_new_tab` to a truthy value,
# add 'target=_blank' to anchor tags that don't have `internal-link` class
# frozen_string_literal: true
require 'nokogiri'
Jekyll::Hooks.register [:notes], :post_convert do |doc|
convert_links(doc)
end
Jekyll::Hooks.register [:pages], :post_convert do |doc|
# jekyll considers anything at the root as a page,
# we only want to consider actual pages
next unless doc.path.start_with?('_pages/')
convert_links(doc)
end
def convert_links(doc)
open_external_links_in_new_tab = !!doc.site.config["open_external_links_in_new_tab"]
if open_external_links_in_new_tab
parsed_doc = Nokogiri::HTML(doc.content)
parsed_doc.css("a:not(.internal-link):not(.footnote):not(.reversefootnote)").each do |link|
link.set_attribute('target', '_blank')
end
doc.content = parsed_doc.inner_html
end
end

View file

@ -1,76 +0,0 @@
.highlight {
background: #f8f8f8;
padding: 1px 1em;
border-radius: 3px;
font-size: 1em;
font-size: 0.9em;
overflow: auto;
margin: 1em -1em;
code{
padding: 0;
}
}
div.highlight {
display: grid;
}
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */

View file

@ -1,338 +0,0 @@
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View file

@ -1,166 +0,0 @@
$color-primary: hsl(0, 0%, 10%);
$color-text: hsl(0, 0%, 20%);
$color-subtext: hsl(0, 0%, 30%);
$color-border: hsl(0, 0%, 85%);
$color-box-background: mix($color-primary, white, 4%);
$border-radius: 4px;
$font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
body {
box-sizing: content-box;
font-family: $font-family;
margin: 0 auto;
line-height: 1.7;
padding: 4vh 6vw;
overflow-x: hidden;
color: $color-text;
font-size: 1rem;
max-width: 63em;
@media (min-width: 820px) {
font-size: 1.2rem;
}
}
time {
display: block;
color: $color-subtext;
margin: 0.5em 0 1em;
}
footer {
margin: 2em 0;
font-size: 0.8em;
color: mix($color-text, white, 80%);
padding-top: 1em;
}
graph {
font-size: 0.8em;
color: mix($color-text, white, 80%);
margin: 2em 0;
}
status {
font-size: 0.8em;
color: mix($color-text, white, 80%);
margin: 2em 0;
}
img {
max-width: 100%;
display: block;
margin: 0 auto;
max-height: 75vh;
border-radius: $border-radius;
}
blockquote {
padding: 1.5em;
margin: 0;
font-size: 0.88em;
background: $color-box-background;
border-radius: $border-radius;
p {
margin: 0;
}
}
hr {
width: 100%;
border: 0;
height: 1px;
margin: 1.5em 0;
background: $color-border;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.3;
margin-bottom: 0;
padding-bottom: 0;
}
a {
transition: background 300ms;
padding: 0 0.1em;
text-decoration: none;
border-bottom: 1px solid $color-border;
color: $color-primary;
&:hover {
color: black !important;
background: #fffaf1;
}
&:after {
position: relative;
top: -0.5em;
font-size: 0.7em;
content: "";
color: #aaaaaa;
}
&.internal-link:after,
&.footnote:after,
&.reversefootnote:after {
content: "";
}
}
*:focus {
background: #ffe8bc !important;
color: black !important;
}
nav {
margin: 1em 0 3em;
}
#notes-entry-container {
display: grid;
grid-gap: 2em;
grid-template-areas:
"content"
"side";
@media (min-width: 700px) {
grid-template-columns: 3fr 1fr;
grid-template-areas: "content side";
}
}
.backlink-box {
background: $color-box-background;
padding: 1em;
border-radius: $border-radius;
}
code {
background: #f5f5f5;
padding: 0.1em 0.2em;
border-radius: 4px;
}
.invalid-link {
color: #444444;
cursor: help;
background: #fafafa;
padding: 0 0.1em;
}
.invalid-link-brackets {
color: #ccc;
cursor: help;
}
th, td {
border: 1px solid;
}
table {
border-collapse: collapse;
}

View file

@ -1,10 +1,3 @@
---
layout: page
title: About
permalink: /about
---
Hi I'm <a class="external-link" href="https://dreat.info">dreat</a>. Hi I'm <a class="external-link" href="https://dreat.info">dreat</a>.
I'm a Software Monk, Drummer and Ambient creator. I'm a Software Monk, Drummer and Ambient creator.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 MiB

View file

@ -8,7 +8,7 @@
See http://github.com/Dynalon/mdwiki for a copy of the source code. See http://github.com/Dynalon/mdwiki for a copy of the source code.
--> -->
<head> <head>
<title>MDwiki</title> <title>Entropic Jungle</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="fragment" content="!"> <meta name="fragment" content="!">
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" /> <link rel="shortcut icon" type="image/x-icon" href="favicon.png" />

View file

@ -1,4 +1,5 @@
# Entropic Jungle # Entropic Jungle
[Home](index.md)
[Home](index.md) [Categories](notes/categories.md)
[About](about.md)

View file

@ -1,3 +0,0 @@
[build]
command = "jekyll build --trace"
publish = "_site"

View file

@ -1,6 +0,0 @@
---
---
@import "../_sass/normalize";
@import "../_sass/code";
@import "../_sass/style";