This is a classic case of Ask Culture meets Guess Culture.
In some families, you grow up with the expectation that it's OK to ask for anything at all, but you gotta realize you might get no for an answer. This is Ask Culture.
In Guess Culture, you avoid putting a request into words unless you're pretty sure the answer will be yes. Guess Culture depends on a tight net of shared expectations. A key skill is putting out delicate feelers. If you do this with enough subtlety, you won't even have to make the request directly; you'll get an offer. Even then, the offer may be genuine or pro forma; it takes yet more skill and delicacy to discern whether you should accept.
In my view, ask culture is a fundamental value of the web. It’s really the only way something as big as the web can possibly work. Some unfortunate government interposition aside, the web connects the entire world. I can’t guess-culture my way to harmony with people that I don’t have a deep understanding of or extremely frequent contact with, but I can ask-culture with them on the web.
The three paragrahps I quoted above are the most widely cited, but there is more to the comment:
All kinds of problems spring up around the edges. If you're a Guess Culture person -- and you obviously are -- then unwelcome requests from Ask Culture people seem presumptuous and out of line, and you're likely to feel angry, uncomfortable, and manipulated.
If you're an Ask Culture person, Guess Culture behavior can seem incomprehensible, inconsistent, and rife with passive aggression.
Obviously she's an Ask and you're a Guess. (I'm a Guess too. Let me tell you, it's great for, say, reading nuanced and subtle novels; not so great for, say, dating and getting raises.)
Thing is, Guess behaviors only work among a subset of other Guess people -- ones who share a fairly specific set of expectations and signalling techniques. The farther you get from your own family and friends and subculture, the more you'll have to embrace Ask behavior. Otherwise you'll spend your life in a cloud of mild outrage at (pace Moomin fans) the Cluelessness of Everyone.
As you read through the responses to this question, you can easily see who the Guess and the Ask commenters are. It's an interesting exercise
Ibid.
One thing I love about the comment is the humility inherent in naming your own attributes without judgement. It’s the most natural thing in the world to notice behavior we don’t like, realize it’s not how we would act, and label it as wrong (and perhaps disgusting). The last paragraph of the comment notes that there are many examples of this in the original thread! But the commenter doesn’t do that — she assertively labels herself, and identifies some benefits of the opposite end of the spectrum.
As she notes, an expansive network necessitates ask culture; what is the web if not an expansive network?
This informs how I want my own creations on the web to be available. I want the public to be able to
This post isn’t permission for those things, because I don’t want to be in the business of approving and denying what I make public. And because permission implies responsibility, and not only do I not want responsibility, I don’t want to have to disclaim it.
Write a comment on the original post.
I’ve been quietly adding books to my website as a parallel taxonomy1. The Play Hades and read the Iliad post references the most books so far, but there are a few others I’ve added, with more to come.
I started out doing this by hand, but of course its impossible to countenance spending dozens of minutes on a rote task after considering the opportunity to spend dozens of hours on an over-engineered “shortcut”.
tl;dr: I wrote bibliographer
,
which pulls books in my Audible and Kindle libraries and saves the metadata where Hugo can find it.
Before we dive into the technical stuff, I’m particularly excited about being able to link to some favorites. Like all posts in the books section, none of these pages will be all that interesting on their own; this is why I don’t expect anyone to follow the section RSS feed. But now I can tag longer blog posts by books when I’m inspired by their ideas.
My intentions of an enjoyable time sink were nearly routed: I tried ChatGPT o1, and it gave me almost 1000 lines of almost working code in one shot. Even with the “almosts”, I was really impressed.
All was not lost, however. It turned out my first instructions took a lot more planning that I normally give to LLM interactions. I tried out the suggestions in o1 isn’t a chat model and it paid off very well. I think it wasn’t quite as fun as jumping right in to write code, but (all jokes aside) the time efficiency was very good, and it drove home the value of planning. You can see my original plan document. I wrote that, including stub functions, before asking ChatGPT anything. I only used o1 is it was available to me in my $20/mo ChatGPT Plus plan; I never used the $200/mo ChatGPT Pro.
I’d love to share the full transcript, but the conversation is large enough that the fucking website doesn’t work. (Isn’t it going to be just tragic if OpenAI et al manage to obsolete the job of programming a computer but every consumer product is broken just as much as it is today?)
Eventually it got big enough that o1 was forgetting things or introducing bugs, and I took a more active hand in writing the code and asked smaller more scoped questions of cheaper models.
bibliographer
with HugoThe GitHub repo has instructions for use, and an example snippet to include in a Hugo theme.
It caches API call results inside assets/bibliographer/apicache/*
,
and creates mapping files under assets/bibliographer/usermaps/*
that you can edit if the heuristics that generate a slug,
find the ISBN,
find the cover,
etc don’t return good results.
All bibliographer
does is write data filse and empty index.md
files;
it’s up to your theme to render them how you like,
and up to you to write content in the book posts if you want to.
I’d like to add author and series cross linking for the site as well, so that someone looking at a book page based on a recommendation can easily find related books without me having to write prose explaining the relation.
I haven’t gotten around to this yet, but it’s on the list for when I have extra tinkering time.
I was surprised at how difficult it was to get data out of Amazon.
There is no official support for exporting a library from Kindle or Audible in any format whatsoever.
Goodreads is owned by Amazon and is privileged with access to a private Kindle API,
but it’s not accessible to users.
(Oddly, Audible, also owned by Amazon, is not supported by Goodreads at all.)
There is also, of course, no public Goodreads API.
(I haven’t implemented Goodreads support in bibliograhper
,
but I would be interested in doing so if there were some way to get the library data
and anyone else wanted the feature.)
Amazon uses an internal product ID called an ASIN. Unsurprisingly, it doesn’t publicize any database it might have of ASIN to ISBN, but it also doesn’t have a public database of ISBNs to ASINs. The Amazon Product Advertising API is not public; if they don’t deign to give you access, they suggest clicking around on their website to generate associate links like an animal.
What do we do instead? Well
audible
package is amazing!
It has reverse engineered the Audible API and was super easy to use.Feature requests and bug reports are welcome. If you end up using it for something, I’d love to hear about it!
… kind of. It is a taxonomy in the dictionary sense, but not in the Hugo sense. In Hugo, the book pages are just regular pages, and my theme finds parameters which cross link between book pages and blog post pages. ↩︎
Write a comment on the original post.
Inspired by The quotes on my wall by Linus, I built a way to display things that I want to draw my attention over time.
I add new entries as I come across them when I’m reading or journaling, including things that inspire me like Oxide’s Mission or this quote from _why, or things that challenge me, like Finish your projects or Creativity is a byproduct of work. Often they are sparked by quotes I’ve read from other people, the way Linus’s backgrounds are, but sometimes they’re just things I want to improve in myself. I’ve found it really useful to be able to highlight a single sentence from a bigger quote to really draw my eye, for example in Having a defensible opinion takes work
As I write this, some of my goals for 2025 are in active rotation.
They’re designed to be displayed as desktop backgrounds. Here’s an example with the focus So create, displayed in an iframe to show what it would look like on a desktop. (Warning: on iOS, attempting to zoom the page while this iframe is in view can cause the web page to crash. If you want to take a closer look at the focus, tap to view it directly.)
All these are in my focalarium, a latin-esque word that I made up patterned after “reliquarium”. That page lists all the active foci, which is sort of like a /now page for things I’m thinking about, as well as a complete list of every focus I’ve ever added.
It also has a special Cycle page, which loops through each active focus, displaying it for 15 minutes at a time. I point Plash at this page, and it updates my desktop background for me.
A few notes about how it’s implemented
I defined a new Hugo media type text/html+focus
and output HtmlFocus
in my config file:
mediaTypes:
# ...
text/html+focus:
suffixes: ["focus.html"]
outputFormats:
# ...
HtmlFocus:
mediatype: text/html+focus
# Output should be 'index.focus.html'
suffix: focus.html
isPlainText: false
isHTML: true
rel: alternate
permalinkable: false
And configured the focalarium
section to use that output in the section frontmatter:
cascade:
outputs:
- HTML
- HtmlFocus
And added an layout template in layouts/focalarium/index.focus.html
to display the focus itself.
This is a very stripped down page,
which pulls in only the <head>
template from my main site.
<!DOCTYPE html>
<html lang="{{ .Site.LanguageCode }}">
<head>
{{- partial "head.html" . }}
<style id="page-focus-styles">{{- with .Page.Resources.Get "focus.css" }}{{ .Content | safeCSS }}{{ end }}</style>
<script id="page-focus-script" type="text/javascript">{{- with .Resources.Get "focus.js" }}{{ .Content }}{{ end }}</script>
</head>
<body>
<main id="content" class="focus-content">
{{ .Content }}
</main>
<div class="focus-explanation">
<p><a href='{{ with site.GetPage "/focalarium" }}{{ .Permalink }}{{ end }}'>Focus</a></p>
</div>
</body>
</html>
Now when the site is built, each focus generates a regular index.html
and a special index.focus.html
.
The index.html
is the focus landing page
that describes what the focus is for any confused humans that stumble across it and shows a preview,
and the index.focus.html
is the stripped down page that displays on the desktop.
The Cycle page uses JavaScript to retrieve an index.focus.html
and replaces the whole page body with its contents every interval.
The default interval is 15 minutes,
and you can adjust the interval with a query string like ?intervalMin=X
.
Point a browser, or Plash, at this page and it’ll show a new focus every so often.
The JavaScript for this is inline;
you can just curl
the Cycle page to see it.
Write a comment on the original post.