Compare commits

...
Sign in to create a new pull request.

613 commits

Author SHA1 Message Date
26dc35e0d0 Mushrooms photo post 2025-08-31 07:45:30 -06:00
f95940c387 Lake Louise photo post 2025-08-31 07:44:49 -06:00
588d88a0b2 Student Again post 2025-08-31 07:39:02 -06:00
1d15db8aa5 I Am an AI Hater link post 2025-08-29 09:14:24 -06:00
2688e4e339 Add a deployment command group to the website script
This group has one command so far: next-tag. It looks at the git tag list and
figured out the next deployment tag. For the most part tags are named like so:

    deploy-%Y-%m-%d-NN

The middle segments are year-month-day, and the last segment is an incrementing
counter. For the most part this number will be 01. On days when I deploy more than
once, it will increment.
2025-08-29 08:59:03 -06:00
69760a802d Lait's Go photo post 2025-08-28 17:13:40 -06:00
294226cfcb Remove Travel category; move it to a tag 2025-08-28 11:25:53 -06:00
ea6eea2b03 Add link archetype 2025-08-28 11:24:51 -06:00
459c55d344 Remove Travel category from Pajaro Dunes post; make it a tag 2025-08-28 11:24:38 -06:00
c9d7c6409e Create a Links category for two recent links posts 2025-08-28 11:23:58 -06:00
33da073783 Update photostream submodule 2025-08-28 11:08:37 -06:00
ee9dc5c9ea Update termlite submodule commit 2025-08-28 08:17:00 -06:00
c2d860a64d Rings post 2025-08-28 07:51:28 -06:00
c878785635 Weeknotes from 2025W06
Why am I so late with this one?? It's not even marked draft anymore.
2025-08-28 07:40:51 -06:00
0e2b3eb249 2026 _index.md 2025-08-28 07:39:40 -06:00
9633b85411 Move photos content path in new-photo-post script to erynwells_me module 2025-08-28 07:37:05 -06:00
24871ecf49 {{ stock }} shortcode for linking to a finance page for a stock ticker symbol 2025-08-28 07:23:13 -06:00
eb9d763638 America Tips Into Fascism link 2025-08-28 07:21:24 -06:00
2016028811 Weeknotes for 2025 week 34 2025-08-25 22:24:12 -06:00
493947028c Mercury @ Valkyries game post 2025-08-21 23:12:24 -07:00
24c61c8cdf Remove title from Not Doing It figure 2025-08-19 10:10:41 -07:00
a8c30e1c90 Update termlite submodule 2025-08-19 10:08:33 -07:00
b57fd9c8d0 Commit the weeknotes for 2025W33 post 2025-08-19 10:05:48 -07:00
1f2de30c60 Pass the list of images generated by the figures/image template to the partials that actually render the figure
This template was doing a bunch of work to look up resources, but then
discarding it and passing just the "name" to the partial. Instead, pass the
$imgs list.

Add a "global-asset-src" parameter to the shortcode that takes an asset path.

Update the termlite submodule commit.
2025-08-19 10:03:50 -07:00
cc405e6ca9 Cat House photo;
Fix up the sort date for the 2025 collection of photo posts.
2025-08-17 16:07:38 -07:00
724f2a37d4 Fix a typo in the MatrixPortal post 2025-08-17 09:32:08 -07:00
86259d788c Update sunset timelapse in the Jackson Hole post 2025-08-17 09:27:05 -07:00
2bad4f9b08 MatrixPortal Metaballs post 2025-08-16 17:26:37 -07:00
85de90bcd3 Add .mov and .mp4 to the LFS attributes 2025-08-16 17:26:21 -07:00
5a0dcb8a7d Rename twitter config settings -> x (ugh) 2025-03-19 11:52:54 -07:00
bef5ab71ce blog: CRT Typography 2025-02-08 08:24:38 -08:00
1c78ce3627 blog: Weeknotes 2025W03: Fix a broken link; add space links 2025-01-20 10:30:26 -08:00
a777b1e726 Weeknotes for 2025W03 2025-01-20 10:24:16 -08:00
64e8aa20d5 Update the weeknotes archetype
Add "Notes on" to the title
Remove the time from the date
2025-01-14 19:31:35 -08:00
49d8e069db blog: 37 birthday post! 2025-01-14 19:31:12 -08:00
f2e835cea5 termlite: Update submodule commit 2025-01-14 19:30:20 -08:00
65410d9de5 photos: Moon and Venus 2025-01-11 10:34:32 -08:00
fd890b7486 blog: Fixing Up Japanese Language Tags
Finish it. Publish.
2025-01-08 20:39:46 -08:00
741163dac8 termlite: Update submodule commit 2025-01-07 15:37:38 -08:00
89abc0b8ee Convert tags added in 5989af5e64 to page bundles
If you added a tag to content/tags/$name as a flat .md file, it won't show the
list of posts under it. If you add them as a bundle, i.e. a directory with a
_index.md, it does.

This is weird to me but whatever.
2025-01-07 15:35:36 -08:00
b732238c20 blog: Fixing Up Japanese Language Tags (draft) 2025-01-07 15:34:16 -08:00
a761f45afd blog: Replace 日本語 tag with "japanese" tag in weeknotes-2024w24 2025-01-07 09:08:58 -08:00
9e2e49d944 blog: Add "recipes" tag to Cat in the Cream Cookies recipe post 2025-01-07 09:08:19 -08:00
5989af5e64 Move all the Japan related tags to ASCII characters
Replace tags like "京都" to "japan-kyoto". Prefix place tags with country names so they're easier to find.
2025-01-07 09:06:20 -08:00
264a828089 blog: Add a description to the termlite post 2025-01-07 08:36:23 -08:00
9d50a93313 blog: Use .ByPublishDate for the blog list 2025-01-07 08:35:04 -08:00
b463f8df64 blog: Notes on 2025w01 (remove draft tag) 2025-01-06 10:46:21 -08:00
471a63463b blog: Notes on 2025W1 2025-01-06 10:44:33 -08:00
e123b3c38e blog: Christmas in Massachusetts 2025-01-06 10:44:13 -08:00
c25987e3c5 tags: Hawai‘i page
To get the glottal stop right.
2025-01-05 09:32:09 -08:00
7fd193d723 photos: Kona, HI beach 2025-01-05 09:31:49 -08:00
78628c2243 blog: Fix the slug of the 2024 books post 2025-01-05 08:27:03 -08:00
dc09f14cc1 termlite: Update submodule commit 2025-01-04 10:13:09 -08:00
a3b33970ed blog: Japan trip placeholder 2025-01-04 09:41:29 -08:00
6f3a30cf4b Add Facebook and StoryGraph to Where Am I
Update the sorting and add a bit more explanatory text around these lists.
2025-01-04 09:41:07 -08:00
712d40177d Add the "Weeknotes" tag to the weeknotes archetype 2025-01-04 09:35:04 -08:00
fd51d2405c blog: Fix a typo in the Qud post 2025-01-04 09:34:19 -08:00
fa19112a4b blog: Add a couple books to the 2025 books list
- On A Sunbeam
- The Selected Poems of Nikki Giovanni
2025-01-04 09:34:06 -08:00
bf0c8a583a blog: Move the "Catching Up" post to 2025 2025-01-03 12:27:41 -08:00
7807e901f7 blog: Termlite (draft) 2025-01-03 11:53:06 -08:00
01d2e7f471 photos: No Matter 2025-01-03 11:52:45 -08:00
55b89dfc93 blog: Qud: add title and alt text to the loading screen image 2025-01-01 11:21:00 -08:00
534c5fa984 blog: Qud 2025-01-01 11:17:30 -08:00
b0f7385daf blog: 2025
New year, mutherfuckers
2025-01-01 10:51:38 -08:00
6db1174a21 scripts: Include os.path as osp in new-photo-post 2025-01-01 10:46:53 -08:00
22dbdceab3 scripts: Return the result of calling the args handler 2025-01-01 10:46:14 -08:00
9db2f3a49b blog: 2024w25 weeknotes 2025-01-01 10:45:52 -08:00
d37d924219 blog: Remove category from Chicago post 2025-01-01 10:45:39 -08:00
0877f504b3 about: Clean up the markup a little bit
I'm still not happy with the circular image. It's not aligned like I would like.
2025-01-01 10:44:57 -08:00
3f436085a3 blog: 2024 Books 2025-01-01 10:42:52 -08:00
eb0a6b0da9 blog: Eclipse, Chicago, and Catching Up posts 2025-01-01 10:42:36 -08:00
a1c22b3491 Clean up partial calls in figures/image
- Include the custom class passed to the template
- Factor out multiple computations of $shouldShowTitle into a variable and pass that
  to called partials
2024-12-31 09:39:46 -08:00
734fe626a3 blog: Books I Read
Added Full Moon Coffee Shop
2024-12-28 21:18:54 -05:00
6ae0590721 blog: Departure Mono 2024-12-28 08:34:33 -05:00
74d4c1a508 blog: Catching Up 2024-12-23 08:45:52 -08:00
4d066582b8 blog: Add a description to the Eclipse post 2024-12-23 08:42:50 -08:00
2061992be1 blog: Chicago 2024-12-23 08:42:38 -08:00
ec13456966 blog: Eclipse 2024-12-23 08:25:57 -08:00
807927a0de termlite: Update submodule commit 2024-12-23 08:13:46 -08:00
e7440684d7 blog: Moon 2024-12-22 15:28:45 -08:00
b9796ab096 When editing weeknotes with the website script, create the page from the Hugo archetype and process it
This implements what the Makefile did, but with a more intuitive interface.
Remove the weeknotes target from the Makefile.
2024-12-10 12:16:23 -08:00
8ec88e6c80 blog: Weeknotes for 2024W49 2024-12-10 11:05:47 -08:00
cc98666b2d blog: Make Pattern Rules 2024-12-05 17:26:55 -08:00
f6955df4f9 blog: Weeknotes for 2024W48 2024-12-01 15:18:32 -08:00
6b8cb0fb22 blog: Milk Bread Rolls 2024-12-01 14:29:07 -08:00
a90ebf15f6 termlite: Update submodule commit 2024-11-26 13:44:41 -07:00
b2eb00a0a8 photostream: Update submodule commit 2024-11-26 08:57:34 -07:00
11d8ac0b07 blog: Weeknotes for 2024W47 2024-11-26 08:45:07 -07:00
bb2e56cb47 blog: Remove draft flag from Orlando Pride post 2024-11-26 08:43:35 -07:00
80d1f8106a blog: Restore the two column layout on Netscape Meteors
At the bottom of this post is a two-column layout showing two versions of the
meteors spinner. I broke that in a previous commit and this commit brings it back.

Use the new content-grid shortcode (implemented in the submodule commit) to render
a two-column grid.
2024-11-26 08:39:50 -07:00
052152193d termlite: Update submodule commit 2024-11-25 15:57:01 -08:00
6edd649fb6 termlite: Update submodule commit 2024-11-25 15:48:15 -08:00
9e0df5797b blog: 2024 Books post
Add Fingersmith
2024-11-25 09:53:32 -08:00
622c09c472 blog: Orlando Pride post (draft) 2024-11-25 09:53:09 -08:00
7ab4ae1864 tags: an NWSL tag that expands to the name of the league 2024-11-25 09:52:43 -08:00
e3b93e5e0f Rewrite the figures/image template to use the new figures in the termlite theme 2024-11-25 09:52:22 -08:00
73aaf24f91 blog: TDoR 2024 2024-11-21 08:21:06 -08:00
3b4297c335 termlite: Update submodule commit 2024-11-19 20:53:38 -08:00
84fce9d862 blog: TDoR 2024 (draft) 2024-11-18 17:03:21 -08:00
ace538d953 blog: Weeknotes for 2024W47 (draft) 2024-11-18 17:03:13 -08:00
a9f52aad98 Rework a bunch of scripts into a single website script 2024-11-18 14:59:43 -08:00
f83c6ebbe5 blog: Cat in the Cream Cookies 2024-11-18 11:47:00 -08:00
b7fb364862 Meta: Avoid an IndexError with .get() instead of indexing in the weeknotes script
Replace indexing into the os.environ dictionary with a .get() call (and a default)
to avoid an IndexError
2024-11-18 08:05:22 -08:00
2d6912aed2 Add a --edit argument to the new-photo-post script 2024-11-17 14:51:39 -08:00
9ce6362402 Meta: Port several things common to various Python scripts to a new website module 2024-11-17 14:49:33 -08:00
a30903c8cf blog: 2024W25 Weeknotes 2024-11-17 14:47:58 -08:00
8afadd8379 blog: Remove draft flag from 2024W46 Weeknotes 2024-11-17 14:47:30 -08:00
dd2eec20bc blog: Books I Read in 2024 (draft) 2024-11-16 09:42:50 -08:00
f82a864f5e blog: Weeknotes for 2024W46 (draft) 2024-11-16 09:42:04 -08:00
a5093be13a termlite: Update submodule commit 2024-11-16 09:41:43 -08:00
96410c903c Add a custom .paragraph-spaced-list class
This class spaces its list elements with the standard paragraph spacing.
2024-11-15 20:58:37 -08:00
a968c9cb78 Add a <hr> to the test page 2024-11-15 07:34:01 -08:00
8105b0e16b Improve the handling of whitespace in template code
resource-builders: Update submodule commit
2024-11-14 08:49:52 -08:00
122e55b1fa blog: Rubiks' Cube Scrambler post
Implement the rubiks-cube-scrambler custom element, including JS and template
files. Put these things in the body-extras.html partial that the termlite theme
added.

resource-builders: Update submodule commit
termlite: Update submodule commit
2024-11-13 17:06:01 -08:00
cb16a35020 photos: Publish the Niagara posts (remove draft flag) 2024-11-11 08:33:27 -08:00
11d4dcd590 photos: Niagara Falls posts 2024-11-09 12:57:45 -08:00
1f53428932 termlite: Update submodule commit 2024-11-07 09:18:12 -08:00
d87438bf6a Add a few characters to the list of ones to strip out of strings when slugifying a title 2024-11-07 09:18:12 -08:00
f47c41a80d photostream: Update submodule commit 2024-11-07 09:18:12 -08:00
0cebee344a photos: Devil's Slide posts 2024-11-07 09:18:11 -08:00
d59f2e0a69 blog: Add citation and caption to Ay Carmela post
Update termlite submodule.
Enable block and title attributes in the Hugo renderer.
2024-11-06 09:32:12 -08:00
2104b5354b blog: Ay Carmela
Update termlite submodule with pre-formatted block styles.
2024-11-06 09:04:24 -08:00
0b67da2557 photos: Bay FC Home Opener post 2024-11-05 08:56:49 -08:00
8483704e73 Remove drafts from the production dev server 2024-11-04 16:53:03 -08:00
15bec870da Add the Coit Tower photo
Rename the first Fairmont photo to match the title and slug. I originally called
it the Freemont Hotel, which is wrong.
2024-11-04 16:52:02 -08:00
8cb1187aaa Do not build drafts
Too much trouble.
2024-11-04 16:38:29 -08:00
7d50f86bcf Remove the /now reference on the home page
/now is still a draft.
2024-11-04 16:37:40 -08:00
32c41daea1 Remove the explicit dependencies from go.mod 2024-11-04 16:36:40 -08:00
54782cc1f7 feeds: Update submodule commit 2024-11-04 15:47:19 -08:00
0a0f007a11 feeds: Update submodule commit 2024-11-04 08:45:11 -08:00
8010f10396 photos: Add North from the Fairmont Hotel post 2024-11-04 08:41:50 -08:00
126dc58e7c Add a 2024 section index to the photostream 2024-11-04 08:41:23 -08:00
0cef7a7903 Fix up the new-photo-post script
Make the script a little more resilient. Print out some EXIF data that the template
will use when generating the page.

Update the photostream submodule commit.

Remove the unused photo_exif_table.html partial.
2024-11-04 08:37:56 -08:00
602f5fa26c Update some content posts to work with the new shortcodes, etc 2024-11-01 21:42:36 -07:00
855c5b719e Create a deployall Makefile target
Move generating nethack data out of the deploy target so that deploy can just be
building what's there and pushing it.

Parameterize the destination build directory as BUILD_DIR. Default to the hugo
default, i.e. public.
2024-11-01 21:29:15 -07:00
aa14214f73 Update Nethack logfile for electra 2024-10-31 17:18:48 -07:00
d42176c918 Update tags and opening paragraph on the Jackson and Other Holes post 2024-10-31 16:29:19 -07:00
f15644810c Add a description to the Jackson and Other Holes post 2024-10-31 12:54:17 -07:00
d1c47448ab termlite: Update submodule commit 2024-10-31 10:55:12 -07:00
fd6fd1c3ca "Jackson and Other Holes"
Travel post about going to Jackson, WY, Yellowstone, and the Grand Tetons with the HS friends group.
2024-10-31 08:39:43 -07:00
cd789e9dfe Update Nethack logfile for electra 2024-10-31 08:11:53 -07:00
d1c2a3b4c8 Limit expanded year lists in the overall list template to 3 years for both blog and photostream 2024-10-31 08:07:05 -07:00
8bfa3fc8bf Add support for embedding videos in the figures/image shortcode 2024-10-31 08:06:05 -07:00
d679ae6c39 Quote the DEPLOY_LOCATION variable in the deploy Makefile target 2024-10-31 08:05:27 -07:00
9b682a5d96 Remove the .py extension from the new-photo-post script 2024-10-31 08:05:00 -07:00
3fba9450ee Update nethack logfile 2024-10-31 08:04:39 -07:00
0d4a5ea214 termlite: Update submodule commit 2024-10-31 08:03:51 -07:00
6343452a62 Exclude drafts from the latest widget 2024-10-27 10:05:35 -06:00
e72f8136ab Publish BSD Make post 2024-10-27 10:03:19 -06:00
d6e56e2ab7 Add a "production" argument to the dev_server script
When this argument is passed, set the environment to "production".
2024-10-27 09:58:42 -06:00
612a0425a2 termlite: Update submodule commit 2024-10-27 09:58:10 -06:00
5e58416bc6 Rewrite home page content
Add the latest widget that lays out two blog posts and four photos in a grid
2024-10-27 09:57:30 -06:00
d5296995de Get the nethack page looking good again
Update all the CSS classes and fix the layout so it looks good in the new theme.
Convert a bunch of CSS classes to BEM style.
2024-10-27 09:56:46 -06:00
2b613de769 termlite: Update submodule commit 2024-10-26 08:32:08 -06:00
b72441b9b1 Embed the image of a photo post link in a <figure> 2024-10-26 08:31:14 -06:00
e65a680b49 Get blog and photos posts recursively in the latest widget
Now that year sections are real sections, real pages (i.e. blog posts and photos)
need to be fetched recursively.
2024-10-26 08:30:44 -06:00
0e2c7c2dac termlite, photostream: Update submodule commits
Consolidate list templates
2024-10-24 10:08:53 -06:00
796371e10f termlite, photostream: Update submodule commits 2024-10-23 11:17:03 -07:00
b163b64e47 Add index pages to blog and photos subdirectories
These should be full Hugo sections so Hugo generates year section pages.
2024-10-23 10:28:54 -07:00
1d4969a06b Ignore /documentation/mirrors/ 2024-10-23 08:36:55 -07:00
300829b9eb Add short linkTitles to a bunch of photo posts 2024-10-23 08:34:55 -07:00
71cb4e9d2f Spell out the arguments to hugo in the Makefile for self-documentation 2024-10-20 09:19:56 -07:00
5c2942bc56 Add a home/latest widget
Add a shortcode and some styles for a two column, two row grid of latest posts.
2024-10-20 09:19:14 -07:00
f55b445c1f The abbr shortcode takes a single positional argument to use a the title attribute 2024-10-20 09:13:54 -07:00
7274f9ce74 Update feed publishing
Remove RSS. As Tess said, it's a pile of hacks and conflicting specs. Better to
use Atom. I was only ever linking to Atom feeds anyway.
2024-10-20 09:13:22 -07:00
f19de6f8fc Update Nethack logfile for electra 2024-10-19 08:30:56 -07:00
310d4177c1 Update build arguments for the development server 2024-10-17 11:37:11 -07:00
093571e1cd Add a link title to the Vibin' photostream post 2024-10-17 08:41:55 -07:00
9e3f7d1a69 Replace the JS railroad diagram with an SVG in the Audio Scope post 2024-10-17 08:41:04 -07:00
45449c3b20 Make the home page a single page 2024-10-17 08:40:32 -07:00
f5b2b1e67a termlite: Update submodule commit 2024-10-17 08:40:13 -07:00
750dd6179b photostream: Add go module, git submodule, and update commit 2024-10-17 08:39:25 -07:00
7b353e2fa8 Disable HTTP caching on the dev server 2024-10-13 23:15:02 -07:00
f95ac34c7c termlite: Update submodule commit 2024-10-13 23:14:45 -07:00
9f2eacfaeb Update the front matter for the cats page 2024-10-12 11:27:53 -07:00
4da0aeca1a Add .figure class to code and image figures 2024-10-12 11:27:38 -07:00
830f22d6ba termlite: Update submodule commit 2024-10-12 11:27:16 -07:00
3766168bea Remove assets/styles 2024-10-10 23:06:23 -07:00
187bc15a6f termlite: Update submodule commit 2024-10-10 23:04:53 -07:00
3bb8917116 termlite: Update submodule commit 2024-10-08 19:22:35 -07:00
3369b52735 Move the youtube shortcode to the termlite theme
Rename it figures/youtube → youtube and update the posts that use it.
2024-10-08 09:09:02 -07:00
d496238184 Update the site title and copyright 2024-10-08 09:06:08 -07:00
8e8881c52e image-utils: Update submodule commit 2024-10-08 08:46:38 -07:00
5510a738fa Remove the railroad shortcode
This partial moved to railroad-diagrams. Except it's pissing me off. 🙃
2024-10-08 08:46:28 -07:00
e0b2683ef9 Remove the images/orientation_angle partial
This partial moved to the image-utilities theme
2024-10-08 08:46:06 -07:00
3102dc1e56 Move a bunch of shortcodes and partials back from the platters theme 2024-10-08 08:45:44 -07:00
20d53e0df2 image-utils: Add image-utils submodule 2024-10-08 08:41:31 -07:00
0f200e3d09 Move circular_image back to the top level 2024-10-07 21:43:47 -07:00
47d1bf9ffe Move nobreak and tess shortcodes back to the top level layouts directory 2024-10-07 21:42:29 -07:00
66adceaf24 Move all layouts to platters theme 2024-10-07 21:39:17 -07:00
de8101efed Remove layouts from themes/platters 2024-10-07 21:38:50 -07:00
6398a4d0df Add an empty platters theme 2024-10-07 21:37:58 -07:00
ae9aa17e37 import map template 2024-10-07 21:36:03 -07:00
3e4e292a23 Update the content header partial 2024-10-07 21:35:48 -07:00
fa82e4f9a7 Make some tweaks to the layout stylesheet 2024-10-07 21:34:44 -07:00
f0d0d5a136 Add an error return from the figures/image shortcode if the images list contains a nil 2024-10-07 21:33:30 -07:00
8d7b2364db Remove the date from the about page 2024-10-07 21:32:31 -07:00
00d6181bd8 Make the whole site a module so it can accommodate the theme modules 2024-10-07 21:30:32 -07:00
bac1ff6ea9 resource-builders: Add submodule 2024-10-07 21:28:10 -07:00
fd75e27423 termlite: Add termlite submodule 2024-10-07 21:12:55 -07:00
afc5433304 Detect all .html files under layouts as HTML files 2024-10-05 18:57:11 -05:00
9628145f56 Remove quotes from B612 title field 2024-07-31 07:18:18 -07:00
c4f5170a09 Edits and updates to Weeknotes 2024w24 2024-06-20 17:21:48 -07:00
4c44baab1b Fix a type in Weeknotes 2024w23 2024-06-18 08:23:34 -07:00
2a780a08ae Weeknotes for 2240w24 2024-06-18 08:20:37 -07:00
bee8800070 Replace the next_sunday.py script with a more comprehensive weeknotes script 2024-06-10 13:18:21 -07:00
1c897e4518 Small edit to 2024w23 weeknotes 2024-06-09 23:18:56 -07:00
2f5b413d1e Enable emoji codes in Markdown like 🏳️‍🌈 2024-06-09 23:18:40 -07:00
b241986a5d Weeknotes for 2024w23 2024-06-09 23:16:19 -07:00
3174b44fbe Ignore .md-e files 2024-06-03 07:56:41 -07:00
7843ee9cdd Write a new script to calculate next Sunday's date 2024-06-03 07:55:36 -07:00
e2d64f82f8 Weeknotes 2024w22 2024-06-03 07:43:53 -07:00
4166a83fcb Remove broken Spanish language page 2024-05-26 09:33:31 -07:00
cfe80aaeef Remove the other archetype 2024-05-26 09:26:59 -07:00
851f676ca0 Weeknotes archetype and Makefile rule 2024-05-26 09:26:40 -07:00
7ff50445f5 Fix the header font size scale 2024-05-26 09:25:24 -07:00
452fec15ad Weeknotes, 2024W21 2024-05-26 09:25:10 -07:00
d7ec4ae8b6 Reindent root_css partial 2024-04-09 20:49:56 -05:00
84f8a6697f Update twitter shortcodes to take user and id argumentsg 2024-04-09 20:49:21 -05:00
6f42d2b7e8 Fix a photo embed in the Japan trip post 2024-03-28 16:49:50 -07:00
de3bf86764 Update Nethack logfile for electra 2024-03-27 07:59:00 -07:00
e18453dac0 Allow the caller of the figures/image shortcode to skip image processing via the shouldResize argument 2024-03-11 08:28:58 -07:00
85ed759a3a Add toki pona to the list of supported languages 2024-03-11 08:27:33 -07:00
dabda17c06 [post] I Use This 2024-03-09 09:35:29 -08:00
84382e4576 [post] B612 2024-03-09 09:08:16 -08:00
d1688c14b5 Style fixes for Definition Lists 2024-01-15 17:07:12 -08:00
5973cd882b [post] You Deserve A Tech Union [draft] 2024-01-15 17:06:29 -08:00
ac8f8781cf Uses page 2024-01-15 17:05:40 -08:00
2098413e87 [post] Thirty Six 2024-01-15 17:04:52 -08:00
ee9382b7a9 Clean up the terms template a bit 2024-01-08 13:16:53 -08:00
8b7e70dc81 Resume updates 2024-01-08 13:16:39 -08:00
48df8771ab [post] We Beat Tetris? 2024-01-08 13:16:19 -08:00
11bacea783 CSS and a shortcode for a 2-column grid within the content track 2024-01-08 08:32:13 -08:00
14f4246154 Fix the misasligned slogan in the site footer 2024-01-08 08:22:47 -08:00
7ebf3da3bd [post] Add a Chess Friend page 2023-12-31 12:17:44 -08:00
9584896363 Add a class argument to the figures/image shortcode 2023-12-31 12:17:27 -08:00
5f14f1cea2 [post] Add a description to "Less Instagram, More Blog" 2023-12-31 12:17:06 -08:00
34d4bee382 [post] Hello Chess Friend 2023-12-31 12:16:45 -08:00
74ed7ba8dc [post] Yerba Buena summary 2023-12-27 13:03:05 -07:00
ff72f94b8f Fix YouTube figures and add a .content-width CSS class 2023-12-27 12:51:07 -07:00
f7e35417a9 [post] Less Instagram More Blog 2023-12-27 12:50:31 -07:00
5444c10dba [photo] Cinnamon Buns 2023-12-26 21:55:49 -07:00
1660f63578 [photo] Tumbleweed Tree 2023-12-26 21:55:36 -07:00
087e3461d6 Apply js.Build to railroad_utils.js 2023-12-26 21:42:16 -07:00
778416a43a [post] What to Blog About 2023-12-23 09:33:43 -07:00
992e9119f3 Remove unneeded icon overrides in nethack.css 2023-12-18 11:22:30 -08:00
383234e983 Address all warnings during the Hugo build
- Add descriptions for pages that have too much content
- Add an image orientation override param so that I can specify orientation when it's missing from EXIF
- Move the author.name and author.email configurations to params; delete author.yaml
2023-12-18 11:22:14 -08:00
e4c62f02d3 Add a description to my "Once Upon A Time I Lived on Mars" book report 2023-12-16 09:26:02 -08:00
b876f5a0cd Move li_grid_with_date template to _default so terms and blog can use it 2023-12-16 09:25:35 -08:00
b9265b5793 Add a tsconfig based on @tsconfig/recommended 2023-12-16 09:25:00 -08:00
d540126bfa Merge branch 'posts/2023/chess' 2023-11-23 09:34:34 -07:00
63ddb21964 Final Chess post 2023-11-23 09:34:16 -07:00
a353c4a549 {{< img >}} shortcode 2023-11-20 11:55:58 -08:00
ee98566283 In the page_css partial, check array length and presence of $.File before concatenating stylesheets 2023-11-20 11:55:40 -08:00
a4a0561bc8 In new-photo-post.py, continue instead of pass when opening an image fails 2023-11-20 11:54:41 -08:00
bcae9f135c Tag a commit after deploying 2023-11-20 11:54:11 -08:00
ca8cbf8f78 Update Nethack logfile for electra 2023-11-20 10:33:57 -08:00
4a4a941e5d Merge branch 'massive-relayout' 2023-11-20 10:33:39 -08:00
5cccfb9887 Give code block line numbers a less prominent color 2023-11-19 07:28:23 -08:00
3783801365 Turn off code block line numbers by default 2023-11-19 07:27:46 -08:00
b3a38f4c7d Define start and end line names for each content column 2023-11-19 07:27:31 -08:00
14cf9750d4 Remove an unused layout CSS rule 2023-11-18 18:30:43 -08:00
cb3d538a54 Table of contents styling and spacing 2023-11-18 11:16:11 -08:00
73320e6fb3 Fix <code> block and inline styles 2023-11-18 11:15:42 -08:00
703d6933f3 Use {% %} instead of {< >} for headings with ruby to make it work correctly in the table of contents 2023-11-18 11:13:47 -08:00
f905b16940 Add a render template for headings
Create heading anchors and style them with colors and stuff
2023-11-18 11:13:16 -08:00
bfee27e7c5 Fix "me" image on the about page
Add a section shortcode to enable wrapping a chunk of a post in a <section>
Add a section.flow class that removes grid from the section
Fix up the about styles so that the paragraph that Hugo wraps the <img> in behaves sensibly when floated
Fix the alt text in the circular_image shortcode
2023-11-18 11:11:34 -08:00
2a83017324 Remove table of contents stylesheet 2023-11-16 13:21:44 -08:00
3d25927c65 Clean up monokai and nethack stylesheets a tiny bit
Remove some unused and redundant stuff
2023-10-14 15:06:16 -07:00
03fee87f16 Rename some root styles 2023-10-14 15:05:58 -07:00
d45ad449a5 Merge branch 'main' into massive-relayout
# Conflicts:
#	assets/styles/root/050_ruby_controls.css
#	layouts/partials/ruby_controls.html
2023-10-14 15:00:00 -07:00
bf37618430 Merge branch 'ruby-switch' 2023-10-14 14:56:57 -07:00
59f5b195a5 The nethack importer updated Electra's hostname 2023-10-14 14:56:38 -07:00
8022a8f84a Integrate <ruby-switch> into the templates 2023-10-14 14:55:54 -07:00
abb85f701d Ruby Switch script v1 2023-10-12 11:05:02 -07:00
c56f91da2c Write a warning if an image doesn't have an orientation
Default to 0º orientation.
2023-10-12 11:04:19 -07:00
ff2dbdb1fd [post] San Diego Zoo Safari Park photos
- Vibin'
- Lotus
2023-10-12 11:03:58 -07:00
a4648e7a39 Add alt text to the doormat test image in test/ 2023-10-12 10:13:52 -07:00
2bd5fd03bb Add .column5 utility class 2023-10-12 10:13:33 -07:00
48a28a7f7a Remove dead 050_ruby.css file 2023-10-12 10:12:28 -07:00
8cc207b84c Parameterize the photo grid 2023-10-03 08:55:13 -07:00
864c1b673a Fix the home layout 2023-09-30 13:03:10 -07:00
20e76897ff Move site header layout styles to columns; fix nav spacing
Do a bit of testing on Chrome too.
2023-09-30 11:56:45 -07:00
17f576406f Move all the figure styles to columns and typography 2023-09-30 11:22:08 -07:00
090eef5bee Fix the alignment of the post title <h1> 2023-09-30 11:06:30 -07:00
fe176e4dfd Two Space Indents in CSS 2023-09-30 11:05:57 -07:00
3a1597acec Move all the syntax highlighting styles to functional stylesheets 2023-09-28 18:16:38 -07:00
fb7fd04fe9 Fix the lists! 2023-09-28 16:29:02 -07:00
c642a23ec3 Move a bunch of color stuff from typography to colors 2023-09-28 14:41:32 -07:00
cf0fd27172 Partially reorganize styles into functional chunks, rather than by component
Move link, generic page layout, post list, and a bunch of leftover stuff in root.css to functional stylesheets in styles/root/.
2023-09-28 14:12:55 -07:00
a9cfddec80 Fix styling of blog, photos, term, ruby
So many fixes!
2023-09-26 09:37:04 -07:00
b7070ccfd5 Remove the <ul> and <li> from the blog list 2023-09-26 08:35:21 -07:00
6f132cc04e Development styles so far 2023-09-24 09:22:00 -07:00
1fac613c37 All the root styles so far 2023-09-24 09:21:49 -07:00
d18edef261 Add section.atom templates to blog and photos that are identical to the home feed 2023-09-24 08:59:40 -07:00
1ce9e2b417 Add empty section.html templates to nethack and nihongo 2023-09-24 08:59:19 -07:00
0262f79509 Add empty section.atom templates to about/ nethack/ and nihongo/ 2023-09-24 08:58:51 -07:00
42dc062147 Updates to the blog list so far (I've lost track) 2023-09-24 08:46:30 -07:00
d6e5c2a978 Only add a figcaption to the figures/image shortcode if the Title is non-empty 2023-09-24 08:45:47 -07:00
162e17339c Move photos styles to styles/photos/ files 2023-09-24 08:43:29 -07:00
2331e37e62 Move blog.css styles to styles/blog/ files 2023-09-24 08:43:10 -07:00
dbb202d7f9 Merge branch 'main' into massive-relayout 2023-09-23 13:34:09 -07:00
b95120c602 Post: Guide to Computing 2023-09-23 13:29:55 -07:00
16f96558cc Reset the line height to 1.5; 2 was silly 2023-09-22 07:56:50 -07:00
4ea71e2219 Ignore node_modules/ 2023-09-19 16:08:27 -07:00
4723da8289 [photo] Mug o' Broth 2023-09-19 16:08:06 -07:00
77f6e16d9a Fix the IsSet warning when building the site 2023-09-19 16:05:17 -07:00
755de7d938 [post] Mastodon Icon, remove draft 2023-09-15 08:00:21 -07:00
931afe5b68 [post] Mastodon Icon 2023-09-15 08:00:21 -07:00
59da399fac Fix all the dark icons 2023-09-15 08:00:21 -07:00
345d5175c9 Copy over the viewBox, width, and height attributes of the light social icons to dark icons 2023-09-15 08:00:21 -07:00
30ec64dd66 Adjust Mastodon icon down 1 px 2023-09-15 08:00:21 -07:00
01d27411d7 Establish a grid system
There are 5 content columns, two gutter tracks, two wide content columns, and two margin columns
2023-08-20 12:23:08 -07:00
f4ed16c706 Clean up content_header 2023-08-20 12:15:37 -07:00
4576de0c8d Wrap about's style in @layer page { } 2023-08-20 12:14:43 -07:00
c94c4a6c95 Teach resources/page_css how to load CSS stylesheets with .Kind 2023-08-20 12:14:08 -07:00
851c74b2c9 Define variables for <h*> sizes 2023-08-20 10:07:26 -07:00
f950cdbbd9 Remove border-radius from figures 2023-08-20 10:06:58 -07:00
1dc243c95f Remove leading empty space from <figcaption> if it's empty 2023-08-20 10:05:37 -07:00
8aed72a94d Wrap tags list in a .taxonomies <div>
Put two <ul.tags> elements inside so there's not an <li> with a triangle in it.
2023-08-20 09:59:16 -07:00
ea9fb02aaa Move home styles to home.css 2023-08-20 09:59:16 -07:00
3bcdd7edb7 Add .page or .list to <main> depending on the length of .Pages 2023-08-20 09:59:02 -07:00
013d707f50 Do the header gradient one letter at a time for browsers that don't support background-clip: text 2023-08-20 09:58:26 -07:00
61047d1c26 [post] Mastodon Icon, remove draft 2023-08-11 08:28:19 -07:00
43e3cc33b3 [post] Mastodon Icon 2023-08-11 08:23:43 -07:00
ead226cccc Fix all the dark icons 2023-08-11 08:21:50 -07:00
629bbe0c5c Copy over the viewBox, width, and height attributes of the light social icons to dark icons 2023-08-11 08:11:08 -07:00
041000ce37 Adjust Mastodon icon down 1 px 2023-08-11 08:07:02 -07:00
9372bf3093 Merge branch 'mastodon-icon' 2023-08-11 08:05:35 -07:00
751f1c7d81 Tweak all the icons
Make them a little bigger. Clean up the view boxes.
Use <img> instead of backgrounds of <a> tags so the Mastodon logo does not get clipped.
2023-08-11 08:05:04 -07:00
d407d9d15a Replace Twitter icon with Mastodon 2023-08-10 07:32:57 -07:00
30b18bd969 [post] Atom Feed Bug Fixes 2023-08-09 08:51:01 -07:00
d685f2e647 Fix the RSS and Atom feeds 2023-08-09 08:21:54 -07:00
a4f54d34f6 Update Nethack logfile for electra 2023-08-08 07:30:00 -07:00
c33d82c0b7 [Post] Netscape Meteors: Retrospective 2023-08-06 14:29:55 -07:00
2fec92c904 Netscape Meteors post 2023-08-02 17:31:48 -07:00
57ce171455 Remove two-column from a couple book posts 2023-08-02 17:30:28 -07:00
afc6e81b70 Redo the figure shortcode to take multiple images
Put all images in a flexbox container
2023-08-02 17:16:30 -07:00
cce2a1670e Add an nvim abbreviation for &times; 2023-08-02 17:15:43 -07:00
64f6161d72 Remove draft tag from Steve Jobs Theater photo post 2023-08-01 18:20:28 -07:00
4604717794 Steve Jobs Theater photo post 2023-07-14 08:44:36 -07:00
f93752e805 Remove draft status from Pajaro Dunes photos 2023-07-14 08:38:26 -07:00
c21398f449 Pajaro Dunes post 2023-07-14 08:37:22 -07:00
bf23ba41a9 Fix a typo in root_css.html 2023-07-14 08:30:16 -07:00
4d14ea9ab2 Process CSS resources as lists (call {{ range }} on them)
All the CSS resource partials return lists now.
2023-07-14 08:26:42 -07:00
6740e7b61d Fix all the CSS resources templates 2023-07-14 08:26:42 -07:00
da64dd30d5 Simplify the draft tag partial
I do not publish drafts to production, so we do not need to check if
the page is being served from localhost in the template.
2023-07-14 08:08:53 -07:00
68618884e8 Add a few more test elements to the test page 2023-07-14 08:07:17 -07:00
f70768ecbf Remove draft status from about page 2023-07-14 08:06:55 -07:00
6a0193c002 Add photos from the Pajaro Dunes trip 2023-07-13 08:06:43 -07:00
1e851f7061 Fix two issues in new-photo-post.py
- Strip typographic quotes from input to slugify()
- Fall back on a floating timestamp if no timezone is given
2023-07-13 07:48:46 -07:00
039efa3c23 Remove flags part of page info debug thingie 2023-05-20 09:44:40 -07:00
5fe0139b93 Fix a stray --body-line-height 2023-05-20 08:32:49 -07:00
ff615a757c Move shortTitle site param to config/_default/params.yaml 2023-05-20 08:31:15 -07:00
4f63fab916 Move all the home styles to inline CSS 2023-05-20 08:28:38 -07:00
1713d5f849 Move site navigation to a partial
It can now be shared between the index and site header templates.
2023-05-20 08:27:55 -07:00
52a79500c0 Tweak the layout of the debug page info thingie 2023-05-20 07:53:26 -07:00
82db8ebfd1 Some test page additions 2023-05-20 07:53:26 -07:00
8029f97f9c Move all the root styles to fragment files
Create assets/styles/root to hold all the fragments of the root
stylesheet. This should make it easier to find and hack on style. Yay!
2023-05-20 07:53:22 -07:00
273c380fe6 Apply tags styles to any ul.tags, not just in the footer 2023-05-17 08:36:57 -07:00
f2800b0619 Use a "major third" type scale from https://typescale.com for the heading font sizes 2023-05-17 08:32:47 -07:00
fc35499d6c Simulate background-clip: text for browsers that don't support it
Move the heading generating to a partial that iteratively wraps each character
of the heading in a <span>. The CSS for the site heading uses :nth-child to
color each span a different color.
2023-05-17 08:28:22 -07:00
0e81f019a7 Fix ruby controls 2023-05-08 20:52:49 -07:00
862b4ce77e Remove draft status! 2023-05-08 20:50:01 -07:00
ba2f868e06 Merge branch 'main' into japan 2023-05-08 20:35:36 -07:00
b3a353c2a8 Fix the page CSS partial so that it generates a new stylesheet for each page 2023-05-08 20:35:12 -07:00
6a6c638b76 Fiddling with the formatting of baseof.html 2023-05-08 20:35:11 -07:00
ca1bb982ca Allow unsafe markup in the Markdown renderer 2023-05-08 20:35:11 -07:00
d6e44d66ef Heian-Jingu photo post 2023-05-08 20:34:47 -07:00
ecd6fbb155 Zen Garden at Hase-dera photo post 2023-05-08 20:34:38 -07:00
fc195c6008 Happy Monks photo post 2023-05-08 20:34:38 -07:00
e346a905fa Add details styling for the TableOfContents 2023-05-08 20:12:55 -07:00
37fecd7dfb Tweak the formatting of table of contents 2023-05-08 20:12:33 -07:00
174e5bc784 Implement ruby controls! 2023-05-08 20:12:11 -07:00
a5f5909bef Limit the ruby/rt transitions to color only 2023-05-08 20:10:22 -07:00
a990aa335a Fix ruby styling 2023-05-08 20:09:17 -07:00
0b754a7d27 Heian-Jingu photo post 2023-05-08 20:08:07 -07:00
727a6ffd59 Fix the page CSS partial so that it generates a new stylesheet for each page 2023-05-08 20:07:26 -07:00
8296cc6e43 Fiddling with the formatting of baseof.html 2023-05-08 20:06:42 -07:00
cec1576d75 Allow unsafe markup in the Markdown renderer 2023-05-08 20:02:56 -07:00
ac6b5125eb Final final? 2023-05-08 20:01:58 -07:00
40274f037d Move souflee pancakes to be a resource of the series page 2023-04-29 20:40:01 -07:00
347c00a054 Zen Garden at Hase-dera photo post 2023-04-29 12:15:48 -07:00
af76a72b57 Happy Monks photo post 2023-04-29 12:15:34 -07:00
fb71dde50b Merge branch 'main' into japan 2023-04-23 22:45:51 +09:00
89323983cc Souflee Pancakes photo post 2023-04-23 22:39:51 +09:00
6a1acdf9bc Hachiko photo post 2023-04-23 22:37:33 +09:00
cb81836279 Kiyomizu-dera photo post 2023-04-23 22:35:29 +09:00
70cce64fc2 Kinkaku-ji photo post 2023-04-23 22:32:09 +09:00
9c02e5fa12 Eaves of the Imperial Palace in Kyoto photo post 2023-04-23 22:27:02 +09:00
f640f8cd28 Fushimi Inari Torii photo post 2023-04-23 22:26:42 +09:00
53be965773 Fuji-san from the Plane photo post 2023-04-23 22:18:50 +09:00
143c148f7a Basic Japan trip series page 2023-04-23 22:15:29 +09:00
66d50f773b Some layout tweaks for the term template
Allow removing the pages list if the "pages" page variable is set false.
2023-04-23 22:11:48 +09:00
f21ac49b08 Add a table of contents
Create a new table_of_contents partial that includes an auto-generated table of contents if the word
count is over 400 and the "toc" page variable has been set true.
2023-04-23 22:11:47 +09:00
6eeeb11ab4 More Japan writing 2023-04-23 22:11:47 +09:00
3b3e38928b Intro blog post 2023-04-23 22:11:47 +09:00
b8434f4b2a Lots of WIP posts 2023-04-23 22:11:47 +09:00
8ce8089474 Shinjuku at Night photo post 2023-04-23 22:10:24 +09:00
29c402c3ec Add a slug argument to the new-photo-post script 2023-04-23 22:10:04 +09:00
2501cac13a Add some UltiSnips snippets to help with Markdown posts and some macron abbreviations for Tokyo and Kyoto 2023-04-23 22:10:04 +09:00
01ca8d8cfb Add "Hiragino Mincho" to the heading font family list 2023-04-23 22:10:04 +09:00
1b02d081e3 Set the line height of all body text to 1.85 2023-04-23 22:10:04 +09:00
ec96e17acd Ruby shortcode and some new ruby CSS styles 2023-04-23 22:10:04 +09:00
51d9a5b61f WIP photo of the Ionic Column at Delphi 2023-04-08 19:44:38 -07:00
15e0caa603 WIP photo of the Temple of Apollo at Delphi 2023-04-08 19:44:25 -07:00
b9869c11f0 Update the EXIF table so that it properly formats data from my Canon camera 2023-04-08 19:43:01 -07:00
3eb3217092 Publish the Frog Pond photo 2023-04-08 19:34:41 -07:00
b1103ab027 Add some nvim configuration for CSS, HTML, and JS files 2023-04-08 17:56:56 -07:00
50c181f2fd Add some nobreak spans around data in the photos EXIF table 2023-04-08 15:17:44 -07:00
7f48047610 Fix the Nethack page at small screen sizes 2023-04-08 15:12:43 -07:00
59bb6d28d0 Move the debug photo-params table styles to development.css
Fix formatting of the development stylesheet
2023-04-08 15:06:39 -07:00
5f6ae6c603 WIP carousel post for the Temple of Hephaestus 2023-04-08 15:05:04 -07:00
d0757067ed Fix the layout of the photo params table at smaller viewport sizes 2023-04-08 15:04:42 -07:00
cb025398b3 Fix the extra 2px space at the bottom of <figure> elements
It was because they were display: inline-block
2023-04-08 15:04:25 -07:00
5fd6f473dd Add a Spanish index for the photos list 2023-04-06 08:48:30 -07:00
17ec17b1e7 WIP of the Long Way to a Small Angry Planet book post 2023-04-06 08:46:28 -07:00
c256179803 Expand the width and heigh argument checks
They are more readable when they are not squashed on one line.
2023-04-06 08:45:15 -07:00
84bf9b3a32 Add a .nvim runtime directory and add a template filetype detection autocmd 2023-04-06 08:45:15 -07:00
3014a7c694 Add a lang shortcode that wraps text in a <span lang="x"> tag 2023-04-06 08:45:15 -07:00
dabe54e581 Another Gratuitous Hanami Photo post 2023-04-02 19:51:18 -07:00
0010e65428 Make sure getting the nethack score path always uses the nethack binary (not my shell function) 2023-04-02 09:29:49 -07:00
9f7f0f84c3 [photo] Bletchley Park selfie 2023-03-28 17:49:59 -07:00
3920d8a415 Hanami photo post 2023-03-28 08:36:22 -07:00
78bd1e4a4e Japanese flashcards! 2023-03-13 21:06:45 -07:00
533bc1138c Update the date of the Once Upon a Time post 2023-03-04 10:48:55 -08:00
15165db3c6 Finish Once Upon a Time I Lived on Mars post 2023-03-04 10:47:13 -08:00
a2653e185c For new photo posts use YYYY/name if possible, and fall back on YYYY/MM/name if not 2023-03-04 10:25:04 -08:00
74ae4174e0 Add Frog Pond photo post 2023-03-04 10:24:35 -08:00
d2709de6d7 Add Showshoeing in Tahoe photo post 2023-03-04 10:24:22 -08:00
f9749738f3 Update Nethack logfile for electra 2023-03-01 07:20:16 -08:00
01fb022322 Old Friends, New Mountain photo post 2023-03-01 07:17:16 -08:00
02b0224247 Render "term" content if it exists; add a Posts header between the content and post list 2023-02-12 10:33:25 -08:00
4254726189 Merge branch 'nethack-background' 2023-02-04 19:22:45 -08:00
61be4cad61 Clean up the find to and from point method in the Tunnel generator 2023-02-04 19:20:52 -08:00
9f1c6e1345 Make site a phony target 2023-02-04 18:26:41 -08:00
4f4312b944 Don't secure assets on localhost; it just messes with the JS debugger 2023-02-04 18:26:32 -08:00
94a09d0c81 Update Nethack logfile for electra 2023-02-04 18:23:39 -08:00
3c25f2041a Revert "Logging for the tunnel digger"
This reverts commit 6f0f1fd337.
2023-02-04 18:18:52 -08:00
6f0f1fd337 Logging for the tunnel digger 2023-02-04 18:18:49 -08:00
c384c07051 Nethack map generator! 2023-02-04 18:18:09 -08:00
78caa686c2 Remove BSPNode 2023-02-03 18:12:25 -08:00
aa50054108 Convert setting cell in room generation method into cell transform 2023-02-03 18:12:07 -08:00
89902ccc03 Tweak the width/height proportion of cells 2023-02-03 18:03:13 -08:00
e4a7550abc Add NRandomRoomsGenerator 2023-02-03 18:03:00 -08:00
5517fd0110 Clean up grid generation in setUp() 2023-02-03 18:02:44 -08:00
a283cae416 Add randomInt() 2023-02-03 18:02:10 -08:00
b8ac3126da Redo Room in terms of Rect 2023-02-03 18:01:53 -08:00
8a5fc9c820 Add some methods to Cell to turn the Cell into a real Cell 2023-02-03 18:01:34 -08:00
2033e0c3a1 Add some basic geometry types: Point, Size, Rect 2023-02-03 18:01:11 -08:00
186929921b Work in progress nethack dungeon generator background for the nethack page 2023-02-03 16:07:04 -08:00
d524a7dd9e Collapse nested if in draft tag into a single if 2023-02-03 16:06:22 -08:00
b20da51037 Make the 2023-books post a non-draft 2023-02-03 08:19:51 -08:00
7f61437f92 Style <main> with box-sizing: border-box and compute the max-width 2023-02-03 08:19:29 -08:00
16cf918e8e Add draft posts for Long Way to a Small Angry Planet and Once Upon a Time I Lived on Mars 2023-02-01 09:22:14 -08:00
18b7ad38b5 Add a category to the Nethack Illustrated Guide post 2023-02-01 09:15:46 -08:00
6affc7b454 Add alt text support to figures/image shortcode 2023-02-01 09:10:35 -08:00
5deda1c5ee Allow pages to specify a two-column layout 2023-02-01 09:10:21 -08:00
12a3fc6e59 Wrap up The Storyteller post 2023-02-01 09:09:54 -08:00
4eb5119b46 Add 2023-books series 2023-02-01 08:21:00 -08:00
eebfdab03f First draft: Tahoe Ski Trip 2023-01-31 09:30:07 -08:00
5bf157ca41 The Storyteller post 2023-01-31 09:29:51 -08:00
e18e207530 Add a post's category to the right of the list item 2023-01-30 12:38:25 -08:00
61b6f361d2 Move Nethack Illustrated Guide post to 2023/ (unnest it from the 01 directory) 2023-01-30 12:37:54 -08:00
547e196616 Conditionally include photo EXIF info so the table looks all right even with missing info 2023-01-30 12:26:06 -08:00
c6531e618d Format month photo path component with a leading 0 2023-01-29 16:28:35 -08:00
8aaeef4d45 Tahoe photo 2023-01-29 16:28:06 -08:00
42a71c1ac3 Update Nethack partials, shortcodes, and page to properly handle ascensions 😁 2023-01-24 08:53:58 -08:00
d1df92aa03 Update Nethack logfile for electra 2023-01-22 14:30:06 -05:00
e8e0a35064 Add a Makefile target that commits an updated Nethack logfile 2023-01-10 16:16:53 -08:00
97c92d209d Revert "Add the ability for post headers to be links when you add a link parameter to the page front matter"
This reverts commit d68e76478d.
2023-01-10 16:16:12 -08:00
4d4ba7bfa8 Update Nethack log file 2023-01-07 09:44:05 -08:00
cbc1cd16f0 Link post to the Nethack: An Illustrated Guide post someone shared on Reddit 2023-01-07 09:43:37 -08:00
d68e76478d Add the ability for post headers to be links when you add a link parameter to the page front matter 2023-01-07 09:43:15 -08:00
4ca71181c7 Add the {{r}} shortcode that renders a subreddit as a subtle (color only on hover) link, in monospace with no background 2023-01-07 09:42:56 -08:00
87e60d53f6 Update the Nethack log file 2022-12-23 08:19:15 -08:00
c13e5a62c3 Laguna Beach photo #1 2022-12-23 08:17:10 -08:00
39467b7a43 Add Mastodon link to <head> 2022-12-19 22:57:53 -08:00
aaa690b777 Add best Nethack game ever! 2022-12-19 22:57:40 -08:00
d67ec5f99b Import new Electra Nethack logfile 2022-12-05 08:15:06 -08:00
2a4838e8a3 Max level in the Nethack logfile is actually the max dungeon level, not the max character level 2022-12-05 08:14:39 -08:00
d88d34a00a Add shortcut icon link to Atom feed 2022-11-29 12:48:52 -08:00
3fe3599bc8 Add some metadata to the November 2022 photos 2022-11-29 09:09:23 -08:00
e263b3cb41 Include all photos as links in the RSS and Atom feeds, instead of just the thumbnail
- Move photo_thumbnail.html to photos/thumbnail.html
- Add a photos/list.html partial that returns a list of photos for the current
  page
- Use the template above everywhere we need a list of photos for the page
2022-11-29 09:06:18 -08:00
ab172e1e9e Add Shadow Kitty! post 2022-11-28 17:29:13 -08:00
b7221075a3 Add a photo_details param that turns off the details table when set to false 2022-11-28 17:29:00 -08:00
fe8e12a2ba Find an image named "thumbnail" if none is given as a param 2022-11-28 17:28:43 -08:00
4231c6c5d8 Add virtualenv requirements.txt 2022-11-28 16:56:19 -08:00
b423f89809 Move new photo script to ./scripts/new-photo-post.py 2022-11-28 16:56:05 -08:00
0ca9cf45c9 Import recent Nethack games; add Dwarf to the import script 2022-11-28 16:48:58 -08:00
4f865015e1 Add a Nethack game 2022-11-25 22:28:51 -05:00
f3ce03ea8d Make sure photo grid cells fill the cell 2022-11-25 22:23:57 -05:00
75a2e3a8bf Set margin-block-end on all children of <main> instead of setting it on every item individually 2022-11-24 12:15:53 -05:00
aa8c85c902 New post: My Best Nethack Game (So Far) 2022-11-24 12:15:15 -05:00
f0931bd9d1 Update favicons and touch icons 2022-11-24 08:29:59 -05:00
88476a707e Add a tbody for list page data to the development page info table 2022-11-24 08:26:50 -05:00
f1b60f443c Fix size of development disclosure instead of growing with the font size of the document 2022-11-24 08:26:28 -05:00
d174ae952d Add my best ever Nethack game :3 2022-11-24 08:26:04 -05:00
2011ccdd78 Add Male entry to GENDERS in nethack import script 2022-11-24 08:25:30 -05:00
828bcb0f94 Oops, recursive definition of DEPLOY_LOCATION in the Makefile 2022-11-20 22:45:50 -08:00
5606feeca1 Re-do a bunch of the styles for the Nethack page 2022-11-20 12:24:14 -08:00
9e11021ae3 Update import nethack logfile script
- Add a few roles to the ROLES mapping
- Check if the logfile changed before writing it (avoid updating the timestamp
  if no changes were made)
2022-11-20 10:01:07 -08:00
d2ab14f649 Parameterize the Makefile; add automatic importing of Nethack logfiles 2022-11-20 10:00:20 -08:00
566c915f43 Add Nethack logfile for Electra 2022-11-20 09:21:07 -08:00
cb8742042f Add Tech category to Where Am I post 2022-11-20 09:15:58 -08:00
7c3a65542a Fix lists (again) 2022-11-20 09:15:46 -08:00
ff65c704bd Add tags to the Where Am I post 2022-11-20 08:09:08 -08:00
0d8f36817f End-align the dates in the blog post list 2022-11-20 08:08:53 -08:00
3a55fbe945 Fix the width of <main> 2022-11-20 07:58:21 -08:00
2ca095e617 Add Where Am I post 2022-11-20 07:58:09 -08:00
df62cc0374 Editorial tweaks of the Nethack blog post, plus add a "Games" category 2022-11-20 07:44:03 -08:00
0be0081319 Fix the footer spacing (feels like the millionth time I've done this??) 2022-11-20 07:43:20 -08:00
f74f0c5e9d Clean up the layout of the Spanish home page 2022-11-19 13:42:20 -08:00
f6000d0197 Fix up the spacing of bulleted and social navs 2022-11-19 13:41:57 -08:00
e83eb2a3e5 Justify items in vertical homepage layout 2022-11-19 13:41:04 -08:00
766557433b Finish Week of Soup post 2022-11-18 21:17:18 -08:00
93a92fad86 Fix lists 2022-11-18 21:17:01 -08:00
188c5fb876 Remove unused $pages variable from photos list template 2022-11-18 08:35:31 -08:00
2c23862cc6 Link to Where to Find Me from the Spanish Sobre page; add a Spanish Donde Encontrarme 2022-11-18 08:31:40 -08:00
1d825755ff Add a nowrap shortcode 2022-11-18 08:30:45 -08:00
7bbd9a3adf Add a sketch archetype with a bunch of boilerplate for p5 sketches 2022-11-18 08:30:32 -08:00
cc4b1df2bf Improve the home page slightly 2022-11-18 08:28:58 -08:00
2c1f64cbca Set the <html lang> attribute correctly 2022-11-18 07:13:18 -08:00
19f153e706 Remove the animated, sticky header 2022-11-18 07:12:57 -08:00
6b800dcbf6 Add single and section pages to the about layouts section 2022-11-15 22:12:54 -08:00
04c4c31f96 Link to the Where Am I page from the about page. 2022-11-15 22:12:38 -08:00
2c5cec4f87 Remove the date from the about section only 2022-11-15 22:12:23 -08:00
8fadc54a43 Move site header and footer to the base template, and override the body block in index 2022-11-15 22:12:09 -08:00
19d8209cb2 Add Where Am I page to about section 2022-11-15 17:24:55 -08:00
4da32bb6d0 Make about a section 2022-11-15 17:24:54 -08:00
567363336d Add Week of Soup draft post 2022-11-15 17:24:54 -08:00
c52ac00231 Add alt text to the Harpswell Sunset post 2022-11-15 17:24:54 -08:00
41f506bb1e Remove margin from the slogans in the footer 2022-11-15 17:24:54 -08:00
c0a2dd9f28 Add alt text to the image in the photo/single template 2022-11-15 17:24:54 -08:00
19145efa33 Add an about menu 2022-11-15 17:24:54 -08:00
03899a54dc Add a copyright to the config 2022-11-15 17:24:54 -08:00
f078614848 Remove the simple layout; and remove the resume single template 2022-11-15 17:24:54 -08:00
5dbec4ec08 Fix the photo-params table: remove the erroneous padding at the bottom 2022-11-15 17:24:54 -08:00
e0b7aae3db Fix Spanish localization of the home page and footer slogans and copyright 2022-11-15 17:24:54 -08:00
da88d389e9 Split building and deployment into separate make targets 2022-11-15 17:24:54 -08:00
6842511b10 Remove the SRI stuff; use md5 instead of sha512 for fingerprinting since it is shorter 2022-11-15 17:24:54 -08:00
fb1b4ccab3 Remove animation log from site.js 2022-11-15 17:24:54 -08:00
bdf5065f17 Add Music Night post 2022-11-12 11:08:38 -08:00
9601e1e283 Implement fingerprinting site and page resources
This will keep browsers from caching files that have changed. I've also added
SRI information to the <script> and <link> elements for browsers to verify
resources.

Squashed commit of the following:

commit f3fcb16388
Author: Eryn Wells <eryn@erynwells.me>
Date:   Tue Nov 8 17:47:42 2022 -0800

    Remove static/styles/root.css

commit 53a30624a0
Author: Eryn Wells <eryn@erynwells.me>
Date:   Tue Nov 8 17:47:26 2022 -0800

    Add back the basic table styles that got ditched when root.css was moved to assets/styles

commit 294fa8343b
Author: Eryn Wells <eryn@erynwells.me>
Date:   Tue Nov 8 17:45:38 2022 -0800

    Get all the fingerprinting done!

    - Add partials in the resources folder for each of the major resources of my site
    - Consolidate .css and .js files via resources.Concat where possible

commit d0b223fa33
Author: Eryn Wells <eryn@erynwells.me>
Date:   Mon Nov 7 08:36:39 2022 -0800

    All the template updates for fingerprinting

commit 1751abadac
Author: Eryn Wells <eryn@erynwells.me>
Date:   Mon Nov 7 08:36:27 2022 -0800

    Add secure_asset.html template

commit 94ea8068c9
Author: Eryn Wells <eryn@erynwells.me>
Date:   Mon Nov 7 08:35:48 2022 -0800

    Move a bunch of scripts and CSS to assets so they can be processed with Hugo Pipes

    Use Pipes to fingerprint and add SLI information to <script> and <link> tags.
2022-11-08 17:50:11 -08:00
f8174ab27c Add Atom output to sections 2022-11-08 08:54:52 -08:00
963444b6b6 Lunar Eclipse -> !draft 2022-11-07 08:59:43 -08:00
02dabcd008 Basic table styles 2022-11-07 08:59:10 -08:00
1a10555640 Lunar Eclipse post 2022-11-07 08:59:04 -08:00
ad646c89c0 Hugo's Dictionary API post
Squashed commit of the following:

commit b507cf8be2ca46ce4b88e3292ef173a0b5e3606f
Author: Eryn Wells <eryn@erynwells.me>
Date:   Sun Nov 6 00:23:05 2022 -0700

    Wrap up this blog post

commit 6ed0c777e7c33b0819f7d7a896fce60f75a13fe3
Author: Eryn Wells <eryn@erynwells.me>
Date:   Sat Oct 15 10:20:03 2022 -0700

    WIP Hugo Dictionary API post
2022-11-06 00:24:29 -07:00
81c04c7b5e Add a blank rss_item.rss template as a catch-all for pages that should not be in the feed 2022-11-05 23:59:13 -07:00
877dcedbcd Put - around $scheme declaration in atom_entry_metadata 2022-11-05 23:58:50 -07:00
d3df159add Do not escape .Content in the RSS feed templates 2022-11-05 23:58:28 -07:00
e15c8488a5 Move index templates up to layouts/ 2022-11-05 23:57:52 -07:00
2f3d133dda Break up the RSS template into item templates, like I did for atom 2022-11-05 13:21:09 -07:00
b2d24aad54 Rename the atom_entry templates with .atom suffix 2022-11-05 13:20:26 -07:00
24122c7427 OOPS! Add back <a> tags to the site menu 2022-11-04 08:07:13 -07:00
2cff513898 Remove the back button from photo posts 2022-11-04 08:05:13 -07:00
ce5f0ea678 Clean up the site header template a little bit 2022-11-04 08:05:07 -07:00
543112fc51 Convert the social menu to a config driven version 2022-11-04 08:01:24 -07:00
7dcfc12ec7 Generate a feed.atom too 2022-11-04 08:01:07 -07:00
c4db9126b5 Always include <content> in photos atom entry 2022-11-03 17:10:48 -07:00
9051fce9aa Add alt text to the Harpswell post 2022-11-03 17:04:33 -07:00
92854f7a0a Add an inline <img> in the photo Atom entry 2022-11-03 17:04:18 -07:00
1e6711b8f3 Use the photo_thumbnail partial in the li_thumbnail_in_grid template 2022-11-03 17:03:57 -07:00
0f47ca61a6 Clean up formatting of photo shortcode 2022-11-03 17:03:25 -07:00
3f1bd948eb Remove <author> from the Atom entry metadata 2022-11-03 17:02:15 -07:00
aea3489ddb OOPS! Fix permalinks on photo pages 2022-11-03 17:01:55 -07:00
3ef4c7eb1b Add a set of templates to generate an Atom feed! 2022-11-03 09:16:25 -07:00
e83ba90c62 Update the photo_thumbnail template to return the thumbnail itself, unmodified, if no changes are required 2022-11-03 09:16:13 -07:00
4c3a61ad5d Reformat the head template a little bit 2022-11-03 09:15:45 -07:00
aeafd0b530 Get the Atom output type all set up
Atom feed is generated at feed.xml using the index.atom.xml template
2022-11-03 09:15:14 -07:00
244220b914 Add email to Author config 2022-11-03 09:14:36 -07:00
48056e5be8 Convert site config to YAML and move it to config/
Keep the old site config.toml around just in case.
2022-11-02 17:46:26 -07:00
cf5d8755ac Add photo thumbnail, category, series, and tags to RSS items 2022-11-02 09:14:47 -07:00
d8e842604d Add orrs-island photo and a bunch of metadata to some posts 2022-10-31 08:42:08 -07:00
8d0048bd25 Clean up the development CSS styles a little bit 2022-10-31 08:41:54 -07:00
55f0526f6e Remove the .post-content section around {{ .Content }} 2022-10-31 08:41:40 -07:00
76e3da0de1 Add the series to the content header 2022-10-31 08:41:24 -07:00
ecb39a9298 Move footer tags list to a partial so photos and blogs can use the same template
Simplify the blog post layout by removing the <article> tag
2022-10-31 08:40:17 -07:00
c5427866c6 Add Harpswell Sunset post 2022-10-31 07:50:08 -07:00
30ba875393 Add hugo-new-photo.py to create a photo post from a list of photos 2022-10-31 07:49:56 -07:00
fd4ab996c5 Use .HasShortcode instead of setting the "includes_" variables in .Page.Store 2022-10-31 07:49:31 -07:00
acb1cf3c35 Use .Page.Store instead of .Page.Scratch for conditional includes of support JS
I saw this on one of the Hugo documentation pages, so I copied it. I am not sure what the difference is.
2022-10-30 11:39:33 -07:00
5920625753 Try to fix the debug EXIF info table -- I don't think this quite does it 2022-10-30 11:35:11 -07:00
16af88e08a Let the photos section adapt to light/dark mode 2022-10-30 11:34:45 -07:00
57947282ce Add a shortcode to embed a photo post in a blog post 2022-10-30 11:31:47 -07:00
e7b2cb493a Redo the blog list layout to make it work a little better on narrow screens 2022-10-30 11:30:41 -07:00
8b4273fcae Delete .gitmodules
This is leftover from a loooong time ago.
2022-10-27 09:24:28 -04:00
ac991083a0 Remove the border from the site header when it's pinned to the top 2022-10-26 09:20:27 -04:00
0a410b0ad8 Expand the theme colors to full 6-digit hex values 2022-10-26 09:20:06 -04:00
e1e63b1499 Two photos from Boston 2022-10-26 09:19:47 -04:00
d45ad6e1ae Add images/orientation_angle partial that returns the angle (in degress) of the orientation from an image's Exif info 2022-10-25 17:55:47 -04:00
4b3abd2a17 Merge branch 'photos' 2022-10-25 17:52:21 -04:00
83f3385bf8 Specify clip-path along with -webkit-clip-path for .circular 2022-10-25 17:51:13 -04:00
1e8b80481e Photos page styles
- Create items in the grid for the month and year
- Use child selectors where possible
- fix the layout
2022-10-25 17:48:20 -04:00
660a1a79b5 Clean up the styles of headings and paragraphs 2022-10-25 17:38:41 -04:00
3ec529525a Remove a bunch of the reset styles 2022-10-25 17:38:14 -04:00
1200833ef3 Get thumbnails oriented the right way before resizing 2022-10-25 17:37:46 -04:00
397c2262be Clean up the footer layout and styles 2022-10-25 17:37:15 -04:00
27f88ab3b5 Clean up the header layout and styles 2022-10-25 17:36:06 -04:00
b5a22374bf Use item-spacing for between the footer of a post and the content 2022-10-25 17:34:23 -04:00
edb9c49f21 Ignore *~ files 2022-10-25 17:33:47 -04:00
35d55c1cf7 Make the about page not-a-draft 2022-10-25 17:33:40 -04:00
782f613d5a Fix up the home page; make the font size bigger; clean up the layout 2022-10-25 17:33:03 -04:00
77d677afed Add langs.title to mytilene photo 2022-10-21 11:10:36 -07:00
d738354e41 Default single.html template cleanup 2022-10-21 11:10:23 -07:00
5bfa439700 Bunch of misc photos template clean up 2022-10-21 11:09:30 -07:00
f23b047a0f Bring back line-height: 1 2022-10-21 11:09:07 -07:00
b8b614e68d Clean up some photos selectors -- use child selectors instead of descendant 2022-10-21 11:08:16 -07:00
ff14784468 P5.js post: Wrap all the code blocks in figure shortcodes and fix the railroad diagrams 2022-10-21 11:07:45 -07:00
23fc76b1f5 Move the li_grid_with_date template to blog/ 2022-10-21 11:07:05 -07:00
84c7c714ed Use JS to show/hide railroad diagrams based on page width (thanks @hober!) 2022-10-21 11:06:13 -07:00
c9c5889bed Ignore log files 2022-10-20 17:15:03 -07:00
539 changed files with 117811 additions and 2350 deletions

3
.gitattributes vendored
View file

@ -1,2 +1,5 @@
*.jpg filter=lfs diff=lfs merge=lfs -text
*.jpeg filter=lfs diff=lfs merge=lfs -text
*.pxm filter=lfs diff=lfs merge=lfs -text
*.mov filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text

9
.gitignore vendored
View file

@ -1,4 +1,11 @@
node_modules/
public/
resources/
/documentation/mirrors/
/resources/
.hugo_build.lock
*.log
*.orig
*~
# Backup files for Markdown files processed in-place with sed
*.md-e

21
.gitmodules vendored
View file

@ -1,3 +1,18 @@
[submodule "themes/paper"]
path = themes/paper
url = ssh://git@github.com:erynofwales/hugo-paper.git
[submodule "themes/platters"]
path = themes/platters
url = nutmeg:git/hugo-theme-platters.git
[submodule "themes/termlite"]
path = themes/termlite
url = git@github.com:erynofwales/hugo-theme-termlite.git
[submodule "themes/resource-builders"]
path = themes/resource-builders
url = git@github.com:erynofwales/hugo-resource-builders.git
[submodule "themes/image-utils"]
path = themes/image-utils
url = git@github.com:erynofwales/hugo-image-utilities.git
[submodule "themes/photostream"]
path = themes/photostream
url = git@github.com:erynofwales/hugo-theme-photostream.git
[submodule "themes/feeds"]
path = themes/feeds
url = git@github.com:erynofwales/hugo-theme-feeds.git

View file

@ -0,0 +1,15 @@
snippet jp "lang jp shortcode" w
{{< lang jp >}}$1{{< /lang >}}
endsnippet
snippet jpp "lang jp shortcode with expansion" w
{{% lang jp %}}$1{{% /lang %}}
endsnippet
snippet tess "tess shortcode" w
{{< tess >}}
endsnippet
snippet ruby "ruby shortcode" w
{{< ruby "$1" >}}$2{{< /ruby >}}
endsnippet

View file

@ -0,0 +1,4 @@
-- Eryn Wells <eryn@erynwells.me>
vim.bo.shiftwidth = 2
vim.bo.softtabstop = 2

View file

@ -0,0 +1,6 @@
-- Eryn Wells <eryn@erynwells.me>
local root = gitTopLevelDirectory()
vim.opt_local.path:prepend(root .. "/assets/scripts/**")
vim.opt_local.path:prepend(root .. "/assets/styles/**")
vim.opt_local.path:prepend(root .. "/layouts/**")

View file

@ -0,0 +1,4 @@
-- Eryn Wells <eryn@erynwells.me>
local root = gitTopLevelDirectory()
vim.opt_local.path:prepend(root .. "/assets/scripts/**")

View file

@ -0,0 +1,11 @@
-- Eryn Wells <eryn@erynwells.me>
vim.bo.textwidth = 80
vim.cmd [[
iabbrev tokyo Tōkyō
iabbrev Tokyo Tōkyō
iabbrev kyoto Kyōto
iabbrev Kyoto Kyōto
iabbrev xx &times;
]]

8
.nvim/ftdetect/html.lua Normal file
View file

@ -0,0 +1,8 @@
-- Eryn Wells <eryn@erynwells.me>
local filetypedetectGroup = vim.api.nvim_create_augroup("HugoHTMLTemplates", {clear = true})
vim.api.nvim_create_autocmd({"BufRead", "BufNewFile"}, {
pattern = {"**/layouts/**/*.html"},
group = filetypedetectGroup,
command = "set ft=gohtmltmpl",
})

View file

@ -1,9 +1,42 @@
# Eryn Wells <eryn@erynwells.me>
DEPLOY_LOCATION=eryn@nutmeg.erynwells.me:/srv/www/erynwells.me/html
BUILD_DIR=public
.PHONY: deploy
deploy:
hugo
rsync -avz --no-times --no-perms --delete public/ $(DEPLOY_LOCATION)
CONTENT_PATH=content
DEPLOY_USER=eryn
DEPLOY_HOSTNAME=nutmeg.erynwells.me
DEPLOY_PATH=/srv/www/erynwells.me/html
DEPLOY_LOCATION=$(DEPLOY_USER)@$(DEPLOY_HOSTNAME):$(DEPLOY_PATH)
HOSTNAME=$(shell hostname -s)
NETHACK_LOGFILE=$(shell command nethack --showpaths | grep scoredir | sed 's/.*"\(.*\)".*/\1/g')/logfile
NETHACK_LOGFILE_DATA_FILE=data/nethack/logfile/$(HOSTNAME).json
.PHONY: site deploy clean
site:
@echo "Building site"
hugo --buildFuture --enableGitInfo --destination "$(BUILD_DIR)"
deploy: site
@echo "Deploying to $(DEPLOY_LOCATION)"
rsync -avz --no-times --no-perms --delete "$(BUILD_DIR)/" "$(DEPLOY_LOCATION)"
git tag -f deploy-$(shell date +%Y-%m-%d)
deployall: nethack deploy
nethack: nethack-logfile nethack-commit
nethack-logfile: $(NETHACK_LOGFILE)
ifeq (,$(wildcard $<))
@echo "Importing Nethack logfile from $(NETHACK_LOGFILE)"
scripts/import-nethack-logfile.py -o $(NETHACK_LOGFILE_DATA_FILE) $<
endif
nethack-commit: $(NETHACK_LOGFILE_DATA_FILE)
if ! git diff --quiet $<; then git commit -m "Update Nethack logfile for $(HOSTNAME)" -- $<; fi
clean:
rm -rf "$(BUILD_DIR)/"

9
archetypes/link.md Normal file
View file

@ -0,0 +1,9 @@
---
title: "{{ replace .Name "-" " " | title }}"
slug: link-{{ .Name }}
date: {{ .Date }}
categories: links
draft: true
tags: []
---

View file

@ -0,0 +1,7 @@
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
{{< figures/p5 id="sketch" >}}

View file

@ -0,0 +1,20 @@
const sketch = p => {
p.setup = () => {
const sketchContainer = document.querySelector('#sketch');
const canvasWidth = parseFloat(getComputedStyle(sketchContainer).width);
let canvas = p.createCanvas(canvasWidth, canvasWidth);
canvas.canvas.removeAttribute('style');
sketchContainer.appendChild(canvas.canvas);
p.pixelDensity(p.displayDensity());
};
p.draw = () => {
p.background(255);
p.strokeWeight(4);
p.stroke(0, 0, 255);
p.circle(100, 100, 100);
};
};
new p5(sketch, 'sketch');

10
archetypes/weeknotes.md Normal file
View file

@ -0,0 +1,10 @@
---
title: "Notes on {{ time.Now.Format "2006" }}W%%WEEK_NUMBER%%"
slug: weeknotes-{{ time.Now.Format "2006" }}w%%WEEK_NUMBER%%
date: {{ .Date | time.Format "2006-01-02" }}
categories: weeknotes
tags:
- Weeknotes
draft: true
---

View file

@ -0,0 +1,18 @@
/************************
* PARAGRAPH-SPACED LIST
************************/
p + .paragraph-spaced-list {
margin-block-start: var(--space-paragraph);
}
.paragraph-spaced-list {
li + li {
margin-block-start: var(--space-paragraph);
}
}

View file

@ -0,0 +1,42 @@
.home-latest {
display: grid;
grid-column: main-start / main-end;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: min-content min-content;
grid-template-areas:
"blog1 blog1 blog2 blog2"
"photo1 photo2 photo3 photo4";
.home-latest__blog {
margin-block-end: var(--space-m);
}
.home-latest__blog:nth-of-type(1) {
grid-area: blog1;
border-right: 2px dashed var(--gray6);
padding-inline-end: var(--space-s);
}
.home-latest__blog:nth-of-type(2) {
grid-area: blog2;
padding-inline-start: var(--space-s);
}
.home-latest__photo {
}
}
@media screen and (max-width: 480px) {
.home-latest {
grid-template-columns: 1fr 1fr;
grid-template-rows: repeat(min-content, 4);
grid-template-areas:
"blog1 blog2"
"photo1 photo2"
"photo3 photo4";
}
}
p + .home-latest {
margin-block-start: var(--space-paragraph);
}

100
assets/css/099_nethack.css Normal file
View file

@ -0,0 +1,100 @@
/******************
* NETHACK LOGFILE
******************/
#dungeon-background {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: -1;
filter: brightness(0.3);
}
.nethack-logfile {
margin-inline-start: 0;
padding-inline-start: 0;
.nethack-logentry {
align-items: first baseline;
display: grid;
grid-template-columns: min-content min-content auto min-content;
grid-template-areas:
"list-marker entry-marker entry-date entry-character-descriptor"
". . entry-description entry-description"
". . entry-stats entry-stats";
gap: var(--space-xs);
margin-inline-start: 0;
}
}
.nethack-logentry {
&:not(:last-child) {
margin-block-end: var(--space-l);
}
&::before {
grid-area: list-marker;
}
.nethack-logentry__marker {
grid-area: entry-marker;
}
.nethack-logentry__date {
grid-area: entry-date;
line-height: 1;
margin: 0;
padding: 0;
}
.nethack-logentry__character-descriptor {
font-family: var(--font-family-monospace);
font-size: var(--text-s);
grid-area: entry-character-descriptor;
line-height: 1;
white-space: nowrap;
}
.nethack-logentry__description {
grid-area: entry-description;
margin: 0;
}
.nethack-logentry__stats {
border: 0;
color: var(--text-color-secondary);
font-family: var(--font-family-monospace);
font-size: var(--text-s);
grid-area: entry-stats;
margin-block: 0;
width: 100%;
-webkit-border-horizontal-spacing: 0;
-webkit-border-vertical-spacing: 0;
}
.nethack-logentry__stats {
padding: 0;
text-transform: uppercase;
vertical-align: bottom;
white-space: nowrap;
thead {
font-weight: bolder;
}
.nethack-logentry__score,
.nethack-logentry__hp,
.nethack-logentry__level {
width: 16rem;
text-align: right;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

106247
assets/scripts/lib/p5-1.5.0.js Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,758 @@
const NUMBER_OF_ROOMS = 12;
const TUNNEL_PASSES = 3;
class Cell {
static CORRIDOR = "#";
static DOOR_CLOSED = "+";
character;
characterColor;
backgroundColor;
constructor(char, charColor) {
this.character = char;
}
empty() { this.character = " "; }
floor() { this.character = "."; }
upStair() { this.character = "<"; }
downStair() { this.character = ">"; }
corridor() { this.character = Cell.CORRIDOR; }
topLeftWall() { this.character = "┌"; }
topRightWall() { this.character = "┐"; }
bottomLeftWall() { this.character = "└"; }
bottomRightWall() { this.character = "┘"; }
horizontalWall() { this.character = "─"; }
verticalWall() { this.character = "│"; }
doorClosed() { this.character = Cell.DOOR_CLOSED; }
isEmpty() { return !this.character || this.character === " "; }
isDoor() { return this.character === Cell.DOOR_CLOSED; }
isCorridor() { return this.character === Cell.CORRIDOR; }
canBecomeDoor() { return this.character === "─" || this.character === "│" }
}
class Point {
x = 0;
y = 0;
constructor(x, y) {
if (x) { this.x = x; }
if (y) { this.y = y; }
}
*neighbors() {
const x = this.x;
const y = this.y;
yield new Point(x - 1, y - 1);
yield new Point(x, y - 1);
yield new Point(x + 1, y - 1);
yield new Point(x - 1, y);
yield new Point(x + 1, y);
yield new Point(x - 1, y + 1);
yield new Point(x, y + 1);
yield new Point(x + 1, y + 1);
}
equalsPoint(other) { return this.x === other.x && this.y === other.y; }
}
class Size {
width = 0;
height = 0;
constructor(width, height) {
this.width = width;
this.height = height;
}
}
class Rect {
origin = new Point();
size = new Size();
static fromCoordinates(x, y, w, h) {
return new Rect(new Point(x, y), new Size(w, h));
}
constructor(origin, size) {
this.origin = origin;
this.size = size;
}
get minX() { return this.origin.x; }
get minY() { return this.origin.y; }
get maxX() { return this.origin.x + this.size.width; }
get maxY() { return this.origin.y + this.size.height; }
get width() { return this.size.width; }
get height() { return this.size.height; }
get area() { return this.size.width * this.size.height; }
*xCoordinates() {
for (let x = this.minX; x <= this.maxX; x++) {
yield x;
}
}
*yCoordinates() {
for (let y = this.minY; y <= this.maxY; y++) {
yield y;
}
}
insetRect(inset) {
const twiceInset = 2 * inset;
return Rect.fromCoordinates(
this.origin.x + inset,
this.origin.y + inset,
this.size.width - twiceInset,
this.size.height - twiceInset
);
}
intersects(otherRect) {
if (otherRect.minX > this.maxX)
return false;
if (otherRect.maxX < this.minX)
return false;
if (otherRect.minY > this.maxY)
return false;
if (otherRect.maxY < this.minY)
return false;
return true;
}
}
class Grid {
#size;
#cells = [];
#rooms = [];
constructor(width, height) {
this.#size = new Size(width, height);
this.#cells = new Array(width * height);
for (let i = 0; i < this.#cells.length; i++) {
this.#cells[i] = new Cell(" ");
}
}
get bounds() { return new Rect(new Point(), this.#size); }
get width() { return this.#size.width; }
get height() { return this.#size.height; }
get rooms() { return this.#rooms; }
generate(p, roomGeneratorClass, tunnelGeneratorClass) {
this.#generateRooms(p, new roomGeneratorClass(this, NUMBER_OF_ROOMS));
this.#placeStairs();
this.#digCorridors(p, new tunnelGeneratorClass(this, TUNNEL_PASSES));
}
#generateRooms(p, generator) {
generator.generate(p);
this.#rooms = generator.rooms;
}
#placeStairs() {
const indexOfRoomWithUpStairs = randomInt(this.#rooms.length);
const coordinateOfUpStair = this.#rooms[indexOfRoomWithUpStairs].randomPoint();
this.cellAt(coordinateOfUpStair.x, coordinateOfUpStair.y).upStair();
while (true) {
let indexOfRoomForDownStair = randomInt(this.#rooms.length);
if (indexOfRoomForDownStair == indexOfRoomWithUpStairs) {
continue;
}
const coordinateOfDownStair = this.#rooms[indexOfRoomForDownStair].randomPoint();
this.cellAt(coordinateOfDownStair.x, coordinateOfDownStair.y).downStair();
break;
}
}
#digCorridors(p, generator) {
generator.generate(p);
}
pointIsInBounds(pt) { return pt.x >= 0 && pt.x < this.width && pt.y >= 0 && pt.y < this.height; }
cellAt(x, y) { return this.#cells[y * this.width + x]; }
}
class Room {
#rect;
constructor(rect) {
this.#rect = rect;
}
get bounds() { return this.#rect; }
get minX() { return this.#rect.minX; }
get minY() { return this.#rect.minY; }
get maxX() { return this.#rect.maxX; }
get maxY() { return this.#rect.maxY; }
randomPoint() {
return new Point(
this.#rect.minX + 1 + randomInt(this.#rect.size.width - 2),
this.#rect.minY + 1 + randomInt(this.#rect.size.height - 2)
);
}
transformCellAt(pt, cell) {
const minX = this.minX;
const minY = this.minY;
const maxX = this.maxX;
const maxY = this.maxY;
const x = pt.x;
const y = pt.y;
if (y === minY && x === minX) { cell.topLeftWall(); }
else if (y === minY && x === maxX) { cell.topRightWall(); }
else if (y === maxY && x === minX) { cell.bottomLeftWall(); }
else if (y === maxY && x === maxX) { cell.bottomRightWall(); }
else if (y === minY || y === maxY) { cell.horizontalWall(); }
else if (x === minX || x === maxX) { cell.verticalWall(); }
else if ((x > minX && x < maxX) && (y > minY && y < maxY)) { return cell.floor(); }
}
}
class NRandomRoomsGenerator {
static MIN_ROOM_DIMENSION = 7;
static MAX_ROOM_DIMENSION = 12;
#numberOfRooms = 12;
#rooms;
#grid;
constructor(grid, numberOfRooms) {
this.#grid = grid;
if (numberOfRooms) {
this.#numberOfRooms = numberOfRooms;
}
}
get rooms() {
if (!this.#rooms) {
this.#generateRooms();
}
return this.#rooms;
}
get #bounds() { return this.#grid.bounds; }
generate(p) {
this.#generateRooms();
for (let i = 0; i < this.#rooms.length; i++) {
let room = this.#rooms[i];
for (let y = room.minY; y <= room.maxY; y++) {
for (let x = room.minX; x <= room.maxX; x++) {
let point = new Point(x, y);
let cell = this.#grid.cellAt(x, y);
room.transformCellAt(point, cell);
cell.characterColor = p.color(255);
}
}
}
}
#generateRooms() {
let rects = new Array();
const sizeRange = NRandomRoomsGenerator.MAX_ROOM_DIMENSION - NRandomRoomsGenerator.MIN_ROOM_DIMENSION;
while (rects.length < this.#numberOfRooms) {
const randomSize = new Size(
NRandomRoomsGenerator.MIN_ROOM_DIMENSION + randomInt(sizeRange),
NRandomRoomsGenerator.MIN_ROOM_DIMENSION + randomInt(sizeRange)
);
const randomOrigin = new Point(
this.#bounds.minX + randomInt(this.#bounds.maxX - randomSize.width),
this.#bounds.minY + randomInt(this.#bounds.maxY - randomSize.height)
);
const proposedRoomRect = new Rect(randomOrigin, randomSize);
// Check that the rect doesn't intersect with any other rects.
if (rects.some(e => e.intersects(proposedRoomRect))) {
continue;
}
rects.push(proposedRoomRect);
}
rects.sort((a, b) => {
if (a.origin.x < b.origin.x) { return -1; }
if (a.origin.x > b.origin.x) { return 1; }
if (a.origin.y < b.origin.y) { return -1; }
if (a.origin.y > b.origin.y) { return 1; }
return 0;
});
this.#rooms = rects.map(r => new Room(r.insetRect(1)));
}
}
class TunnelGenerator {
static MAX_DOORS = 100;
#grid;
#passes = 3;
#numberOfDoorsPlaced = 0;
constructor(grid, passes) {
this.#grid = grid;
if (passes) { this.#passes = passes; }
}
generate(p) {
console.group("Digging tunnels");
if (this.#passes >= 1) {
this.#doPassOne(p);
}
if (this.#passes >= 2) {
this.#doPassTwo(p);
}
if (this.#passes >= 3) {
this.#doPassThree(p);
}
console.groupEnd();
}
#doPassOne(p) {
console.group("Pass 1");
this.#iterateAndConnectRoomsWithOffset(p, 1);
console.groupEnd();
}
#doPassTwo(p) {
console.group("Pass 2");
this.#iterateAndConnectRoomsWithOffset(p, 2);
console.groupEnd();
}
#doPassThree(p) {
console.group("Pass 3");
this.#iterateAndConnectRoomsWithOffset(p, 3);
console.groupEnd();
}
#iterateAndConnectRoomsWithOffset(p, offset) {
let rooms = this.#grid.rooms;
const numberOfRooms = rooms.length;
for (let i = 0; i < numberOfRooms - offset; i++) {
let fromRoom = rooms[i];
let toRoom = rooms[i + offset];
let [fromPoint, toPoint] = this.#findPointFromRoomToRoom(fromRoom, toRoom);
if (!fromPoint || !toPoint) {
continue;
}
for (let neighbor of fromPoint.neighbors()) {
if (!this.#grid.pointIsInBounds(neighbor)) {
continue;
}
let cell = this.#grid.cellAt(neighbor.x, neighbor.y);
if ((neighbor.x === fromPoint.x || neighbor.y === fromPoint.y) && cell.canBecomeDoor()) {
cell.doorClosed();
this.#numberOfDoorsPlaced++;
break;
}
}
const successfullyFoundTargetPoint = this.#digCorridorFromPointToPoint(p, fromPoint, toPoint);
if (successfullyFoundTargetPoint) {
for (let neighbor of toPoint.neighbors()) {
if (!this.#grid.pointIsInBounds(neighbor)) {
continue;
}
let cell = this.#grid.cellAt(neighbor.x, neighbor.y);
if ((neighbor.x === toPoint.x || neighbor.y === toPoint.y) && cell.canBecomeDoor()) {
cell.doorClosed();
this.#numberOfDoorsPlaced++;
break;
}
}
}
}
}
/**
* Dig a corridor from fromPoint to toPoint, assuming that both points are
* adjacent to valid locations for doors on the map.
*
* This is as close a copy of dig_corridor in the Nethack source as I could
* muster. It's not exactly pretty. This method assumed
*/
#digCorridorFromPointToPoint(p, fromPoint, toPoint) {
const MAX_STEPS = 500;
if (!fromPoint || !toPoint) {
return;
}
const fromX = fromPoint.x;
const toX = toPoint.x;
const fromY = fromPoint.y;
const toY = toPoint.y;
let curX = fromX;
let curY = fromY;
let dx = 0;
let dy = 0;
// Set up the initial direction of the dig.
if (toX > curX) {
dx = 1;
} else if (toY > curY) {
dy = 1;
} else if (toX < curX) {
dx = -1;
} else {
dy = -1;
}
curX -= dx;
curY -= dy;
let steps = 0;
while (curX !== toX || curY !== toY) {
if (steps++ > MAX_STEPS) {
return false;
}
curX += dx;
curY += dy;
if (curX >= this.#grid.width - 1 || curX <= 0 || curY <= 0 || curY >= this.#grid.height - 1) {
return false;
}
let cell = this.#grid.cellAt(curX, curY);
if (cell.isEmpty()) {
cell.corridor();
} else if (!cell.isCorridor()) {
return false;
}
let dix = Math.abs(curX - toX);
let diy = Math.abs(curY - toY);
if (dix > diy && diy) {
const random = randomInt(dix - diy + 1);
if (!random) {
dix = 0;
}
} else if (diy > dix && dix) {
const random = randomInt(dix - diy + 1);
if (!random) {
diy = 0;
}
}
if (dy && dix > diy) {
const ddx = curX > toX ? -1 : 1;
let cell = this.#grid.cellAt(curX + ddx, curY);
if (cell.isEmpty() || cell.isCorridor()) {
dx = ddx;
dy = 0;
continue;
}
} else if (dx && diy > dix) {
const ddy = curY > toY ? -1 : 1;
let cell = this.#grid.cellAt(curX, curY + ddy);
if (cell.isEmpty() || cell.isCorridor()) {
dy = ddy;
dx = 0;
continue;
}
}
cell = this.#grid.cellAt(curX + dx, curY + dy);
if (cell.isEmpty() || cell.isCorridor()) {
continue;
}
if (dx) {
dx = 0;
dy = toY < curY ? -1 : 1;
} else {
dy = 0;
dx = toX < curX ? -1 : 1;
}
cell = this.#grid.cellAt(curX + dx, curY + dy);
if (cell.isEmpty() || cell.isCorridor()) {
continue;
}
dy = -dy;
dx = -dx;
}
return true;
}
#findPointFromRoomToRoom(fromRoom, toRoom) {
const fromRoomBounds = fromRoom.bounds;
const toRoomBounds = toRoom.bounds;
let foundFromPoint = false;
let foundToPoint = false;
let fromPoint;
let toPoint;
if (fromRoomBounds.maxX < toRoomBounds.minX) {
// fromRoom is farther left than toRoom
fromPoint = new Point(fromRoomBounds.maxX, fromRoomBounds.minY + 1 + randomInt(fromRoomBounds.height - 2));
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
for (let y of fromRoomBounds.yCoordinates()) {
fromPoint.y = y;
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
if (foundFromPoint) {
break;
}
}
if (!foundFromPoint) {
return [];
}
toPoint = new Point(toRoomBounds.minX, toRoomBounds.minY + 1 + randomInt(toRoomBounds.height - 2));
foundToPoint = this.#canPlaceDoorAt(toPoint);
for (let y of toRoomBounds.yCoordinates()) {
toPoint.y = y;
foundToPoint = this.#canPlaceDoorAt(toPoint);
if (foundToPoint) {
break;
}
}
if (!foundToPoint) {
return [];
}
fromPoint.x += 1;
toPoint.x -= 1;
} else if (fromRoomBounds.minX > toRoomBounds.maxX) {
// fromRoom is farther right than toRoomBounds.
fromPoint = new Point(toRoomBounds.maxX, toRoomBounds.minY + 1 + randomInt(toRoomBounds.height - 2));
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
for (let y of toRoomBounds.yCoordinates()) {
fromPoint.y = y;
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
if (foundFromPoint) {
break;
}
}
if (!foundFromPoint) {
return [];
}
toPoint = new Point(fromRoomBounds.minX, fromRoomBounds.minY + 1 + randomInt(fromRoomBounds.height - 2));
foundToPoint = this.#canPlaceDoorAt(toPoint);
for (let y of fromRoomBounds.yCoordinates()) {
toPoint.y = y;
foundToPoint = this.#canPlaceDoorAt(toPoint);
if (foundToPoint) {
break;
}
}
if (!foundToPoint) {
return [];
}
fromPoint.x -= 1;
toPoint.x += 1;
} else if (fromRoomBounds.maxY < (toRoomBounds.minY - 1)) {
// fromRoom is above toRoom
fromPoint = new Point(fromRoomBounds.minX + 1 + randomInt(fromRoomBounds.width - 2), fromRoomBounds.maxY);
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
for (let x of fromRoomBounds.xCoordinates()) {
fromPoint.x = x;
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
if (foundFromPoint) {
break;
}
}
if (!foundFromPoint) {
return [];
}
toPoint = new Point(toRoomBounds.minX + 1 + randomInt(toRoomBounds.width - 2), toRoomBounds.minY);
foundToPoint = this.#canPlaceDoorAt(toPoint);
for (let x of toRoomBounds.xCoordinates()) {
toPoint.x = x;
foundToPoint = this.#canPlaceDoorAt(toPoint);
if (foundToPoint) {
break;
}
}
if (!foundToPoint) {
return [];
}
fromPoint.y += 1;
toPoint.y -= 1;
} else if (fromRoomBounds.minY > (toRoomBounds.maxY + 1)) {
// fromRoom is below toRoom
fromPoint = new Point(toRoomBounds.minX + 1 + randomInt(toRoomBounds.width - 2), toRoomBounds.maxY);
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
for (let x of toRoomBounds.xCoordinates()) {
fromPoint.x = x;
foundFromPoint = this.#canPlaceDoorAt(fromPoint);
if (foundFromPoint) {
break;
}
}
if (!foundFromPoint) {
return [];
}
toPoint = new Point(fromRoomBounds.minX + 1 + randomInt(fromRoomBounds.width - 2), fromRoomBounds.minY);
foundToPoint = this.#canPlaceDoorAt(toPoint);
for (let x of fromRoomBounds.xCoordinates()) {
toPoint.x = x;
foundToPoint = this.#canPlaceDoorAt(toPoint);
if (foundToPoint) {
break;
}
}
if (!foundToPoint) {
return [];
}
fromPoint.y += 1;
toPoint.y -= 1;
}
return [fromPoint, toPoint];
}
#canPlaceDoorAt(pt) {
if (this.#numberOfDoorsPlaced > TunnelGenerator.MAX_DOORS) {
return false;
}
if (!this.#grid.cellAt(pt.x, pt.y).canBecomeDoor()) {
return false;
}
for (let neighbor of pt.neighbors()) {
if (!this.#grid.pointIsInBounds(neighbor)) {
continue;
}
let cell = this.#grid.cellAt(neighbor.x, neighbor.y);
if (cell.isDoor()) {
return false;
}
}
return true;
}
}
function randomInt(n) {
max = Math.floor(n);
return Math.floor(Math.random() * max);
}
let grid;
new p5(p => {
const CELL_WIDTH = 20;
const CELL_HEIGHT = Math.floor(CELL_WIDTH * 1.3);
p.setup = () => {
const container = document.querySelector('#dungeon-background');
console.assert(container, "Missing #dungeon-background element");
canvasWidth = parseFloat(getComputedStyle(container).width);
canvasHeight = parseFloat(getComputedStyle(container).height);
let canvas = p.createCanvas(canvasWidth, canvasHeight);
canvas.canvas.removeAttribute('style');
container.appendChild(canvas.canvas);
p.pixelDensity(p.displayDensity());
p.textFont("Courier");
const gridBounds = Rect.fromCoordinates(
0, 0,
Math.max(80, Math.ceil(canvasWidth / CELL_WIDTH) - 1),
Math.max(24, Math.ceil(canvasHeight / CELL_HEIGHT) - 1)
);
console.log(`Generating grid with size ${gridBounds.size.width} x ${gridBounds.size.height}`);
grid = new Grid(gridBounds.size.width, gridBounds.size.height);
grid.generate(p, NRandomRoomsGenerator, TunnelGenerator);
};
p.draw = () => {
console.log("Drawing");
p.textSize(CELL_HEIGHT);
for (let y = 0; y < grid.height; y++) {
for (let x = 0; x < grid.width; x++) {
let cell = grid.cellAt(x, y);
let fillColor = cell.characterColor ? cell.characterColor : p.color(255);
p.fill(fillColor);
p.textAlign(p.CENTER, p.CENTER);
p.text(cell.character, x * CELL_WIDTH, y * CELL_HEIGHT, CELL_WIDTH, CELL_HEIGHT);
}
}
p.noLoop();
};
}, '#dungeon-background');

View file

@ -0,0 +1,63 @@
import rr from "scripts/lib/railroad.js";
class RailroadDiagramManager {
constructor() {
this.figures = new Map();
this.isCurrentlyNarrow = undefined;
this.diagramBreakpoint = window.matchMedia("(max-width: 450px)");
this.diagramBreakpoint.addEventListener("change", () => {
this.updateVisiblity();
});
}
add(svg) {
const parent = svg.parentElement;
if (!this.figures.has(parent)) {
this.figures.set(parent, []);
}
this.figures.get(parent).push(svg);
parent.removeChild(svg);
}
updateVisiblity() {
const isNarrow = this.diagramBreakpoint.matches;
if (isNarrow === this.isCurrentlyNarrow) {
return;
}
this.isCurrentlyNarrow = isNarrow;
for (let [figure, svgs] of this.figures.entries()) {
for (let svg of svgs) {
const svgHasNarrowClass = svg.classList.contains("narrow");
if (isNarrow && svgHasNarrowClass)
figure.appendChild(svg);
else if (!isNarrow && !svgHasNarrowClass)
figure.appendChild(svg);
else if (svg.parentElement === figure)
figure.removeChild(svg);
}
}
}
}
let railroadDiagramManager = new RailroadDiagramManager();
export function railroadDiagram(builder, elementID, isNarrow) {
const diagram = builder(rr);
const svg = diagram.addTo(document.getElementById(elementID));
if (isNarrow) {
svg.classList.add("narrow");
}
railroadDiagramManager.add(svg);
}
window.addEventListener("DOMContentLoaded", () => {
railroadDiagramManager.updateVisiblity();
});

View file

@ -0,0 +1,123 @@
class RubiksCubeScrambler extends HTMLElement {
static #RandomMoveHysteresisMaxLength = 2;
#shadowRoot;
#movesListElement;
#numberOfMovesToGenerate = 25;
constructor() {
super();
this.#shadowRoot = this.attachShadow({ mode: "open" });
}
scramble() {
console.log("Randomizing Rubik's cube...");
const movesList = this.#movesListElement;
while (movesList.childElementCount > this.#numberOfMovesToGenerate) {
movesList.removeChild(movesList.lastChild);
}
let randomMoveHysteresis = [];
for (let i = 0; i < this.#numberOfMovesToGenerate; i++) {
const randomMove = this.#randomMove(randomMoveHysteresis);
let moveItem;
if (i < movesList.childElementCount) {
moveItem = movesList.children[i];
} else {
moveItem = document.createElement("li");
movesList.appendChild(moveItem);
}
moveItem.classList.add("scrambler__move");
moveItem.classList.remove("scrambler__move--start", "scrambler__move--end");
if (randomMove.includes("2")) {
moveItem.classList.add("scrambler__move--start");
} else if (randomMove.includes("'")) {
moveItem.classList.add("scrambler__move--end");
}
moveItem.innerText = randomMove;
}
}
#randomMove(hysteresis) {
const faces = "FBLRUD";
let move;
do {
move = faces.charAt(Math.floor(Math.random() * faces.length));
} while (hysteresis && hysteresis.includes(move));
if (hysteresis) {
hysteresis.unshift(move);
while (hysteresis.length > RubiksCubeScrambler.#RandomMoveHysteresisMaxLength) {
hysteresis.pop();
}
}
const modifierFactor = Math.random();
if (modifierFactor < 0.33333) {
move = "2" + move;
} else if (modifierFactor < 0.666666) {
move = move + "'";
}
return move;
}
#removeAllMoves() {
const element = this.#movesListElement;
while (element.hasChildNodes()) {
element.removeChild(element.lastChild);
}
}
// MARK: Custom Element
connectedCallback() {
let template = document.getElementById("rubiks-cube-scrambler-template");
console.assert(template, "Couldn't find RubiksCubeScrambler component template in the document");
const shadowRoot = this.#shadowRoot;
shadowRoot.appendChild(template.content.cloneNode(true));
this.#movesListElement = shadowRoot.querySelector(".scrambler__move-list");
shadowRoot
.querySelector("button[name='scramble']")
.addEventListener("click", () => this.scramble());
const patternLengthInputElement = shadowRoot.querySelector(".scrambler__pattern-length > input");
patternLengthInputElement.value = this.#numberOfMovesToGenerate;
patternLengthInputElement.addEventListener("input", event => {
try {
const integerValue = parseInt(event.target.value);
this.#numberOfMovesToGenerate = integerValue;
} catch (e) {
console.error("Non-integer value of pattern length field", e);
}
});
this.scramble();
}
attributeChangedCallback(name, oldValue, newValue) {
console.debug("RubiksCubeScrambler attribute changed", name, oldValue, newValue);
if (name === "count") {
try {
let newIntValue = parseInt(newValue);
this.#numberOfMovesToGenerate = newIntValue;
} catch (e) {
console.error("`count` attribute should have an integer value.", e);
}
}
}
}
window.customElements.define("rubiks-cube-scrambler", RubiksCubeScrambler);

View file

@ -0,0 +1,169 @@
// Eryn Wells <eryn@erynwells.me>
class RubySwitch extends HTMLElement {
static controlSizeInPixels = 32;
static thumbTransitionDuration = 0.1;
static settings = [
{
id: "ruby-switch-none",
value: "none",
label: "あ"
},
{
id: "ruby-switch-both",
value: "both",
label: "<ruby>あ<rt>a</rt></ruby>",
default: true
},
{
id: "ruby-switch-hidden",
value: "hidden",
label: "ab"
},
];
#root;
#thumb;
constructor() {
super();
this.#updateValue(RubySwitch.settings.find(obj => obj.default).value);
this.addEventListener("RubyStyleChanged", event => {
this.#updateValue(event.detail.style);
});
this.#root = this.attachShadow({ mode: "closed" });
this.#buildShadowDOM();
this.#updateThumbPosition(this.#root.querySelector(".control[data-default]"));
}
#updateValue(style) {
this.setAttribute("value", style);
}
get #stylesheet() {
const controlSize = RubySwitch.controlSizeInPixels;
const halfControlSize = controlSize / 2;
return `
#ruby-controls {
box-sizing: border-box;
display: inline-block;
position: relative;
}
#controls {
border: none;
box-sizing: border-box;
display: inline grid;
grid-template-columns: repeat(3, ${controlSize}px);
margin: 0;
overflow: none;
padding: 0;
}
#thumb {
box-sizing: border-box;
box-shadow: 2px 2px 6px #ccc;
border: 0.5px solid #aaa;
border-radius: ${halfControlSize}px;
position: absolute;
top: 0;
height: ${controlSize}px;
width: ${controlSize}px;
z-index: 50;
transition: left ${RubySwitch.thumbTransitionDuration}s;
}
.control {
aspect-ratio: 1;
display: flex;
justify-content: center;
align-items: center;
height: ${controlSize}px;
width: ${controlSize}px;
}
b {
font-weight: normal;
cursor: pointer;
}
label {
z-index: 2;
text-align: center;
}
#ruby-switch-both {
}
`;
}
#buildShadowDOM() {
const root = this.#root;
const style = document.createElement("style");
style.textContent = this.#stylesheet;
root.appendChild(style);
let container = document.createElement("div");
container.id = "ruby-controls";
root.appendChild(container);
let controls = document.createElement("div");
controls.id = "controls";
container.appendChild(controls);
for (const desc of RubySwitch.settings) {
let control = document.createElement("div");
control.classList.add("control")
control.id = desc.id;
control.dataset.value = desc.value;
if (desc.default) {
control.dataset.default = "";
}
controls.appendChild(control);
control.addEventListener("click", event => {
event.stopPropagation();
event.preventDefault();
this.#updateThumbPosition(event.currentTarget);
this.#root.dispatchEvent(new CustomEvent("RubyStyleChanged", {
bubbles: true,
composed: true,
detail: {
style: control.dataset.value,
},
}));
}, { capture: true });
const label = document.createElement("b");
label.innerHTML = desc.label;
control.appendChild(label);
}
const thumb = document.createElement("div");
this.#thumb = thumb;
thumb.id = "thumb";
container.appendChild(thumb);
}
#updateThumbPosition(selectedControl) {
const controls = this.#root.querySelector("#controls");
const trackBoundingRect = controls.getBoundingClientRect();
const controlBoundingRect = selectedControl.getBoundingClientRect();
const offset = controlBoundingRect.left - trackBoundingRect.left;
this.#thumb.style.left = `${offset}px`;
}
}
customElements.define("ruby-switch", RubySwitch);

6
assets/scripts/site.js Normal file
View file

@ -0,0 +1,6 @@
/* site.js
* Eryn Wells <eryn@erynwells.me>
*/
window.addEventListener("DOMContentLoaded", () => {
});

View file

@ -0,0 +1,6 @@
baseURL: https://erynwells.me/
languageCode: en-US
title: ~eryn
copyright: Copyright © 2020—2024 Eryn Wells
defaultContentLanguage: en
enableEmoji: true

View file

@ -0,0 +1,12 @@
en:
languageName: English
weight: 1
es:
languageName: Español
weight: 2
jp:
languageName: 日本語
weight: 3
tok:
languageName: toki pona
weight: 4

View file

@ -0,0 +1,12 @@
goldmark:
renderer:
unsafe: true
parser:
attribute:
block: true
title: true
highlight:
anchorLineNos: true
lineNos: false
lineNumbersInTable: false
noClasses: false

View file

@ -0,0 +1,6 @@
application/rss+xml:
delimiter: .
suffixes: [rss]
application/atom+xml:
delimiter: .
suffixes: [atom, xml]

52
config/_default/menu.yaml Normal file
View file

@ -0,0 +1,52 @@
main:
- identifier: blog
name: Blog
url: /blog/
weight: 10
- identifier: photos
name: Photos
url: /photos/
weight: 20
- identifier: about
name: About
url: /about/
weight: 30
- identifier: feed
name: feed
url: /feed.atom
weight: 40
params:
style: file
social:
- identifier: mastodon
name: Mastodon
url: https://mastodon.social/@erynofwales
weight: 10
params:
shortName: mst
- identifier: github
name: Github
url: https://github.com/erynofwales
weight: 20
params:
shortName: gh
- identifier: instagram
name: Instagram
url: https://instagram.com/erynofwales
weight: 30
params:
shortName: ig
- identifier: feed
name: feed
url: /feed.atom
weight: 40
params:
shortName: feed
targetBlank: false
about:
- identifier: resume
name: Résumé
url: /resume/
- identifier: whereAmI
name: Where Am I
url: /where-am-i/

View file

@ -0,0 +1,15 @@
hugoVersion:
extended: false
min: "0.116.0"
replacements: >-
github.com/erynofwales/hugo-theme-feeds/v2 -> feeds,
github.com/erynofwales/hugo-theme-termlite/v2 -> termlite,
github.com/erynofwales/hugo-theme-photostream/v2 -> photostream,
github.com/erynofwales/hugo-resource-builders/v2 -> resource-builders,
github.com/erynofwales/hugo-image-utilities/v2 -> image-utils
imports:
- path: github.com/erynofwales/hugo-theme-termlite/v2
- path: github.com/erynofwales/hugo-theme-feeds/v2
- path: github.com/erynofwales/hugo-theme-photostream/v2
- path: github.com/erynofwales/hugo-resource-builders/v2
- path: github.com/erynofwales/hugo-image-utilities/v2

View file

@ -0,0 +1,8 @@
RSS:
mediatype: application/rss+xml
baseName: feed
suffixes: [rss]
Atom:
mediatype: application/atom+xml
baseName: feed
suffixes: [atom, xml]

View file

@ -0,0 +1,4 @@
home: [HTML, Atom]
section: [HTML, Atom]
taxonomy: [HTML]
term: [HTML]

View file

@ -0,0 +1,20 @@
author:
name: Eryn Wells
email: eryn@erynwells.me
shortTitle: Eryn Wells
twitter: erynofwales
github: erynofwales
instagram: erynofwales
description: Home page of Eryn Rachel Wells
blog:
yearLimit: 3
photostream:
yearLimit: 3
photos:
gridSize: 200
thumbnailSize: 600

View file

@ -0,0 +1,2 @@
blog: blog/:year/:month/:slug/
photos: photos/:year/:month/:slug/

View file

@ -0,0 +1,2 @@
x:
enableDNT: true

View file

@ -0,0 +1,2 @@
x:
disableInlineCSS: true

View file

@ -0,0 +1,4 @@
category: categories
location: locations
series: series
tag: tags

View file

@ -1,5 +1,8 @@
---
title: Eryn Rachel Wells
layout: single
---
Este es un poco de texto sobre Eryn: quién es, qué le gusta, y por qué existe este sitio.
{{< nobreak >}}Ingeniera de software,{{< /nobreak >}}
alfarera, música, y
{{< nobreak >}}nerd en general.{{< /nobreak >}}

View file

@ -1,5 +1,58 @@
---
title: Eryn Rachel Wells
layout: single
params:
renderHeadingAnchors: false
---
Software engineer, potter, musician, and overall nerd. This is my website.
Hi, I'm Eryn Wells. This is my website. Welcome!
## Latest
Here are some of my most recent posts.
{{< home/latest >}}
## Personal
I'm a queer trans woman, {{< tess >}}' partner, and mom of [two cats][cats]. I
was born in Seattle, {{< abbr Washington >}}WA{{< /abbr >}} and grew up in
Phoenix, {{< abbr Arizona >}}AZ{{< /abbr >}}. I attended [Oberlin College][ob]
where I got a degree in Computer Science. My pronouns are [she/her][pronouns].
You can read more about me on my [about][ab] page, or [get in touch][where-am-i].
## Professional
I've worked as a software engineer since 2011 for a variety of companies around
the San Francisco Bay Area. I joined [Apple][a] in 2016, where I currently work
on password management and authentication technologies.
My [résumé][r] has all the details.
## Hobbies
When I'm not working, you can reliably find me hacking on this website or [some
coding other project][gh]. I'm also a musician, and play piano, Irish tin
whistle, and modular synthesizer. Occasionally I [record][bc] [things][sc]. I
love outer space and astronomy; I will always get excited to look at the moon
with you, or check out anything through a telescope. I enjoy [photograhy][p],
mostly as a travel hobby. And I've been practicing iaido, a traditional Japanese
sword art, since early 2024. Other things I've been into include: bread baking,
bicycling, calligraphy, ceramics, and knitting.
[a]: https://apple.com
[ab]: {{< ref "/about" >}}
[b]: {{< ref "/blog" >}}
[bc]: https://erynwells.bandcamp.com/releases
[cats]: {{< ref "/cats" >}}
[eml]: mailto:Eryn%20Wells<eryn@erynwells.me>
[gh]: https://github.com/erynofwales
[ig]: https://www.instagram.com/erynofwales
[m]: https://mastodon.social/@erynofwales
[n]: {{< ref "/now" >}}
[ob]: https://www.oberlin.edu
[p]: {{< ref "/photos" >}}
[pronouns]: http://pronoun.is/she
[r]: {{< ref "/resume" >}}
[sc]: https://soundcloud.com/purlsnbeeps
[where-am-i]: {{< ref "/about/where-am-i" >}}

View file

@ -1,12 +1,24 @@
---
title: "Hola! 👋🏻"
draft: false
slug: sobre
resources:
- name: me
src: me.jpeg
---
Me llamo Eryn. Mis pronombres son [ella/ella][p]. Esta es me página personal. Bienvenide.
{{< circular_image id=me name=me class="float-right" width=200
alt="Una foto de me, con sombrero, sentando en frente de un fondo de piedra">}}
Soy una mujer trans y queer. Vivo en San Francisco con mis [dos gatos][cats]. Nací en Seattle, WA, y crecía en Phoenix, AZ. Asistí [Oberlin College][ob] donde obtuve un títolo en informática. {{< tess >}} es mi novia.
Me llamo Eryn. Mis pronombres son [ella/ella][p]. Esta es me página personal.
Bienvenide.
Mi lengua nativa es inglés, y también hablo español pero siempre necesito practicar más.
Soy una mujer trans y queer. Vivo en San Francisco con mis [dos gatos][cats].
Nací en Seattle, WA, y crecía en Phoenix, AZ. Asistí [Oberlin College][ob] donde
obtuve un títolo en informática. {{< tess >}} es mi novia.
Mi lengua nativa es inglés, y también hablo español pero siempre necesito
practicar más.
## Pasatiempos
@ -35,14 +47,15 @@ Echa un vistazo a mi [resumen][r] para más detalles.
## Decirme Hola
Puedes encontrarme en muchos rincones del Internet. Estoy más activa en
[Twitter][t] y [Instagram][i]. Publico música en [SoundCloud][sc] y
Puedes [encontrarme en muchos rincones del Internet][where-am-i]. Estoy más
activa en [Twitter][t] y [Instagram][i]. Publico música en [SoundCloud][sc] y
[Bandcamp][bc]. Y para los proyectos de software, estoy en [GitHub][gh].
[p]: http://pronoun.is/she
[cats]: {{< ref "/cats" >}}
[ob]: https://www.oberlin.edu
[r]: {{< ref "/resume" >}}
[r]: {{< ref path="/resume" >}}
[where-am-i]: {{< ref path="about/where-am-i" lang="es" >}}
[t]: https://twitter.com/erynofwales
[i]: https://www.instagram.com/erynofwales/
[sc]: https://soundcloud.com/purlsnbeeps

View file

@ -1,14 +1,16 @@
---
title: "Hi! 👋🏻"
date: 2022-09-03T12:14:32-07:00
draft: true
layout: single
resources:
- name: me
src: me.jpeg
params:
alt: >
Me, wearing a hat and smiling slightly, standing in front of a stone
background.
---
{{< circular_image id=me name=me class="float-right" width=200
alt="A photo of me, wearing a hat, standing in front of a stone background">}}
{{% section class=content--small-right-column %}}
I'm Eryn. My pronouns are [she/her][p]. I'm a queer trans woman. I live in San
Francisco, CA, on the unceded ancestral lands of the Ramaytush Ohlone people,
@ -18,6 +20,10 @@ I attended [Oberlin College][ob] where I got a degree in Computer Science.
I speak English natively, and Spanish too, though I always need more practice.
{{< circular_image id=me name=me class="content--right-column" width=200 >}}
{{% /section %}}
## Hobbies
I've been a musician for most of my life. I started on the piano at age seven,
@ -45,8 +51,8 @@ Check out my [résumé][r] for more details.
## Say Hello
You can find me in lots of other corners of the Internet. I'm most active on
[Twitter][t] and [Instagram][i]. I post music on [SoundCloud][sc] and
You can find me in [lots of other corners of the Internet][where-am-i]. I'm most
active on [Twitter][t] and [Instagram][i]. I post music on [SoundCloud][sc] and
[Bandcamp][bc]. I'm on [GitHub][gh] for coding projects. You can also send me an
[email][eml].
@ -60,3 +66,4 @@ You can find me in lots of other corners of the Internet. I'm most active on
[bc]: https://erynwells.bandcamp.com/releases
[gh]: https://github.com/erynofwales
[eml]: mailto:Eryn%20Wells<eryn@erynwells.me>
[where-am-i]: {{< ref "/about/where-am-i" >}}

View file

@ -1,4 +1,17 @@
@layer page {
main > section > p:not(:last-child) {
margin-bottom: var(--body-item-spacing);
}
img#me {
p:has(img#me) {
display: inline;
grid-column: unset;
margin-bottom: 0;
}
img#me {
margin: 0;
shape-outside: circle(55%);
width: min(200px, 25%);
}
}

View file

@ -0,0 +1,25 @@
---
title: "Dónde encontrarme"
date: 2022-11-11T08:35:26-08:00
slug: donde-encontrarme
---
Aquí está una lista de dónde se puede encontrarme en línea.
## Redes Sociales
- Cohost: [@eryn](https://cohost.org/eryn)
- Instagram: [@erynofwales](https://instagram.com/erynofwales)
- Mastodon: [@erynofwales](https://mastodon.social/@erynofwales)
- Twitter: [@erynofwales](https://twitter.com/erynofwales)
## Contenido
- Bandcamp: [erynwells](https://erynwells.bandcamp.com/releases)
- Soundcloud: [purlsnbeeps](https://soundcloud.com/purlsnbeeps)
- YouTube: [Eryn Wells](https://www.youtube.com/channel/UCWb2pTDlC27R1PucyUPrypA)
- GitHub: [erynofwales](https://github.com/erynofwales)
## La Manera Antigua
- Email: [eryn@erynwells.me](mailto:Eryn%20Wells<eryn@erynwells.me>)

View file

@ -0,0 +1,30 @@
---
title: "Where to Find Me"
date: 2022-11-11T08:35:26-08:00
---
Here's a list of places you can find me online. You can often find me on
services not listed here with the `erynofwales` or `erynrwells` handles.
## Social Media
I'm really only on Instagram and Mastodon these days. My Twitter account is
still live, as an archive, but I don't post on it or look at it. Ditto for
Facebook.
- Facebook: [erynofwales](https://www.facebook.com/erynofwales)
- Instagram: [@erynofwales](https://instagram.com/erynofwales)
- Mastodon: [@erynofwales](https://mastodon.social/@erynofwales)
- Twitter: [@erynofwales](https://twitter.com/erynofwales)
## Content
- Bandcamp: [erynwells](https://erynwells.bandcamp.com/releases)
- GitHub: [erynofwales](https://github.com/erynofwales)
- Soundcloud: [purlsnbeeps](https://soundcloud.com/purlsnbeeps)
- StoryGraph: [erynrwells](https://app.thestorygraph.com/profile/erynrwells)
- YouTube: [Eryn Wells](https://www.youtube.com/channel/UCWb2pTDlC27R1PucyUPrypA)
## The Old Fashioned Way
- Email: [eryn@erynwells.me](mailto:Eryn%20Wells<eryn@erynwells.me>)

View file

@ -1,7 +1,7 @@
---
title: "Booting a Raspberry Pi Over TFTP"
date: 2020-10-13T08:31:52-07:00
draft: false
description: A writeup of how I set up a Raspberry Pi to boot over TFTP to facilitate an operating system development project.
series: ["Raspberry Pi OS Development"]
categories: ["Tech"]
tags: ["Raspberry Pi", "Networking"]

View file

@ -0,0 +1,4 @@
---
title: 2020
date: 2020-01-01
---

View file

@ -7,7 +7,7 @@ categories: ["Music"]
tags: ["Synthesizers", "Electronics", "DIY", "Compositions"]
---
{{< figures/youtube id="gCSwWsxzy_c" title="A timelapse video of me building an Oskitone Scout, set to music produced using the Scout itself">}}
{{< youtube id="gCSwWsxzy_c" title="A timelapse video of me building an Oskitone Scout, set to music produced using the Scout itself" >}}
[Oskitone][oskitone] recently released a new synthesizer: the [Scout][scout].
It's a small monophonic keyboard synth built around an Arduino. It was a quick

View file

@ -41,4 +41,4 @@ I'm so grateful for every one of these people. We've been friends for years and
even though our lives have taken us in so many different directions, we've found
each other again and that is so wonderful.
{{< twitter erynofwales 1447951049076056071 >}}
{{< twitter user=erynofwales id=1447951049076056071 >}}

View file

@ -0,0 +1,4 @@
---
title: 2021
date: 2021-01-01
---

View file

@ -7,7 +7,7 @@ categories: ["Music"]
tags: ["Eurorack", "Synthesizers", "Recordings", "Performances", "Compositions"]
---
{{< figures/youtube id="sqr7g4P85aM" title="A top-down video of me operating a small Eurorack system made of only three modules. Lights flash, an incorporeal hand turns knobs to sculpt the sound." >}}
{{< youtube id="sqr7g4P85aM" title="A top-down video of me operating a small Eurorack system made of only three modules. Lights flash, an incorporeal hand turns knobs to sculpt the sound." >}}
This is my submission to the [Three Module Challenge][3mc] show put on by
Colorado Modular Synth Society in late January 2022. This is my first time

View file

@ -2,14 +2,15 @@
title: Ay, Ella Se Ha Vuelto Adicta a Nethack
date: 2022-04-24T17:36:33-07:00
description: In which I get hooked on that one roguelike (God help me)
draft: false
categories: ["Games"]
tags: ["Nethack", "Video Games"]
---
Hace unas semanas que conecté a mi VPS para averiguar algo. Hay [un
parte][list-tmux-sessions] de [mis dotfiles][zprofile] que ejecuta durante la
iniciación de las sesiones de inicio de ZSH que imprime las sesiones existidos
de `tmux` asociados con mi cuenta. Realizé que había una sesión y me la adjunté.
de `tmux` asociados con mi cuenta. Me dio cuenta que había una sesión y me la
adjunté.
En esa sesión encontré un juego de [Nethack][nethack] que empezaba en enero y
nunca lo completé. Lo completé, me mató un duende, y, pues, el daño ya se me
@ -17,7 +18,7 @@ estuve hecho.
Es posible que me entusiasme un poco.
{{< twitter erynofwales 1510763278691016705 >}}
{{< twitter user=erynofwales id=1510763278691016705 >}}
He mejorado mucho en las últimas semanas. Mis puntajes han crecidos desde 1,000
hasta el mejor juego hasta ahora en que [obtuve 9401 puntos][over9000]. Quién
@ -34,4 +35,4 @@ web. Echa un vistazo a mi [logfile](/nethack) de Nethack para esa.
[nethack]: https://www.nethack.org
[nethackwiki]: https://nethackwiki.com/wiki/Main_Page
[priceid]: https://nethackwiki.com/wiki/Price_identification
[over9000]: https://www.youtube.com/watch?v=ITWMoS2L1oo
[over9000]: https://www.youtube.com/watch?v=ITWMoS2L1oo

View file

@ -2,7 +2,6 @@
title: Oh Dear, She Got Hooked on Nethack Again
date: 2022-04-24T17:36:33-07:00
description: In which I get hooked on that one roguelike (God help me)
draft: false
categories: ["Games"]
tags: ["Nethack", "Roguelikes"]
---
@ -24,7 +23,7 @@ packed with [NetHackWiki][nethackwiki] tabs too, including a pinned one for the
I may have gotten a little carried away a time or two.
{{< twitter erynofwales 1510763278691016705 >}}
{{< twitter user=erynofwales id=1510763278691016705 >}}
I've gotten much better in that time. My scores have increased from the
1000-2000 range to my best game so far in which [I scored 9401

View file

@ -1,6 +1,7 @@
---
title: "Roguelikes I Like"
date: 2022-05-09T08:37:23-07:00
description: Some roguelikes Ive enjoyed recently.
draft: false
resources:
- name: nethack

View file

@ -0,0 +1,36 @@
<svg class="railroad-diagram" width="408" height="62" viewBox="0 0 408 62">
<g transform="translate(.5 .5)">
<g>
<path d="M20 21v20m10 -20v20m-10 -10h20"></path>
</g>
<path d="M40 31h10"></path>
<g>
<path d="M50 31h0"></path>
<path d="M358 31h0"></path>
<g class="terminal ">
<path d="M50 31h0"></path>
<path d="M126 31h0"></path>
<rect x="50" y="20" width="76" height="22" rx="10" ry="10"></rect>
<text x="88" y="35">&#60;audio></text>
</g>
<path d="M126 31h10"></path>
<path d="M136 31h10"></path>
<g class="terminal ">
<path d="M146 31h0"></path>
<path d="M230 31h0"></path>
<rect x="146" y="20" width="84" height="22" rx="10" ry="10"></rect>
<text x="188" y="35">Analyzer</text>
</g>
<path d="M230 31h10"></path>
<path d="M240 31h10"></path>
<g class="terminal ">
<path d="M250 31h0"></path>
<path d="M358 31h0"></path>
<rect x="250" y="20" width="108" height="22" rx="10" ry="10"></rect>
<text x="304" y="35">destination</text>
</g>
</g>
<path d="M358 31h10"></path>
<path d="M 368 31 h 20 m -10 -10 v 20 m 10 -20 v 20"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -1,7 +1,7 @@
---
title: "Making an Audio Scope with P5.js"
date: 2022-08-18T20:48:37-07:00
draft: false
description: A writeup of a small JavaScript waveform visualizer I made with P5.js.
categories: ["Tech"]
tags: ["P5.js", "Programming", "Web", "Art"]
resources:
@ -23,11 +23,13 @@ visualizations. By the end, we'll have something like this:
HTML has the ability to [embed audio][mdn-audio-tag] in a page with the
`<audio>` tag. This one declares a single MP3 file as a source.
{{< figures/code >}}
```html
<audio id="amen">
<source src="amen.mp3" type="audio/mpeg">
</audio>
```
{{< /figures/code >}}
In this form, the `<audio>` element doesn't do anything except declare some
audio that can be played. It's invisible and the user can't interact with it or
@ -47,6 +49,7 @@ destinations could be your computer's speakers or a file.
Here's the entire code snippet that sets up the audio processing I need for the
sketch:
{{< figures/code >}}
```js {linenostart=2}
let analyzerNode = null;
let samples = null;
@ -67,6 +70,7 @@ let audioContext = (() => {
return audioContext;
})();
```
{{< /figures/code >}}
The [`AudioContext`][mdn-audio-context] is the object that encapsulates the
entire node graph. On line 10, I create a new `AudioContext`.
@ -84,21 +88,7 @@ node to the input of the analyzer node, and the output of the analyzer node to
the audio context's `destination` node that routes to the computer's speakers.
Our audio processing graph looks like this:
{{< figures/railroad id="audioContextDiagram" >}}
return rr.Diagram(
rr.Sequence(
rr.Terminal("<audio>"),
rr.Terminal("Analyzer"),
rr.Terminal("destination")));
{{< /figures/railroad >}}
{{< figures/railroad id="audioContextDiagram" class="narrow-only" >}}
return rr.Diagram(
rr.Stack(
rr.Terminal("<audio>"),
rr.Terminal("Analyzer"),
rr.Terminal("destination")));
{{< /figures/railroad >}}
![](diagram.svg)
By itself the AudioContext doesn't actually play any audio. I'll tackle that
next.
@ -109,6 +99,7 @@ Next up is starting playback. The following snippet creates a Play button using
P5.js's DOM manipulation API, and hooks up the button's `click` event to start
and stop playback.
{{< figures/code >}}
```js {linenostart=29}
const playPauseButton = p.createButton('Play');
playPauseButton.position(10, 10);
@ -131,6 +122,7 @@ playPauseButtonElement.addEventListener('click', function() {
}
});
```
{{< /figures/code >}}
Something I found odd while working with these audio components is there isn't a
way to ask any of them if audio is playing back at any given moment. Instead it
@ -147,12 +139,14 @@ The last bit of playback state tracking to do is to listen for when playback
ends because it reached the end of the audio file. I did that with the `ended`
event:
{{< figures/code >}}
```js {linenostart=53}
audioElement.addEventListener('ended', function() {
playPauseButtonElement.dataset.playing = 'false';
playPauseButtonElement.innerHTML = '<span>Play</span>';
}, false);
```
{{< /figures/code >}}
This handler resets the `playing` flag and the label of the button.
@ -160,6 +154,7 @@ This handler resets the `playing` flag and the label of the button.
Now it's time to draw some waveforms! The main part of a P5 sketch is the `draw` method. Here's mine:
{{< figures/code >}}
```js {linenostart=57}
const amplitude = p.height / 2;
const axis = p.height / 2;
@ -184,12 +179,15 @@ for (let i = 0; i < samples.length; i++) {
p.point(i, axis + amplitude * sampleValue);
}
```
{{< /figures/code >}}
The most interesting part of this function starts at line 66 where we get an array of samples from the analyzer node. The `samples` variable is a JavaScript `Float32Array`, with one element for each pixel of width.
{{< figures/code >}}
```js {linenostart=30}
samples = new Float32Array(p.width);
```
{{< /figures/code >}}
Once the sample data is populated from the analyzer, we can render them by
plotting them along the X axis, scaling them to the height of the sketch.

View file

@ -0,0 +1,152 @@
---
title: "Hugo's Dictionary API"
date: 2022-10-13T10:19:02-07:00
description: Ive found Hugos API for collections to be difficult to understand. Heres my attempt to summarize its quirks.
categories: ["Tech"]
tags: ["Hugo", "Web", "API Design"]
series: "Erynwells.me Development"
---
Hugo's templating system has support for dictionaries. Unfortunately the API for
working with them is, frankly, awful. While working on developing some new
templates for this site, I had to figure out how to build up dictionary data
structures and it took me a _long_ time to figure out how to do some basic
operations with them.
Here's a quick summary of what I found.
## Creating Dictionaries
The function to create a dictionary is called [`dict`][dict] and it takes a
variable number of arguments that alternate between keys and values. It reminds
me of this [bizarre and backwards NSDictionary API][nsdictionary-init] in Apple's
Foundation framework. Keys must be strings (or string slices) and values can be
anything. So this:
{{< figures/code >}}
```go-html-template
{{ $d := dict "a" 1 "b" 2 "c" 3 }}
```
{{< /figures/code >}}
creates a structure that looks like this JSON object:
{{< figures/code >}}
```json
{ "a": 1, "b": 2, "c": 3 }
```
{{< /figures/code >}}
You can also create an empty dictionary by calling `dict` with no arguments.
{{< figures/code >}}
```go-html-template
{{ $d := dict }}
```
{{< /figures/code >}}
## Accessing Keys and Values
Statically, you can get a single item in a dictionary with dot syntax. Below,
`$item` will get the value 1.
{{< figures/code >}}
```go-html-template
{{ $item := (dict "a" 1 "b" 2 "c" 3).a }}
```
{{< /figures/code >}}
If you want to get a value with a key you get at render time, you can use the
[`index`][index] function. In the snippet below, `$item` will get the value of
`"b"`, which is 2.
{{< figures/code >}}
```go-html-template
{{ $key := "b" }}
{{ $item := index $key (dict "a" 1 "b" 2 "c" 3) }}
```
{{< /figures/code >}}
`index` doesn't make much sense to me as a verb for accessing values in a
dictionary. It sounds more like an array function, and indeed it's the function
that gives you access to items in arrays. I would like to see another function
with a more dictionary-sounding name, like `get` or `value` or `item`, even if
it were just an alias for `index` underneath.
## Adding Items to a Dictionary
This is a bit complex because, as far as I can tell, dictionaries are immutable.
So, if you want to update a dictionary, you need to combine two dictionaries and
then save it back to the original variable. The [`merge`][merge] function does
that. Here's a snippet:
{{< figures/code >}}
```go-html-template
{{ $d := dict "a" 1 "b" 2 "c" 3 }}
{{ $d = merge $d (dict "b" 4) }}
{{ $item = index "b" $d }}
```
{{< /figures/code >}}
`merge` takes a variable number of arguments, and merges dictionaries left to
right. So, items in dictionaries later in the argument list will override items
in dictionaries earlier in the list.
Just to underscore, you have to set the update dictionary back to the original
variable to complete the update, hence the `$d = ...`.
All that is to say: at the end of that snippet, `$item` will get the value 4.
## A Complex Example: A Dictionary of Arrays
For the previously mentioned template changes I was making, I was updating the
`terms` template for my category taxonomy. For each category, I wanted to show
one section per tag, and a list of all the posts with that tag underneath.
My categories are high level groups like "Tech," "Music," and "Travel." Tags are
more specific topics for the post like "Web" or "Compositions." Pages only ever
have one category but they can have multiple tags.
A `terms` template lets you access an array of terms, and the pages associated
with those terms. You can access the tags attached to a page with the
`.GetTerms` function. Here's what I did, and then I'll talk through it:
{{< figures/code >}}
```go-html-template
{{- $pagesByTag := dict -}}
{{- range $page := .Pages -}}
{{- range $tag := .GetTerms "tags" -}}
{{- $tagName := $tag.Name -}}
{{- if not (in $pagesByTag $tagName) -}}
{{- $pagesByTag = merge $pagesByTag
(dict $tagName (slice $page)) -}}
{{- else -}}
{{- $pagesForTag := index $pagesByTag $tagName -}}
{{- $pagesForTag = $pagesForTag | append $page -}}
{{- $pagesByTag = merge $pagesByTag
(dict $tagName $pagesForTag) -}}
{{- end -}}
{{- end -}}
{{- end -}}
```
{{< /figures/code >}}
`$pagesByTag` is my empty dictionary. It will hold tag names as keys, each
pointing to a slice (array) of page objects. For each page, I get its list of
tags. For each tag, I check `$pagesByTag` to see if it already has a key/value
pair for that tag. If not, I create a new entry in `$pagesByTag` with `merge`.
If it does already, I get the slice for that tag with `index`, add the Page to
the slice with `append`, and then merge the updated slice back into
`$pagesByTag` with `merge`.
It's not too bad once it's all spelled out, but it does feel like more work than
it should take for such simple operations.
I think this API could be improved substantially with some new functions that
operate specifically on dictionaries and that have clear names that describe
what they do.
[dict]: https://gohugo.io/functions/dict/
[index]: https://gohugo.io/functions/index-function/
[merge]: https://gohugo.io/functions/merge/
[nsdictionary-init]: https://developer.apple.com/documentation/foundation/nsdictionary/1574181-dictionarywithobjectsandkeys?language=objc

View file

@ -0,0 +1,34 @@
---
title: "Lunar Eclipse 🌝"
date: 2022-11-07T08:37:45-08:00
description: A quick note about the upcoming lunar eclipse in the morning of 2022-11-08.
categories: Space
tags: [Moon, Lunar Eclipse]
---
I shouldn't be surprised (but I am) that the lunar eclipse happening tomorrow
morning has [its own Wikipedia page][wp]. It won't be visible at all from most
of Europe and Africa, but it will be from most of North America, and on the west
coast of North America, we'll be able to see it all. Yay!
All the times on that page are in UTC. Here are some handy conversions (in 24-hr
form) to PST for those of us on the US west coast:
| Contact | Time (PST) |
|:--------:|:----------:|
| P1 | 00:02 |
| U1 | 01:09 |
| U2 | 02:16 |
| Max | 02:59 |
| U3 | 03:41 |
| U4 | 04:49 |
| P4 | 04:56 |
If these times make no sense to you, the eclipse starts at roughly midnight
tonight, the total eclipse is between 02:16 and 03:41, and it ends at 04:56.
More information about contact points for lunar eclipses can be found in the
Timing section on the Wikipedia page for [Lunar Eclipse][wp-le].
[wp]: https://en.wikipedia.org/wiki/November_2022_lunar_eclipse
[wp-le]: https://en.wikipedia.org/wiki/Lunar_eclipse#Timing

View file

@ -0,0 +1,66 @@
---
title: "My Best Nethack Game (So Far)"
date: 2022-11-24T09:13:15-05:00
description: A summary of my best-to-date game of Nethack.
categories: ["Games"]
tags: ["Nethack", "Roguelikes", "Video Games"]
resources:
- name: wishing
src: wishing.png
title:
- name: oracle
src: oracle.png
title:
---
I just finished my best ever game of Nethack. I earned 31,118 points as a level
9 Valkyrie.
Some highlights:
I got all the way to the bottom of the Mines, fought several vampires and
trolls, but somehow completely missed the luckstone. I did pick up a grey stone,
but it ended up being a touchstone.
I got a Wand of Wishing! I was zap testing wands in Minetown and the game asked
me for a wish! I had no idea what to wish for -- it was my first time getting a
wish 😱 -- but I had been watching [Adeon's Nethack speedrun][adeon] at the 2017
Roguelike Celebration and remembered him wishing for some absurdly qualified
dragon scale mail, so I ended up with a *+2 uncursed silver dragon scale mail*
that brought my AC down to -10. It saved my butt later on when I ran into a
bunch of winter wolf pups because it reflected their cold beams.
{{< figures/image name=wishing >}}
Later on in the mines, I stepped on a polymorph trap that transformed me into an
ice dragon. That transformation caused my dragon scale mail to fuse into my
body. When the transformation ended, I was left with simple dragon scales,
which were still silver, but no longer had the big defense bonus. Boo. :( I did
get to lay two eggs that hatched into baby ice dragons. Baby dragons are
ravenous and indiscrimate.
The baby dragons killed the Oracle. Whoops.
{{< figures/image name=oracle >}}
In the oracle level, I tried to dip my long sword into the fountains around the
Oracle, hoping to find Excalibur. Just a few turns before, I'd fought a
gelatinous cube that corroded my sword. I didn't notice at the time though, so
dipping went horribly wrong... Not only did my corroded long sword become
*thoroughly rusted*, it also eventually became cursed. Oddly enough, that sword
was still the best weapon I had, and I used it to the very end. I need to figure
out how to replace weapons that get degraded like that.
I solved Sokoban with some help from the Nethack wiki for the first time. The
puzzles are hard but I enjoyed thinking through them. The monsters in there,
especially in the upper levels are *hard*: multiple elementals, several packs of
winter wolf pups, yetis, apes, and a zruty. I got through the last level and
discovered a mimic blocking the hallway to the zoo. It killed me.
Near the end, I was testing amulets and put on an Amulet of Changing that caused
me to switch genders. Boo.
It's in my [logfile][logfile] now too.
[adeon]: https://www.youtube.com/watch?v=rIB0y_kwFuY
[logfile]: {{< ref "nethack" >}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View file

@ -0,0 +1,20 @@
---
title: "Week of Soup"
date: 2022-11-11T12:42:33-08:00
categories: ["Food"]
tags: ["Soup", "San Francisco", "Restaurants"]
---
{{< tess >}} and I were both sick this week and had a hankering for soup. We
ended up eating soup for lunch every day. (What can I say, we like soup.) All of
these places are excellent.
- Matzo Ball Soup from [Wise Sons][ws]
- Pozole and caldo de pollo from [La Espiga de Oro][edo]
- Ramen from [Coco's][cocos]
- Chicken Noodle Soup and dumplings from [Leleka][leleka]
[ws]: https://www.wisesonsdeli.com
[edo]: https://www.yelp.com/biz/la-espiga-de-oro-san-francisco
[cocos]: http://www.cocoramen.com
[leleka]: https://lelekasf.com

View file

@ -0,0 +1,17 @@
---
title: "Where Am I"
date: 2022-11-20T07:42:27-08:00
categories: "Tech"
tags: ["Twitter", "Me", "News"]
---
In the wake of Elon Musk taking control of Twitter, a lot of folks have decided
it's not as welcoming a place as it once was. In my circles, there's been a huge
movement of people to [Mastodon][m] and [cohost][c] mainly. I have accounts on
all of those places, though I haven't quite figured out where I'll land yet. If
you're interested in following me anywhere else on the internet, I made
[a handy list][where].
[m]: https://mastodon.social/
[c]: https://cohost.org
[where]: {{< ref "about/where-am-i" >}}

View file

@ -0,0 +1,4 @@
---
title: 2022
date: 2022-01-01
---

View file

@ -0,0 +1,4 @@
---
title: 2023
date: 2023-01-01
---

View file

@ -0,0 +1,17 @@
---
title: "Atom Feed Bug Fixes"
date: 2023-08-09T08:43:26-07:00
categories: ["Tech"]
tags: ["Erynwells.me", "Meta", "Atom"]
---
A kind reader pointed out to me that my Atom feed was incorrect. There were two
problems. First, I was specifying an incorrect URL in the feed's `<link
rel="self">` -- it was pointing to a nonexistant feed.xml file. Second, I was
omitting a `<link>` tag from the entries entirely.
Thunderbird didn't like this. With no `<link>` for an entry, it would show the
feed's `<link>` in it's UI. And that link left users at a 404 page.
I pushed a fix this morning. You might have to refresh or resubscribe to pick up
the changes.

View file

@ -0,0 +1,22 @@
---
title: "Chess"
date: 2023-11-20T14:58:56-08:00
categories: Chess
tags: ["Games", "Hobbies"]
---
I've been playing a lot of chess lately. {{< tess >}} and I have been watching
[Slow Horses][slow-horses] on Apple TV+, and there was a recent episode in which
a chess game between two characters is a key plot beat. That got me thinking
about playing again.
I learned chess as a kid. My dad taught me. I played in chess clubs in
elementary and middle school. I was really into it for a while!
I have a [Chess.com](chess.com) account now: [erynrwells][chess-com-profile].
I'm also on [lichess.org](lichess.org): I'm [erynrwells][lichess-profile] there too.
Send me a friend request or challenge? :)
[slow-horses]: https://tv.apple.com/us/show/slow-horses/umc.cmc.2szz3fdt71tl1ulnbp8utgq5o
[chess-com-profile]: https://www.chess.com/member/erynrwells
[lichess-profile]: https://lichess.org/@/erynrwells

View file

@ -0,0 +1,13 @@
---
title: "Guide to Computing"
date: 2023-09-23T10:24:35-07:00
categories: "Tech"
tags: ["Retro Computing", "Design"]
---
I really enjoyed looking through the images on [Docubyte's Guide to
Computing][link]. It depicts machines from the early days of modern computing --
think IBM mainframes, PDP-1's, and lots of midcentury modern design -- in a way
I found really intriguing.
[link]: https://www.docubyte.com/projects/guide-to-computing/

View file

@ -0,0 +1,38 @@
---
title: "Hello Chess Friend"
description: I started building a chess engine in Rust. Here it is.
date: 2023-12-29T08:29:00-08:00
series: chess-friend
categories: Tech
tags: [Programming, Chess]
---
I started [playing a lot of chess][chess-post] recently. As often happens with
me, it wasn't very long until I started wondering how I could Do Programming To
It.
I found the mostly excellent, occasionally vague and confusing [Chess
Programming Wiki][cpwiki] and have been using that as a guide. It helpfully says
this on it's [Getting Started][cpgs] page:
> The **very first step** to writing a chess engine is to write a complete, bug
> free board representation that knows every rule of chess.
As a software engineer, the "bug free" bit cracks me up.
My engine is called ChessFriend. It uses [bitboards][cpbb] for its board
representation. As of this post, I've managed to write a board representation
that allows me to place pieces of both colors on any square, and I'm hacking
away at the move generator. I've also written a small command line "board
explorer" utility that can interact with my board representation. Of course, it
has a pile of unit tests, helping me inch ever-so-slowly toward that blissful
bug-free state.
It's written in Rust. I've [_mostly_][rust-bc-toot] avoided fighting with the
borrow checker.
[chess-post]: {{< ref "chess" >}}
[cpwiki]: https://www.chessprogramming.org/Main_Page
[cpgs]: https://www.chessprogramming.org/Getting_Started
[cpbb]: https://www.chessprogramming.org/Bitboards
[rust-bc-toot]: https://mastodon.social/@erynofwales/111637122773195611

View file

@ -0,0 +1,36 @@
---
title: "Less Instagram, More Blog"
description: Resolving, yet again, to blog more and social media less.
date: 2023-12-27T08:56:44-07:00
categories: Meta
tags: [Writing, Resolutions, Habits]
---
I've been thinking the last few days about how to make use of my blog in 2024. I
made some vague noises in this general direction a few days ago in my [What
Should I Blog About?][what-to-blog-about] post too.
My vision since I started posting more here has been to use it as a place to
share all sorts of things: stuff I'm working on or thinking about; photos; and
stories from travel and life.
I often fall into a trap when I sit down to write something in which I feel like
I must first invent the Universe. The need to explain everything from first
principles seriously hampers my ability (and frankly, desire) to write anything.
I don't want to only post carefully thought out, highly edited and polished
pieces, though I certainly hope _some_ of my posts reach that bar. I hope to
also post quick notes and sketches of ideas. I've enjoyed reading some quicker
posts from {{< tess >}} and [Elaine][e] this past year, and I'd like to follow
their example.
{{< youtube zSgiXGELjbc >}}
I'm not setting myself a specific goal here. The idea is just "more" in a
certain general direction. I don't want to commit to a specific frequency or
quality. Instead, I'm hoping this post sets a foundation on which to build a
sustainable thinking-writing-sharing habit.
Thanks for coming along. :)
[what-to-blog-about]: {{< ref "what-to-blog-about" >}}
[e]: https://diplograph.net

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:562f6c157c43ef11ae55274b0bd1403c2cbb9a64b82443a2d9f4fb58b32606fd
size 148873

View file

@ -0,0 +1,10 @@
---
title: "The Long Way to a Small, Angry Planet by Becky Chambers"
slug: long-way-to-a-small-angry-planet-book
date: 2023-02-01T09:16:48-08:00
draft: true
categories: Books
tags: ["Science Fiction"]
series: 2023-books
---

View file

@ -0,0 +1,15 @@
---
title: "Mastodon Icon"
date: 2023-08-11T08:23:25-07:00
categories: ["Tech"]
tags: ["Meta", "Erynwells.me", "Web"]
---
I finally got around to replacing the Twitter icon in the site's header with a
link to my Mastodon page. It was surprisingly tricky because of how I styled and
layed out those icons. I was able to clean up the SVGs a little bit too.
These days I have [way too many social media accounts][where-to-find-me]. I'm
mostly on Mastodon and Instagram.
[where-to-find-me]: {{< ref "/about/where-am-i" >}}

View file

@ -0,0 +1,14 @@
---
title: "Nethack Illustrated Guide"
date: 2023-01-07T08:52:53-08:00
link: https://thinkmoult.com/nethack-illustrated-guide-mazes-of-menace.html
categories: Games
tags: [Nethack, Art, AI]
---
While browsing {{< r nethack >}}, I came across a [post][post] from someone sharing a [collection of AI-generated
images][guide] that illustrate the story arc of a game of Nethack. Between the images and the prose they added around
it, I thought they did a fantastic job of capturing the mood of the game.
[post]: https://www.reddit.com/r/nethack/comments/zx965y/nethack_an_illustrated_guide_to_the_mazes_of/
[guide]: https://thinkmoult.com/nethack-illustrated-guide-mazes-of-menace.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 KiB

View file

@ -0,0 +1,47 @@
---
title: "Netscape Meteors: Retrospective"
date: 2023-08-05T17:14:40-07:00
description: Someone shared my Netscape Meteors post on the Orange Website, causing it to be moderately viral for a few days. Heres an update on the web traffic my server received.
categories: ["Tech"]
tags:
- History
- Meta
- Netscape
- Web
- Web Browsers
---
Last week, I published a small blog post about trying to find the original
[Netscape "meteors"][meteors] loading animation. At some point that night,
someone posted it on the orange website, and ... it did some numbers.
As of today, five days later, my server has registered just over 200,000 page
accesses.
{{< figures/code >}}
```txt
% grep "GET /blog/2023/08/netscape-meteors/" \
/var/log/nginx/access.log | wc -l
200201
```
{{< /figures/code >}}
Bandwidth saw a bit of a spike too.
{{< figures/image name=bandwidth-2023-08-05.png shouldShowTitle=false >}}
To my knowledge this is the first time anything I've published on the internet
has been picked up by Hacker News. It's jarring to realize so many people have
visited my website in the last several days, reading this and other things I've
written, listening to music I've published, and looking through photos I've
posted. It's a little like having surprise house guests and realizing you
haven't tidied up in a little while.
I only took a brief look at the comments. I was pleased to see they were civil,
and mostly reminiscing about the days of Netscape and the early web. I had a few
people reach out to tell me they enjoyed my post too.
Thanks, y'all, for reading my little corner of the web, and for your kind
words.
[meteors]: {{< ref "blog/2023/netscape-meteors" >}}

View file

@ -0,0 +1,97 @@
---
title: "Netscape Meteors"
date: 2023-08-01T18:23:33-07:00
description: I went on a hunt to find the "Meteors" loading animation from Netscape back in the 90s, and wrote up my adventure.
resources:
- name: netscape60
title: Netscape Meteor Loading Animation
src: netscape-meteors.gif
- name: netscape-modified60
title: Modified Netscape Meteor Loading Animation, Small
src: netscape-meteors-modified-60.gif
- name: netscape-modified240
title: Modified Netscape Meteor Loading Animation, Large
src: netscape-meteors-modified-240.gif
- name: rectangular-pixels
title: Rectangular Pixels
src: rectangular-pixels.png
alt: "A zoomed in screenshot of an animation frame with pixel grid enabled,
showing rectangular pixels"
categories: Tech
tags: ["Netscape", "History", "Web Browsers", "Web"]
---
I went on a small journey the last couple days to find the original Netscape
Navigator "meteors" animation. This one has a special place in my head and
heart because it is so clearly connected to my memories of discovering the
web as a kid. Here it is in its original 60&times;60 px glory:
{{< figures/image name=netscape60 shouldShowTitle=false size=small >}}
I started out doing some web searches that turned up several versions. One was
promising but far too big: 400&times;400 px. Worse, after some shoddy resize
attempts, the "pixels" had become rectangular.
{{< figures/image name=rectangular-pixels shouldShowTitle=false size=small >}}
This would not do.
I continued searching, hoping to find the original animations. I found someone's
[mirror of Netscape 5.0 on Github][gh-netscape]. Then I found some [very old
versions of Mozilla][moz-netscape] on a Mozilla FTP server. Sadly, the
animations had been stripped out of these archives. :(
Frustrated with hitting several deadends, I complained to {{< tess >}} and
wondered aloud if anyone might have the original images stashed away somewhere.
She quipped that if anyone did, it would be Jamie Zawinski.
A little later, I posted about it on Mastodon.
<iframe
src="https://mastodon.social/@erynofwales/110817133916254596/embed"
class="mastodon-embed"
style="max-width: 100%; border: 0"
width="400"
allowfullscreen="allowfullscreen">
</iframe>
And wouldn't you know it, a friend tagged [`@jwz`][masto-jwz] asking if he had
it, and a few moments later I got a reply from [Jamie][jwz] himself.
<iframe
src="https://mastodon.social/@jwz/110817331045294426/embed"
class="mastodon-embed"
style="max-width: 100%; border: 0"
width="400"
allowfullscreen="allowfullscreen">
</iframe>
If you don't know, Jamie Zawinski is well-know for working on several important
software projects in the '90s. He worked on Netscape Navigator, built and
maintains [Xscreensaver][xscreensaver], and several other things. Nowadays, he
owns and runs [DNA Lounge][dna] in San Francisco.
There are a lot of neat bits of web browser history on the page he linked --
totally worth a quick look over -- but most important to the quest at hand, it
had that Netscape meteors loading animation.
The original one has some small artifacts on the left side of frame 10 that
render as red and orange pixels. These bothered me enough that I made a version
that replaces those pixels with ones that match the surrounding pixels. Here's
the modified 60&times;60 one and a bigger 240&times;240 px one, for good
measure:
{{< content-grid columns=2 >}}
{{< figures/image name="netscape-modified60" shouldShowTitle=false shouldResize=false size=small >}}
{{< figures/image name="netscape-modified240" shouldShowTitle=false shouldResize=false size=small >}}
{{< /content-grid >}}
<script src="https://mastodon.social/embed.js" async="async"></script>
[gh-netscape]: https://github.com/zii/netscape
[moz-netscape]: https://ftp.mozilla.org/pub/mozilla/source/
[masto-jwz]: https://mastodon.social/@jwz
[jwz]: https://www.jwz.org
[xscreensaver]: https://www.jwz.org/xscreensaver/
[dna]: https://www.jwz.org
[about-jwz]: https://www.jwz.org/doc/about-jwz.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 KiB

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:fa3b6749eb23bff608c4b7233746c6d0577c689786cc69d7354758959e56a9fc
size 159168

View file

@ -0,0 +1,32 @@
---
title: Once Upon a Time I Lived on Mars by Kate Greene
slug: once-upon-a-time-i-lived-on-mars-book
description: A brief book report.
date: 2023-02-20T09:16:48-08:00
date_finished: 2023-02-20T00:00:00-08:00
categories: Books
tags: [Memoirs, Space]
series: 2023-books
resources:
- name: cover
src: cover.jpeg
alt: "The cover of Once Upon a Time I Lived on Mars by Kate Greene, with a subtitle that reads 'Space, Exploration, and Life on Earth'"
title:
---
{{< figures/image name=cover >}}
{{< tess >}} got me this book for Christmas 2022 on a whim at a local bookshop. It's a series of essays -- reflections
and examinations -- of the author's time parcipating in one of NASA's Mars analog missions on Mauna Kea, Hawai'i. She is
a lesbian and, as luck would have it, lived in the same part of town that Tess and I do! It was fun to read little
anecdotes about her and her (ex) wife stopping in at shops that we frequent ourselves.
I enjoyed reading about her experiences working with NASA in the context of an analog mission. It sounds like they went
above and beyond to make the mission as close to a real Mars experience as possible, despite being firmly on Earth.
Communication with mission control was artificially delayed 20 minutes, as it would be on Mars. Going outside required
putting on bulky spacesuits. And participants were isolated together for six months.
She also has several essays in which she reflected on the politics and cost of spaceflight, and what it means for humans
to explore and exist in space.
Support a local bookshop and get it from [Folio Books](https://www.foliosf.com/book/9781250796660). 🙂

View file

@ -0,0 +1,17 @@
---
title: "Pajaro Dunes"
date: 2023-05-30T08:31:34-07:00
tags: [Travel, Beaches, Tess, EJ, Vacations]
---
{{< tess >}}, EJ, and I took a weekend trip down the coast over Memorial Day
weekend this year to stay in a beachside condo in Pajaro Dunes, just west of
Watsonville. We enjoyed hanging out on the beach, playing music and games,
building [Kiwi Crates][kiwi], and just generally being together. I took a couple
photos too. :)
{{< photo "2023/pajaro-dunes" >}}
{{< photo "2023/sunset-over-pajaro-dunes" >}}
[kiwi]: https://www.kiwico.com

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ded6e76e0903c82d1db25e8df3f5b68ac72bd07774648ee2dab2c68c0ddbc77f
size 2616121

View file

@ -0,0 +1,56 @@
---
title: "Tahoe Ski Trip"
date: 2023-01-30T12:40:15-08:00
draft: true
categories: Travel
tags: [Friends, Snowboarding, Snowshoeing]
resources:
- name: cabin
src: cabin.jpg
title:
params:
alt: A cozy cabin living room, with wood panel walls, lots of fuzzy, furry pillows, and a high steeply pitched roof. A fireplace is off to the right, and a large couch occupies the middle of the room. The windows fill the wall, floor to ceiling. Outside, you can see many tall pine trees and snow falling.
- name: snowshoeing
src: snowshoeing.jpg
title:
params:
alt: "A selfie of three people: me and two friends, wearing cold weather gear and standing in the snow. A well-traveled path in the snow meanders through the snow-covered trees."
---
This weekend I took a trip to the north side of Lake Tahoe with a group of coworkers and friends to ski and snowboard,
and enjoy the mountains and each other's company. We stayed in an AirBnb in Truckee, and spent a couple days up at
Northstar.
{{< figures/image name=cabin >}}
We all spent Friday on the mountain. I took an all-day group snowboarding lesson, while the rest did runs all over the
moutain. My lesson was a small group, just five of us, and it was really great. We were all newbies, and very
encouraging of each other. Our instructor pushed us quickly through standing and short glides on the board, to longer J
turns, and traversing the bunny hill. Before lunch, we were doing the Big Easy. I felt like I was starting to get the
hang of it, and the instructor agreed. After lunch, we went up the Arrow Express lift and took Lumberjack all the way
down. It was harrowing--I have bad memories of the first drop from the last time I was at Northstart--but we all made
it! By the end, I was feeling much more confident on the board, though I was also pretty beat up from several rough
falls throughout the day.
We all went to bed pretty sore that night, but the next day we got up and did it all again. There were a _lot_ more
people on the mountain on Saturday, so wait times for lifts were longer. Despite that I got a bunch of good runs in,
including one from the top of the moutain with the rest of my group! I ended the day with two runs from the top of the
moutain, and a sore tail bone, but with much more confidence in my ability to turn and stop on a board. 🤙🏻
The third day was a rest day for me. While some went back up the mountain for another day of skiing, a few others of us
decided to go on a snowshoe hike. This was my first time with snowshoes. They're a bit awkward, but pretty easy to get
the hang of. We took a loop around a small lake near Donner Lake. I always enjoy the peace that being out in nature
brings, and it was great to catch up with two of my friends in a smaller group.
{{< figures/image name=snowshoeing >}}
At the end of the day, we scrambled to amass a stockpile of snowballs for an ambush! The guys in our group had decided
to go skiing a third day, and were on their way back. When they pulled into the driveway, we attacked! Honestly, it
wasn't anywhere near a fair fight. 😅 They fought back though, survived the onslaught, and we all had a great time.
Spending quality time with friends, going on trips like this, means a lot to me. I've gotten to do trips with friends
like this a few times over the last couple years, but it's been a bit since I went with _this_ group. I had so much fun
being up in the moutains, hanging out, playing games, and having long conversations. We're such a good group, and I'm
grateful to have all of them in my life.
Thanks y'all. <3

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:00a65714e64f92a4ae67d2d21c8be81341a433f9eabb23c032f835d8cc6a0580
size 3079324

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6d82f2760711b2c4b7148bf22a141002a937890b8abb8568b4fd3746d8edf0d0
size 55408

View file

@ -0,0 +1,26 @@
---
title: "The Storyteller by Dave Grohl"
slug: the-storyteller-book
date: 2023-01-31T09:17:09-08:00
date_finished: 2023-01-31T09:17:09-08:00
series: 2023-books
categories: Books
tags: [Memoirs]
resources:
- name: cover
src: cover.jpg
alt: "The cover of The Storyteller by Dave Grohl: a profile photo of Dave Grohl with the title of the book overlaid."
title:
---
{{< figures/image name=cover >}}
I checked out [Dave Grohl's new memoir](https://www.davegrohlstoryteller.com) from the San Francisco Public Library as
an audiobook after a friend recommended it to me. Broadly, it's a series of anecdotes from his life, many of which
include famous celebrities and musicians.
Dave seems like a really genuine person. Throughout the book he expresses his gratitude for the people who've supported
him along the way. He's been through many challenging experiences too, and reflects on them with a positive attitude. I
enjoyed his humor and humility, and the pearls of wisdom he'd earned from those experiences.
[SFPL](https://sfpl.bibliocommons.com/v2/record/S93C4875170)

View file

@ -0,0 +1,22 @@
---
title: Trip to Japan
date: 2023-04-14T21:40:21+09:00
categories: Travel
tags:
- Travel
- japan
---
At the beginning of April, {{< tess >}} and I took a trip to Japan for two
weeks. She had a work meeting to attend in Tōkyō, and we were lucky to be able
to extend the trip to take some vacation before her meeting.
This was my first trip to Japan. I had been wanting to travel there since I was
a kid playing Pokémon Red on my OG Game Boy. To say I was excited is a bit of an
understatement.
You can read all about our trip [on my travel log page][series-page]. Tess also
wrote about it [on her website][tess-post].
[series-page]: {{< ref "/series/2023-japan" >}}
[tess-post]: https://tess.oconnor.cx/2023/04/japan

View file

@ -0,0 +1,13 @@
---
title: What Should I Blog About?
date: 2023-12-20T08:06:34-08:00
link: https://css-irl.info/what-to-blog-about-when-you-dont-know-what-to-blog-about/
categories: Tech
tags: [Writing]
---
I came across this handy list of [things to blog about when you don't know what
to blog about][link]. As someone who often doesn't know what to blog about, it's
nice to have a list of ideas for what to blog about.
[link]: https://css-irl.info/what-to-blog-about-when-you-dont-know-what-to-blog-about/

View file

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7bc98cce772e0c075daed5a6dd9b1c18e6fd19e94ac68197893fd14cb58cf790
size 83946

View file

@ -0,0 +1,27 @@
---
title: "Yerba Buena by Nina LaCour"
date: 2023-11-23T09:50:06-07:00
series: 2023-books
categories: Books
tags: [Romance, Lesbians, Queerness]
resources:
- name: cover
src: cover.jpg
title:
params:
alt: An orange book cover with green leafy sprigs around the edges. Profiles of two women, overlapping and facing opposite directions. "Yerba Buena a novel" is written across the top half.
---
I thought this book was a lesbian romance -- and it is -- but it's so much more
too. It's the story of two women and the difficult pasts they emerge out of. I
really enjoyed how LaCour wove together their processing of that trauma with
growing into young women, making questionable choices, finding themselves, and
ultimately each other. It's heavy at times, but also beautiful. I really enjoyed
it. Thank you, {{< tess >}}, for the gift. ❤️
Get it at [Folio][folio] in San Francisco, or on [Bookshop.org][bookshop].
{{< figures/image name=cover class=content-width >}}
[folio]: https://www.foliosf.com/book/9781250810519
[bookshop]: https://bookshop.org/p/books/yerba-buena-nina-lacour/18721506?ean=9781250810519

View file

@ -0,0 +1,28 @@
---
title: "You Deserve a Tech Union by Ethan Marcotte"
date: 2023-12-16T08:19:41-08:00
draft: true
series: 2023-books
categories: Books
tags: [Unions, Tech]
---
Ethan's book came out in August 2023, and I've been eager to read it since he
announced it. Unionization has been a hot topic in the US over the last several
years. I've rooted for workers at Amazon, Google, Starbucks, and Apple to form
unions and advocate for their rights vis á vis their employers. I think that
work is so important.
This book provides an overview of the history of unions in the US, and in the US
tech industry, plus some helpful thoughts on how to form unions in your
workplace.
I found his arguments about why unions are important, even in an industrial
sector considered to be rather plush compared to many others. Many people think
of unions as organizations that advocate for _more_ privileges and protections
for workers. However, at least as important as that work, they also ensure that
workers retain the privileges they already have.
Get it from [A Book Apart][aba].
[aba]: https://abookapart.com/products/you-deserve-a-tech-union

View file

@ -0,0 +1,4 @@
---
title: 2024
date: 2024-01-01
---

Some files were not shown because too many files have changed in this diff Show more