Skip to main content

Waypoint (Obsidian Plugin)

· 3 min read

The Waypoint plugin automatically generates an index listing for a Folder Note.

It's useful for folks who prefer to organize their vaults with folders. If you prefer a flat folder structure you won't get as much out of it.

Unlike many Obsidian plugins, it makes permanent changes to the content (contrast e.g. DataView) so the listing will continue to work event if you uninstall the plugin.

How it works

You add a special Obsidian comment to a folder note, which the plugin will expand into an index listing, and keep up to date.

By default, the flag word is "Waypoint" but this is customizable. In this example, I will use the word "Flag" instead, so that the plugin doesn't try to expand the example.

If you have these files:

$ tree /path/to/folder-note/
folder-note
├── folder-note.md
├── note1.md
├── note2
│ ├── note2.md
│ └── note2-1.md
└── note3.md

And folder-note.md has the following content:

# Folder Note
## Index
%% Flag %%

And note2.md has the following content:

# Note 2
## Index
%% Flag %%

The plugin will expand the comment in folder-note into the following listing, and bold any child waypoints it finds:

# Folder Note
## Index
%% Begin Flag %%
- [[note1]]
- **[[note2]]**
- [[note3]]
%% End Flag %%

Waypoints and Landmarks

In addition to standard Waypoints, the plugin also understands a variant they call "Landmarks".

When it encounters a Waypoint, it links to that note, and stops. You can see this in the example above, with note2. (The example assumes that note2.md also contains a waypoint.)

When it encounters a Landmark, it links to that folder note but continues listing that notes sub-notes as well.

The "Landmark" behavior is used by default for child folder-notes which do not specify either type of flag.

So, if note2 contained a landmark instead of a waypoint, then folder-note.md would have expanded to this instead:

# Folder Note
## Index
%% Begin Flag %%
- [[note1]]
- **[[note2]]**
- [[note2-1]]
- [[note3]]
%% End Flag %%

Quirks

I've noticed a few quirks related to the "Use Title Property" setting:

  • leaf nodes (regular notes) will use the title property as the display text for the link (e.g. [[note1|Display Text]]), but parent nodes (folder notes) will not.
  • This one is a maybe: There is some churn in the index when working on mobile, where it will flip between using or not setting the display text.
    • I am not certain this is real churn. This setting wasn't always available, and it seems to happen randomly with files I wasn't actually working on, plus I have better automation on desktop. So it's entirely possible that this is happening all the time and I only notice it on mobile.

Synergy with other plugins

  • Supports the title front matter property, so it works well with [[2024-07-26-front-matter-title-plugin]]

How to update front matter via Templater templates

· One min read

[[TemplaterPlugin|Templater (Obsidian Plugin)]] doesn't have a straightforward way to update the front matter of a note that already has content in it. However, you can use the native Obsidian API within a template to achieve the same thing.

Side note: this code block keeps getting wiped out. I had thought it was due to transitioning back to submodules. Now, I'm pretty sure it's due to the Templater setting to evaluate templates on file creation, so I removed the Templater delimiters. Put this snippet into a < %* % > block.

// When creating a new file, we would create a race condition between Templater and the native Obsidian APIs we're using here.
// We can circumvent that by utilizing hooks.
tp.hooks.on_all_templates_executed(async () => {
const file = tp.file.find_tfile(tp.file.path(true));
await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
frontmatter["day"] = [`[[${tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD")}]]`]
let tags = frontmatter["tags"] ?? []
tags += "Meetings/Scrum";
frontmatter["tags"] = tags;
});
});

References

Issues with using subtrees in my notes

· 3 min read

I manage my notes with Obsidian and store them in git. I have some notes that I share between home and work, and others that I only access via personal devices. I used to manage these shared notes with submodules, but recently switched so sub trees. However, I ran into some issues that have me considering switching back to submodules.

How to ensure front matter exists in Markdown files

· 3 min read

YQ supports operating and transforming YAML front matter via the --front-matter flag.

For example, when using a file that has front matter, yq can extract the YAML correctly:

$ yq --front-matter=extract '.' ./with-frontmatter.md.txt
---
key: value

However, it behaves unexpectedly when the file does not have any front matter.

Prototype: Fallout hacking buddy

· 4 min read

Fallout is one of my favorite game series. The hacking minigame isn't bad, but there is a lot of it, so it can get tedious. The purpose of this tool is to simplify solving the minigame.

The "perfect" version of this tool would be the following:

  • When I come across a locked terminal in game, I snap a photo of the screen with my phone
  • That photo is automatically converted to a game board in the tool
  • When I make a guess in the game, I enter the "Likeness" reported by the game, into the tool
  • The tool would then analyze what we know so far, and automatically eliminate certain candidates

The main thing I care about right now is the logic to iteratively eliminate candidates.

Bash

· 4 min read

Handling unset or empty variables

Syntax

  • + -- if the variable is set, use the substitution
  • - -- if the variable is not set, use the substitution
  • : -- handle empty string as though it were unset

Table

unset VARexport VAR=''export VAR='x'
echo ">${VAR+y}<"><>y<>y<
echo ">${VAR:+y}<"><><>y<
echo ">${VAR-y}<">y<><>x<
echo ">${VAR:-y}<">y<>y<>x<

When the variable is not set

$ unset VAR
$ echo ">${VAR+y}<"
><
$ echo ">${VAR:+y}<"
><
$ echo ">${VAR-y}<"
>y<
$ echo ">${VAR:-y}<"
>y<

When the variable is set to empty string

$ export VAR=''
$ echo ">${VAR+y}<"
>y<
$ echo ">${VAR:+y}<"
><
$ echo ">${VAR-y}<"
><
$ echo ">${VAR:-y}<"
>y<

When the variable is set to a non-empty string

$ export VAR='x'
$ echo ">${VAR+y}<"
>y<
$ echo ">${VAR:+y}<"
>y<
$ echo ">${VAR-y}<"
>x<
$ echo ">${VAR:-y}<"
>x<

(bash:unofficial-strict-mode)=

Unofficial "Strict Mode"

TL;DR

#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

Explanation

  • set -e option - cease execution on first error
  • set -u option - treat undefined variables as an error
  • set -o pipefail option - treat an error in any sub-command within a pipeline as a failure of the whole pipeline

Colors Cheat Sheet

Regular Colors

ValueColor
\e[0;30mBlack
\e[0;31mRed
\e[0;32mGreen
\e[0;33mYellow
\e[0;34mBlue
\e[0;35mPurple
\e[0;36mCyan
\e[0;37mWhite

Bold

ValueColor
\e[1;30mBlack
\e[1;31mRed
\e[1;32mGreen
\e[1;33mYellow
\e[1;34mBlue
\e[1;35mPurple
\e[1;36mCyan
\e[1;37mWhite

Underline

ValueColor
\e[4;30mBlack
\e[4;31mRed
\e[4;32mGreen
\e[4;33mYellow
\e[4;34mBlue
\e[4;35mPurple
\e[4;36mCyan
\e[4;37mWhite

Background

ValueColor
\e[40mBlack
\e[41mRed
\e[42mGreen
\e[43mYellow
\e[44mBlue
\e[45mPurple
\e[46mCyan
\e[47mWhite

High Intensity

ValueColor
\e[0;90mBlack
\e[0;91mRed
\e[0;92mGreen
\e[0;93mYellow
\e[0;94mBlue
\e[0;95mPurple
\e[0;96mCyan
\e[0;97mWhite

Bold High Intensity

ValueColor
\e[1;90mBlack
\e[1;91mRed
\e[1;92mGreen
\e[1;93mYellow
\e[1;94mBlue
\e[1;95mPurple
\e[1;96mCyan
\e[1;97mWhite
===

High Intensity backgrounds

ValueColor
\e[0;100mBlack
\e[0;101mRed
\e[0;102mGreen
\e[0;103mYellow
\e[0;104mBlue
\e[0;105mPurple
\e[0;106mCyan
\e[0;107mWhite

Reset

ValueColor
\e[0mReset

References

IPv4

· One min read
  • allows for 2^32^ addresses (~4.3 billion)

Terms

  • "snet" = "source network"
  • "dnet" = "destination network"

Subnets

  • The initial octets specify the network, while the remaining octets specify the host.
  • Private subnet
    • means the default route is a NAT Gateway
    • the snet will be the public IP of the NAT Gateway
  • Public subnet
    • means the default route is an Internet Gateway

The Math

Classes

  • A
  • B
  • C
  • D
  • E

Special Addresses

  • 127.0.0.1: loopback, i.e. localhost

Private networks

  • 10.0.0.1 - 10.255.255.255
  • 172.16.0.0 - 172.31.255.255
  • 192.168.0.0 - 192.168.255.255

Network Engineering

· One min read
:glob:
*

Terms and abbreviations

  • BGP
    • short-for:: Border Gateway Protocol
    • How routers communicate with one another
  • SNI
    • short-for:: Server Name Indicator
  • SAN
    • short-for:: Subject Alternative Name
  • Dual Stack Networking
    • When your network supports both IPv4 and IPv6

Launch with Docusaurus

· One min read

I have been meaning to create a blog for a while, but I keep procrastinating--usually by overthinking which technology to use.