diff options
| author | Joe Carstairs <jcarstairs@scottlogic.com> | 2025-01-28 18:06:53 +0000 |
|---|---|---|
| committer | Joe Carstairs <jcarstairs@scottlogic.com> | 2025-01-28 18:06:53 +0000 |
| commit | ed52216fb8df3c5c6ed1561ed59699a67a950187 (patch) | |
| tree | 643debcd204e511e0842a68f6946a97a26f51814 /website | |
| parent | 17aa658fb8b86a5caf3d3608f7871e43d09be55a (diff) | |
| parent | c9f6c53a0d9617e3d3a6862b3998322c2a1470c8 (diff) | |
Merge branch 'main' of https://github.com/joeacarstairs/personal-website
Diffstat (limited to 'website')
16 files changed, 394 insertions, 25 deletions
diff --git a/website/public/css/base.css b/website/public/css/base.css index d4c070a..fd5bbf2 100644 --- a/website/public/css/base.css +++ b/website/public/css/base.css @@ -2,6 +2,7 @@ :root { --colour-primary-10: #060300; + --colour-primary-15: #150800; --colour-primary-20: #1f1400; --colour-primary-30: #3c2b00; --colour-primary-40: #5c4300; @@ -26,19 +27,22 @@ --colour-primary-fg: var(--colour-primary-90); --colour-primary-fg-accent: var(--colour-primary-80); --colour-primary-bg: var(--colour-primary-10); + --colour-code-fg: var(--colour-primary-90); + --colour-code-bg: var(--colour-primary-15); --colour-hyperlink: var(--colour-hyperlink-80); --font-size-sm: 1rem; - --font-size-base: 1.25rem; - --font-size-md: 1.75rem; - --font-size-lg: 2.5rem; - --font-size-xl: 3.5rem; + --font-size-base: 1.125rem; + --font-size-md: 1.5rem; + --font-size-lg: 2rem; + --font-size-xl: 3rem; --spacing-block-xs: 0.5rem; --spacing-block-sm: 1.75rem; --spacing-block-md: 2.5rem; --spacing-block-lg: 3.5rem; --spacing-block-xl: 5rem; + --spacing-inline-xs: 0.25rem; --spacing-inline-sm: 0.5rem; --spacing-inline-md: 1.5rem; --spacing-inline-lg: 3rem; @@ -92,9 +96,10 @@ body { img { margin-inline: auto; + height: auto; } -@media (min-width: 36rem) { +@media (min-width: 48rem) { body { display: grid; grid-template-columns: @@ -108,7 +113,7 @@ img { --body-margin-inline-end: 6rem; --grid-margin-inline: 6rem; - --grid-total-width: 36rem; + --grid-total-width: 48rem; --grid-max-content-width: calc( var(--grid-total-width) - var(--body-margin-inline-start) @@ -133,12 +138,6 @@ img { } } -@media (min-width: 48rem) { - body { - --grid-total-width: 48rem; - } -} - /** Headings */ h1 { @@ -262,3 +261,28 @@ blockquote :is(i, em) { .small-caps { font-variant: small-caps; } + +/** Pre-formatted blocks */ +pre { + border: 2px solid var(--colour-primary-fg); + border-radius: 2px; + background-color: var(--colour-code-bg) !important; + margin-block-start: var(--spacing-block-sm); + padding-inline: var(--spacing-inline-sm); + padding-block: var(--spacing-block-xs); +} + +/** Code blocks */ +code { + border: 2px solid var(--colour-primary-fg); + border-radius: 2px; + padding-inline: var(--spacing-inline-xs); + color: var(--colour-code-fg); + background-color: var(--colour-code-bg); + font-size: var(--font-size-sm); +} +pre code { + border: none; + border-radius: none; + padding: none; +} diff --git a/website/src/components/BlogFeed.astro b/website/src/components/BlogFeed.astro index f1559b9..5d5f727 100644 --- a/website/src/components/BlogFeed.astro +++ b/website/src/components/BlogFeed.astro @@ -64,7 +64,7 @@ const canonicalBlogUrl = new URL('blog', Astro.site) <ul> { posts.filter(matchesYear(year)).sort(sortByPubDateDescending).map(post => ( <li class="h-entry"> - <a class="u-url p-name" href={`/blog/${post.slug}`}>{post.data.title}</a>. + <a class="u-url p-name" href={`/blog/${post.id}`}>{post.data.title}</a>. <Fragment set:html={post.data.description} /> Added: <FormattedDate date={post.data.pubDate} /> </li> diff --git a/website/src/components/Me.astro b/website/src/components/Me.astro index fc21bbf..4d26ace 100644 --- a/website/src/components/Me.astro +++ b/website/src/components/Me.astro @@ -45,6 +45,7 @@ <a href="https://www.facebook.com/joe.carstairs.5" rel="me">Facebook</a>, <a href="https://mastodon.social/@joe_carstairs" rel="me">Mastodon</a>, <a href="https://www.linkedin.com/in/joe-carstairs-0aa936277" rel="me">LinkedIn</a>, + <a href="https://bsky.app/profile/joeacarstairs.bsky.social" rel="me">BlueSky</a>, or <a href="https://github.com/joeacarstairs" rel="me">GitHub</a>. </small> </p> diff --git a/website/src/content/config.ts b/website/src/content.config.ts index dfdf403..5436030 100644 --- a/website/src/content/config.ts +++ b/website/src/content.config.ts @@ -1,8 +1,9 @@ +import { glob } from 'astro/loaders'; import { defineCollection, z } from 'astro:content'; const blog = defineCollection({ - type: 'content', - schema: z.object({ + loader: glob({ pattern: '**/*.(md|mdx|html)', base: './src/content/blog' }), + schema: z.object({ title: z.string(), hidden: z.optional(z.boolean()), description: z.string(), diff --git a/website/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md b/website/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md index dec6bf5..e81ca44 100644 --- a/website/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md +++ b/website/src/content/blog/2024/01/29/euhwc_toast_to_the_lasses_2024.md @@ -91,7 +91,7 @@ She uses what her Maker has endowed her<br> with: her recorder skills are off the charts;<br> youse think I’m joking, but I wouldn’t doubt her!<br> This lass of the land of the Rot-Gold-Schwarz<br> -will soon depart, though long we might beseech ya<br> +will soon depart, though long we might beseech you<br> to stay. Of course, you’ll break all of our hearts,<br> but mine most of all. Any time, Felicia,<br> Creag Meagaidh calls, I know routes up the rear<br> diff --git a/website/src/src/content/blog/2024/04/10/tracking_pixels.md b/website/src/content/blog/2024/10/tracking_pixels.md index cb2e965..cb2e965 100644 --- a/website/src/src/content/blog/2024/04/10/tracking_pixels.md +++ b/website/src/content/blog/2024/10/tracking_pixels.md diff --git a/website/src/content/blog/2025/01/19/my_feed_and_reading_list.md b/website/src/content/blog/2025/01/19/my_feed_and_reading_list.md new file mode 100644 index 0000000..c11dd85 --- /dev/null +++ b/website/src/content/blog/2025/01/19/my_feed_and_reading_list.md @@ -0,0 +1,193 @@ +--- +title: How I read things on the Internet now (no, of course I don't leave the terminal!) +description: >- + I've been sprucing up how I follow what's happening on the Internet. I can + now read all the things I want to read pretty efficiently, and enjoy doing + it, which is exciting. +pubDate: 2025-01-19 +--- + +## The problem + +I like to read things on the Internet sometimes. Or listen to things. Or watch +things. + +Some interesting people write blog posts. Some beautiful people make music. Some +silly people make comedy sketches. Sometimes my friends are sharing stuff with +their friends, which means me (WIP on that front: I'll get back to that). + +I want to know about it. I want to read interesting things that will educate +me. I want to hear beautiful music. I want to hear about what my friends are up +to. + +I can't read everything as it comes in, it's too much: I'll need to sift a lot +of it out quickly. I'll need to sift through it regularly to stay on top of it: +like, several times a week, if not daily. And sometimes, while I'm doing my +daily sifting, I'll find something I really want to read, but I haven't got +time right now: I'll save this for the weekend. + +For a while, I've been hosting [CommaFeed][commafeed] on [PikaPods][pikapods]. +This has been OK ([OMG, RSS is cool][rss]), but the interface is just clunky +enough to make it a chore to use. That means I don't sift through stuff +regularly, and that means my feed piles hundreds of unread posts high. + +It also hasn't been any good for distinguishing between stuff I don't want to +read *ever*, and stuff I don't want to read *right now* but will get round to +later. I could in theory use the bookmarking feature built-in to my browser, +but removing things after I've read them is too clunky, so I don't do it. + +## The solution + +Every morning, I open my terminal and run [newsboat][newsboat]. + + + +I know the unread count is pretty fresh, because I've set up a systemd service +to run newsboat at startup to fetch the feeds. + +I press `l` twice to open a post. Then I press `n` to navigate to the next +unread post until I run out of unread posts. + + + +If I encounter something I want to read later, but don't have time right now, I +press `b`, which runs a home-made bookmarking script. Here it is: + +```bash +### readlater.sh ### + +# newsboat passes a few arguments: +# the first one is the post URL +url="$1" + +# I turn the URL into a suitable filename +filename=$( \ + echo $url | \ + sed "s/.*:\/\///" | \ + sed "s/\//./g" | \ + sed "s/\.html\$//g" \ +) +filename="$filename".html + +# If I've already got this in my reading list, +# I don't add it again +if [[ -a "$HOME/readlist/unread/$filename" ]] +then + exit 0 +fi + +# Otherwise, I download the post with curl +# and pipe it to a file in my reading list +# folder, ~/readlist/unread +curl "$url" > "$HOME/readlist/unread/$filename" +``` + +I can also run this script manually and pass it a URL of my choice at any time, +say, if I find an interesting article while browsing the Web. + +When I want to read from my reading list, I run `readnow.sh`, which simply +opens my reading list folder, `~/readlist/unread`, in my terminal file browser +of choice: namely, [ranger][ranger]. + + + +Although ranger has a preview, I'll typically open the file up in my terminal +web browser of choice, which is [w3m][w3m] (plus a couple of custom +key-bindings). I've configured this to be my preferred web browser in ranger by +shifting it to the top of the list of HTML browsers in +`~/.config/ranger/rifle.conf`. + +```conf +### ~/.config/ranger/rifle.conf ### + +... + +ext x?html?, has w3m, terminal = w3m "$@" +ext x?html?, ... + +... +``` + +Having configured my default web browser in my ranger config, all +I need to do is press `l`. + + + +No ads, no cookie popups, no giant banner images taking 2 seconds to load and +shifting the content all over the place: just the text I want to read. Isn't it +beautiful? + +Once I'm finished reading the post, I'll press `q` to quit w3m and return to +ranger. Assuming I don't need to read it again, I'll press `dm` to move the +post to `~/readlist/read` - my way of marking a post as 'read'. + +I've done this by writing a super simple script, `markread.sh`: + +```bash +### markread.sh ### + +filename="$(basename $1)" + +if [[ -a "$HOME/readlist/unread/$filename" ]] +then + mv "$HOME/readlist/unread/$filename" "$HOME/readlist/read/$filename" + echo "Marked $filename as read." +else + echo "I couldn't find a file in ~/readlist/unread with the name: $filename" +fi +``` + +...and hooking it onto the custom keybinding, `dm`, in ranger: + +```conf +### ~/.config/ranger/rc.conf ### + +... + +# map `dm` to run markread.sh in the shell, providing the active filename +# as the first and only argument +map dm shell markread.sh %f + +... +``` + +## The result + +I can now keep up to date, and I enjoy doing it. + +I get not everyone likes to live in the terminal. I think the key takeaways +are: + +- Make it really easy to sift through new posts +- When you sift, sift through every post, and for each one, either read it + straight away, or add it to your reading list +- Sift daily +- Make it really easy to add things to your reading list +- Make it really easy to browse, read things, and mark things read in your + reading list +- Set aside time to catch up on your reading list +- Make the whole thing joyful (both because joy is good, and because you won't + do it otherwise) + +## Next steps + +I still haven't really figured out social media. I'd like to stay up to date +with what my friends are doing, especially the ones I don't see very often. If +my friends are posting stuff on the Internet, I'd love to see it. + +I still need to know: + +- Are my friends posting stuff on the Internet? +- If so, where? +- What's the best way of subscribing to their posts - even if they live on + different websites and in different formats? +- What's the best way of sending and receiving comments/replies/reactions? + +TBC. Answers on a postcard please. + +[commafeed]: https://www.commafeed.com +[pikapods]: https://www.pikapods.com +[newsboat]: https://newsboat.org +[ranger]: https://ranger.github.io +[rss]: /blog/2024/05/02/no_more_youtube +[w3m]: https://w3m.sourceforge.net diff --git a/website/src/content/blog/2025/01/19/newsboat-post.webp b/website/src/content/blog/2025/01/19/newsboat-post.webp Binary files differnew file mode 100644 index 0000000..3d34afc --- /dev/null +++ b/website/src/content/blog/2025/01/19/newsboat-post.webp diff --git a/website/src/content/blog/2025/01/19/newsboat.webp b/website/src/content/blog/2025/01/19/newsboat.webp Binary files differnew file mode 100644 index 0000000..b6929cc --- /dev/null +++ b/website/src/content/blog/2025/01/19/newsboat.webp diff --git a/website/src/content/blog/2025/01/19/ranger.webp b/website/src/content/blog/2025/01/19/ranger.webp Binary files differnew file mode 100644 index 0000000..f325e56 --- /dev/null +++ b/website/src/content/blog/2025/01/19/ranger.webp diff --git a/website/src/content/blog/2025/01/19/w3m.webp b/website/src/content/blog/2025/01/19/w3m.webp Binary files differnew file mode 100644 index 0000000..0548a47 --- /dev/null +++ b/website/src/content/blog/2025/01/19/w3m.webp diff --git a/website/src/content/blog/2025/01/24/science_and_philosophy.md b/website/src/content/blog/2025/01/24/science_and_philosophy.md new file mode 100644 index 0000000..e906062 --- /dev/null +++ b/website/src/content/blog/2025/01/24/science_and_philosophy.md @@ -0,0 +1,139 @@ +--- +title: Why scientists need philosophers +description: This is a practice essay, OK? Don't shoot me if it's no good. +pubDate: 2025-01-24 +--- + +I've recently been working at a +[Philosophy of Science MOOC]([phil-sci-coursera]) on Coursera, the online +courses website. Later on, they set you an exercise to write a short essay +addressing how philosophy can contribute to science. + +So this is my punt. Life is too short to revise or, hell, even research this, so +don't take any of this as my settled opinion or as my best work. Whatever. With +that caveat in mind, it might still be entertaining at least, or maybe even +spark some thoughts. + +--- + +Walk into a particular room in the Science Museum in Kensington, and you will +find yourself enveloped in a cavern of ironmongery and miscellanea. The shelves +droop under the weight of bolts, files, screws, bits, grinders, saws, +protractors, clamps and pins. The inventory scrolls endlessly past you, voices +reciting the lists of trinkets like an incantation. + +This is the workshop of James Watt, meticulously reconstructed from the +original as it was left in his home in Birmingham after his death. This +entrancing space invites you to imagine a tireless creative, endlessly +tinkering away at his next contraption. + +And yet for all that - and for all his immense valorisation as the lynchpin of +Britain's industrial revolution - Watt was reluctant to think of himself as the +engineer everyone else loved. He aspired to be remembered not as an engineer +but as a scientist. + +To understand why James Watt, one of the most admired engineers who ever lived, +wished he were famed as a scientist instead, is to understand something +essential about modern Western thought. + +In Watt's lifetime, scientists increasingly became the elite of society. In the +nineteenth and twentieth century, this trend only gathered pace. We constructed +our modern public health infrastructure on the advice of pathologists and made +medicine scientific. We funded scientific expeditions to map the world, even to +its remotest corners (in part to help us conquer it). We adopted radical new +economic policies in response to scientific economic theories. We built vast +infrastructure networks to communicate waves of invisible energy discovered by +pioneering physicists, and built nuclear plants to generate more of the stuff +by means of nuclear science. We even designed social programmes on the basis of +scientific anthropology. By the end of the twentieth century, scientists were +our prophets, priests and kings. Or so we thought. + +In the 1990s, at the so-called 'end of history', it was assumed that there +would be no more need for social upheaval. Humanity had arrived at the ideal +system of social organisation. And among other ideologies - secularism, +libertarianism, democracy - an essential part of the package is that science +was our ultimate and incontestible way of securing knowledge about the world. + +Yet now, that certainty is broken. Religious fundamentalism, whether Christian, +Muslim, Hindu, or else besides, is politically empowered in many places, +together with its rejection of science. + +At the same time, the myth of science is ever more punctured. The supposedly +scientific West has increasingly come to appreciate that their scientific +heritage also includes much we would rather ignore - phrenology, race science, +systematic blindness to female bodies in medicine. + +Meanwhile, scientists themselves are noticing that their holy calling has +turned out to be rather less holy than they had hoped. They find science +pulled between the competing demands of truth and tenure. Scientific knowledge +is locked behind the paywalls of exclusive journals, which even many academics +struggle to access, never mind the general public. + +What then for science in the twenty-first century? + +Yet there is another story available. It starts with confessing that the old +stories got things wrong in important ways. When we put ideology aside, science +has not been on an uncontested march to universal acceptance since Galileo. +There has been continual change, continual conflict, continual readjustment of +our ideas to the changing demands of the age. + +In Galileo's day, it may have been a fight to establish that there was much to +be seen by simply looking. As empirical observation started to prove its worth +in the early modern period, thinkers wrestled with new problems: how to +reconcile the evidence of Scripture with the evidence of the senses? How to +understand how sensation can give us knowledge at all, granted that any +observer may be vulnerable to illusions, tricks and dreams? And if that's how +sense data work, what then for our mathematical or logical knowledge, which +seems to already bind the world even before we start experiencing it? + +This centuries-long struggle culminated in the work of Kant, who in his 1786 +magnum opus, the _Critique of Pure Reason_, set out a masterful - if infamously +obscure - system, which enabled thinkers to understand just how empirical +knowledge might work. + +Yet two generations later, Charles Darwin lit the flame under new controversy +about the relationship between scientific and religious knowledge. His bizarre +and wildly imaginative theory of evolution by natural selection challenged the +Genesis Creation accounts, and this was soon to be followed up with the theory +of tectonic shift. + +Some said that where scientists contradicted the authority of Scripture, the +word of God must always win. Others said that science alone had the keys to +knowledge, and if what the Bible said couldn't be proven scientifically, then +it couldn't be accepted. Some said that science and religion were two +incommensurable attempts to study the same subject matter, while others said +that they covered completely separate spheres. + +Gradually, all of these views moved to the extremes. Now, most people (though +not all) agree that science and religion have overlapping spheres, and can +inform one another, but neither the Book of Nature nor the Book of Scripture +has the decisive final say. + +Now, in our post-Christendom Western context, it's more important than ever to +understand how science and religion can talk to one another. Religious +minorities - as all religions now are in the West - are vulnerable to the risk +of becoming epistemic islands, cut off from the knowledge of the rest of the +community, unless we can find ways that science can talk across creedal +differences. + +We need, too, for scientifically marginalised communities, such as non-white +people, whom science has ignored, or worse, to be more tightly integrated into +science, both so that knowledge might increase, and so that the benefits +knowledge gives might be fairly shared. + +In light of these urgent needs, today's philosophers are considering science +not just as an epistemic problem, but as a social problem. As philosophers once +established science as the bedrock of modern knowledge, so philosophers today +have the task of figuring out how science can glue together our societies. + +Science has been at its most dangerous when it hasn't been questioned. At all +times, as long as we practice science, we need to consider what it means, what +it means to do science well, how it can generate knowledge, and how it ought to +be used as a powerful instrument of change. + +And perhaps that might justify James Watt in his obsession to be seen as a +scientist: since we can't get by just with practitioners. We need people who +can see our practices from the outside and shine a mirror back on us. If we +want science, then we need philosophers. + +[phil-sci-coursera]: https://www.coursera.org/learn/philosophy-physical-sciences diff --git a/website/src/data/links.ts b/website/src/data/links.ts index ff6e9d2..0395687 100644 --- a/website/src/data/links.ts +++ b/website/src/data/links.ts @@ -134,6 +134,12 @@ const LINKS: Link[] = [ description: 'Handy for the next time you develop a CLI or TUI. Also handy as a user: now I know about <a href="https://readline.kablamo.org/emacs.html">readline key bindings</a>, which are everywhere apparently.', isoDateAdded: '2024-12-20', }, + { + href: 'https://www.bankofengland.co.uk/statistics/research-datasets', + title: "Bank of England's 'Millenium of Macroeconomic Data'", + description: 'There was no long-term price inflation from 1200 (when these data begin) until 1550. WHAT?!', + isoDateAdded: '2025-01-23', + }, ]; export default LINKS; diff --git a/website/src/pages/blog/[...slug].astro b/website/src/pages/blog/[...slug].astro index 800c534..0754ea7 100644 --- a/website/src/pages/blog/[...slug].astro +++ b/website/src/pages/blog/[...slug].astro @@ -1,20 +1,20 @@ --- -import { type CollectionEntry, getCollection } from 'astro:content'; +import { type CollectionEntry, getCollection, render } from 'astro:content'; import BlogPost from '../../layouts/BlogPost.astro'; export async function getStaticPaths() { const posts = await getCollection('blog'); return posts.map((post) => ({ - params: { slug: post.slug }, + params: { slug: post.id }, props: post, })); } type Props = CollectionEntry<'blog'>; const post = Astro.props; -const { Content } = await post.render(); +const { Content } = await render(post); --- <BlogPost {...post.data}> <Content /> -</BlogPost>
\ No newline at end of file +</BlogPost> diff --git a/website/src/pages/blog/rss.xml.ts b/website/src/pages/blog/rss.xml.ts index afd0640..5b90fd0 100644 --- a/website/src/pages/blog/rss.xml.ts +++ b/website/src/pages/blog/rss.xml.ts @@ -23,9 +23,9 @@ export async function GET(context: APIContext) { site: path.join(site.toString(), 'blog'), trailingSlash: false, items: posts.map((post) => ({ - link: `/blog/${post.slug}`, + link: `/blog/${post.id}`, title: post.data.title, - content: mdParser.render(post.body), + content: mdParser.render(post.body ?? ''), pubDate: post.data.pubDate, description: post.data.description, author: 'Joe Carstairs', diff --git a/website/tsconfig.json b/website/tsconfig.json index 41bbfbf..7fc8467 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -1,6 +1,11 @@ { "extends": "astro/tsconfigs/strict", "compilerOptions": { - "strictNullChecks": true - } -}
\ No newline at end of file + "strictNullChecks": true + }, + "include": [ + ".astro/types.d.ts", + "**/*" + ], + "exclude": ["dist"] +} |
