Categories: sharing » writing » blogging

RSS - Atom - Subscribe via email

Through blogging, we discover our thoughts and other people

| connecting, blogging, writing
Text and links from sketch

Through blogging, we discover our thoughts and other people.

Henrik Karlsson's "Advice for a friend who wants to start a blog" nudged me to explore two threads of thought:

Writing helps you refine your thoughts:

  • This reminds me of Sonke Ahrens's How to Take Smart Notes and David Bessis's Mathematica.
    • Everything drives toward writing; writing is how to clarify your thoughts
    • Writing helps you improve your intuition, which feeds your writing.
  • I want to understand:
    • What's possible?
    • What's easier? what's harder (for now?)
    • How can we make things. easier? How can we make more things doable?
  • and also:
    • What am I thinking?
    • what do I want to try?
  • I want to get better at this through practice.

Writing helps you find your tribe:

  • Definitely - and the more idiosyncratic my posts are, the more amazing it is when someone resonates with it, even years later.
  • (I was amused to see him trace his tweet's flow through Stian HÃ¥klev, who reached out for a conversation in 2010 about peer-to-peer education because he read my blog.)
  • I deliberately boost my tribe's information flow:
  • I want to get better at this by
    • following my curiosity
    • improving search and serendipity
    • connecting people & ideas with community infrastructure and resources

Both sides: Because it's fun and leads to more awesomeness.

View org source for this post

Looking at my blog post stats by year

| blogging
blog-stats.svg
Figure 1: Blog statistics

I was curious about the shape of my blog over the years, excluding Emacs News and my link-heavy weekly/monthly reviews. It started off with lots of little posts like the way other weblogs were also quick links and notes. As weblogs morphed into blogs with more text, I also settled down into fewer, longer posts with lots of code (analyzed by looking for <pre> blocks). I wrote much less after A+ was born. Interestingly, I've been shifting towards longer posts with more images.

  • Blog posts exclude permalinks that match emacs-news|review|week-ending, which casts a bit of a wide net but should give me the general shape of things.
  • Total words per year and average words per post both exclude code snippets.

Here's how I got those numbers:

(append
 '(("Year" "Posts" "Total words" "Words per post" "Posts with pre" "Posts with images")
   hline)
 (cl-loop for i from 2001 to 2024
          collect
          (let* ((default-directory (expand-file-name (number-to-string i) "~/proj/static-blog/blog"))
                 (exclude (shell-quote-argument "emacs-news|review|week-ending"))
                 (files (format "find . -name '*.html' | grep -v -e '%s' | " exclude))
                 (posts (string-to-number
                         (string-trim
                          (shell-command-to-string (concat files "wc -l")))))
                 (words (string-to-number
                         (replace-regexp-in-string
                          "TOTAL: " ""
                          (shell-command-to-string
                           (concat files "xargs ~/bin/count-words | grep TOTAL")))))
                 (posts-with-images
                  (string-to-number
                   (string-trim
                    (shell-command-to-string (concat files "xargs grep -l '<img' | wc -l")))))
                 (posts-with-pre
                  (string-to-number
                   (string-trim
                    (shell-command-to-string (concat files "xargs grep -l '<pre' | wc -l"))))))
            (list i
                  posts
                  words
                  (/ words posts)
                  posts-with-images
                  posts-with-pre))))
Year Posts Total words Words per post Posts with pre Posts with images
2001 3 438 146 0 0
2002 31 4336 139 0 0
2003 863 64953 75 0 59
2004 967 125789 130 2 98
2005 679 135334 199 4 40
2006 869 171042 196 19 42
2007 489 107011 218 33 32
2008 380 121158 318 85 57
2009 400 175692 439 81 20
2010 335 160289 478 93 19
2011 324 163274 503 93 28
2012 286 124300 434 111 12
2013 273 173021 633 172 11
2014 272 186788 686 138 30
2015 173 133682 772 82 36
2016 25 11560 462 13 6
2017 37 24063 650 6 2
2018 66 46827 709 7 8
2019 18 13054 725 3 6
2020 13 6791 522 4 5
2021 31 17389 560 8 16
2022 21 11264 536 4 9
2023 68 47188 693 26 52
2024 74 58439 789 27 40

And here's how I plotted the charts:

import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(data[1:], columns=data[0])
# Create a figure with subplots
fig, (ax1, ax4, ax2, ax3) = plt.subplots(4, 1, figsize=(10, 12))
fig.suptitle('Blog Statistics by Year', fontsize=16)

# Plot Posts
ax1.bar(df['Year'], df['Posts'], color='lightblue', label='Other posts')
ax1.bar(df['Year'], df['Posts with pre'] , color='darkblue', label='With preformatted blocks')
ax1.set_title('Number of posts per year')
ax1.set_ylabel('Posts')
ax1.legend()

# Plot Posts
ax4.bar(df['Year'], df['Posts'], color='lightblue', label='Other posts')
ax4.bar(df['Year'], df['Posts with images'] , color='darkgreen', label='With images')
ax4.set_title('Number of posts per year')
ax4.set_ylabel('Posts')
ax4.legend()

# Plot Total Words
ax2.bar(df['Year'], df['Total words'], color='lightblue')
ax2.set_title('Total words per year')
ax2.set_ylabel('Total words')

# Plot Words per Post
ax3.bar(df['Year'], df['Words per post'], color='lightblue')
ax3.set_title('Average words per post')
ax3.set_ylabel('Words per post')
ax3.set_xlabel('Year')

# Adjust layout and display
plt.savefig(f)
View org source for this post

Thinking about webpage margins

| blogging, design

I want to write more, and I want to enjoy going through my archive. Some posts are long, especially those that come from transcripts. If I sat with the ideas for longer, I might be able to make them more concise or break them up into more atomic notes; but I also want to get things out faster in order to learn from potential conversations. So I'm thinking about text structure and margins, since I want to re-read my blog more and I sometimes glaze over when there's lots of text.

More headings are a good start. Org Mode makes it easy enough to add them: M-RET calls org-insert-heading.

I'm experimenting with sticky tables of contents on large screens: one for "on this page" on the left, and one for long posts on the right.

2024-11-06_16-42-18.png
Figure 1: Screenshot of my blog with tables of content on both sides

On the individual post page, it'll just be the table of contents for the post, like this one.

2024-11-06_16-43-45.png
Figure 2: Screenshot of individual post

It feels a little busy. If I write some Javascript, I might be able to use IntersectionObservers to highlight where we are. Maybe I can even squeeze the article's TOC into the "on this page" TOC if there is one, which means it can stay on one side.

I want to do other things with the margins. Doodles for fun? My cargo bike post started with the doodles pulled all the way into the margins, and then I moved them back into the text so that I don't have to worry about bumping into the table of contents.

2024-11-06_16-45-02.png
Figure 3: Screenshot of doodles in the margins

Sometimes I use a sketchnote to help me think through or summarize a topic. It might be fun to use the sketchnote as a table of contents or overview, maybe even highlighting different sections of it as I scroll. handwritten.blog uses mix-blend-mode for hyperlinks. If the SVG isn't too big, maybe I can use the same kind of technique I used in animating SVG topic maps with Inkscape. Alternatively, I could put extracted regions from the sketchnote in the margins for context and visual variety.

Sidenotes? I like how A Scripter's Notes has both an active, expanding TOC on the right as well as side notes on the left.

2024-11-06_16-46-00.png
Figure 4: Screenshot from A Scripter's Notes

Karthinks uses a sticky TOC and sidenotes:

2024-11-06_16-51-50.png
Figure 5: Screenshot from karthinks.com showing table of contents and sidenotes

A Blog With Relevant Information uses just sidenotes, so the rest of the page feels pretty clear:

2024-11-06_17-07-37.png
Figure 6: Screenshot of sidenotes

Maybe keywords, like the Cornell method of note-taking? Kind of like sidenotes, but more structural, for skimming. I'm having a hard time finding a blog example, though. If I figure out side nodes, I could probably just use a different style to indicate those Cornell-style cues.

But there's so much more I want to do with the space. I like the stacking of https://notes.andymatuschak.org , and I like that you can link to a particular stacked state.

2024-11-06_16-47-44.png
Figure 7: Stacked items from Andy's working notes

Then every so often, I come across a blog that is just clean and refreshing and then I want to get rid of everything in the margins.

There are plenty of CSS and JS resources out there. Figuring out what I want is the tough part.

View org source for this post

How do I want to get better at learning out loud? Part 1 of 4: Starting

| sharing, blogging, writing

Nudged by Thierry Stoehr's toot about my 23rd blogiversary, I've been thinking about how much I've learned thanks to blogging, and how I can get even better at learning out loud. I'm curious about what this could become over the next twenty years, when I'm in my sixties.

The first part of the text from the sketch is duplicated and expanded in the list below. There are a lot of different aspects I want to get better at, so I'm not going to try to work on all of them in one go, but it's fun mapping out so much room for growth.

Besides, maybe one of these aspects will resonate with you as either something you're learning or something you've figured out something about, and then you'll get in touch, and then we'll both learn more. Wouldn't that be cool?

I'm experimenting with getting stuff out in smaller chunks, so this is part 1 of 4: Starting.

Noticing

I think of this as seeing the opportunity for learning, which I sometimes miss out on because I take things for granted or I don't connect the dots. I can get better at this by slowing down and by borrowing other people's questions. I've been giving myself more time to write and draw these days. It feels a little weird ignoring the other tasks on my TODO lists that are more clearly defined or that are related to other people's requests, but I like the way this feels.

Imagining

It's easy for me to come up with all sorts of ideas for things I want to tweak about Emacs. I can get better at this by reading more about what other people are doing and what other capabilities are there.

I can also get better at exploring ideas for non-Emacs topics, like ways to respond to parenting situations and things I can do support the causes I care about. I can expand my toolbox by reading books and blog posts, and depending on the topic, I can also listen to podcasts and videos.

Bumping into things

It's useful to bump into things I might not think of looking for. One way to do that would be to save various manuals on my e-ink notebook and phone so that I can read them during quiet moments.

I've added some randomness to shuffle old blog posts and tasks, although browsing through this tends to be low-priority. (I never get to the bottom of my reading/thinking list!)

"On this day" might be interesting too. This is more for fun and serendipity. I used to have it on my blog, and it should be pretty easy to reimplement using 11ty.

Learning from others

I'd like to spend more time thinking about and building on other people's ideas, maybe starting with Emacs and then branching out to other topics.

I also want to get back to reading people's blogs through an RSS reader so that I can get a slightly wider view of people's interests and learn more about non-Emacs things. I've added Feeder to my phone.

Taking notes

I capture a lot of snippets in my Org Mode inbox. I'd like to get better at adding some more context and quick thoughts when I create a note so that it's easier to pick up the idea later on. I do most of this capturing on my phone, so I'm getting the hang of slowing down and adding some more notes.

I also want to get better at actually reviewing and refining those notes. My inbox tends to grow and grow, especially when I get interrupted by an interesting idea. I have some writing/editing time while I keep A+ company during virtual school, so it'll be fun revisiting the notes I stashed.

Collecting

This is about putting a bunch of related notes together, which I usually do by refiling them. It's probably also related to clustering, which I'll get to in the next post about thinking.

I do most of this collecting on my computer, so I can write a few Emacs functions to make it easier. For example, I have some code to do the opposite of refiling so that while I'm looking at a topic, I can pull in a subtree from somewhere else.

Some buckets collect thoughts for blog posts, some for projects, some just for areas I'm interested in. I feel like I tend to lose track of the buckets that I'm collecting thoughts into–the list of slightly-less-active thoughts, as the active thoughts are easily findable. Maybe this is okay.

Expanding

I want to get better at going from a microblog post/toot or a quick index-card-type sketch to a longer blog post or sketchnote.

Actually, since my current workflow focuses mostly on blog posts, I think this part is more about contracting: picking out a small thought that I can share right now instead of waiting until I write the rest of it. This idea might also include picking a medium-sized chunk and making it the first post in a series, and the current post is an experiment in doing so. I'm a little hesitant to do so because my brain tends to wander off towards the end of a series, but it might be worth an experiment.

I'll also need some code to make it easier to add links between things in a series, which could be manual (handy for other non-series links too) or possibly something handled on the 11ty side (like How to build a blog series with 11ty/Eleventy).

I can also experiment with spreading posts out by scheduling them as Org tasks. I've theoretically added support for holding back future-dated posts in my 11ty config, but I think managing that on the Org side might be easier for now.

Boosting

This is linked to learning from others. Boosting what other people have said or thought can be a quick and easy way of learning out loud and enlarging the conversation. I can do more of that through Mastodon toots, rolling them up into my blog. I often add snippets to my config based on the things I come across in Emacs News.

I also like the commentary on blogs like Irreal and would like to grow into things like that.

Next up: thinking, making, and sharing

Over the next little while, I'm looking forward to fleshing out the next sections. Let's see if breaking things up into posts works…

  • Thinking: trying; reflecting; developing thoughts; shifting; reviewing; clustering; building on; searching (local, web, exact, approximate); questioning; reframing
  • Making: organizing; writing; editing; drawing (sketchnotes, doodles); diagramming; plotting; charts; coding; showing
  • Sharing: designing; linking; mapping thoughts; joining the conversation
View org source for this post

Organizing my visual book notes by topic

| blogging, 11ty

I want to start building up more thoughts as chunks and relating them more logically instead of just chronologically. I've been using categories to organize my posts into buckets, but within a category, it's still chronological. I also have a large outline that includes posts from 2017 to 2024. I'd like to break it up into smaller topic pages so that they're easier to link to, although it's a little more challenging to search.

Now that I have a nice gallery view for my visual book notes, I wanted to organize the book notes by topic. I made an async Eleventy paired shortcode called gallerylist that lets me turn a list of links into into thumbnails and links.

I also modified org-html-toc to not include the Table of Contents header and to tweak the HTML attributes assigned to it.

New table of contents code
(defun my-org-html-toc (depth info &optional scope)
  "Build a table of contents.
DEPTH is an integer specifying the depth of the table.  INFO is
a plist used as a communication channel.  Optional argument SCOPE
is an element defining the scope of the table.  Return the table
of contents as a string, or nil if it is empty."
  (let ((toc-entries
   (mapcar (lambda (headline)
       (cons (org-html--format-toc-headline headline info)
       (org-export-get-relative-level headline info)))
     (org-export-collect-headlines info depth scope))))
    (when toc-entries
      (let* ((toc-id-counter (plist-get info :org-html--toc-counter))
             (toc (concat (format "<div class=\"text-table-of-contents toc-id%s\" role=\"doc-toc\">"
                                  (if toc-id-counter (format "-%d" toc-id-counter) ""))
        (org-html--toc-text toc-entries)
        "</div>\n")))
        (plist-put info :org-html--toc-counter (1+ (or toc-id-counter 0)))
  (if scope toc
    (let ((outer-tag (if (org-html--html5-fancy-p info)
             "nav"
           "div")))
      (concat (format "<%s class=\"table-of-contents toc-id%s\" role=\"doc-toc\">\n"
                            outer-tag
                            (if toc-id-counter (format "-%d" toc-id-counter) ""))
              ;; (let ((top-level (plist-get info :html-toplevel-hlevel)))
              ;; (format "<h%d>%s</h%d>\n"
              ;;   top-level
              ;;   (org-html--translate "Table of Contents" info)
              ;;   top-level))
        toc
        (format "</%s>\n" outer-tag))))))))

(with-eval-after-load 'org
  (defalias 'org-html-toc #'my-org-html-toc))

This is what my visual book notes topic page looks like now:

2024-10-25_09-23-26.png
Figure 1: Screenshot of visual book notes

I can improve on this by using the topic maps to determine next/previous links for the posts. Someday!

View org source for this post

Added a gallery and slideshow view for my visual book notes

| 11ty, blogging

I customized my visual book notes - all view to show the thumbnails of the images, and I added You can get to it by going to the visual-book-notes category from a post and then choosing "All". I like the new "View slideshow" and "Shuffle slideshow" buttons I added.

2024-10-23_14-09-26.png
Figure 1: Screenshot of my visual book notes gallery

I also fixed some of the broken images in older posts, so there should be 43 posts with images now.

Someday I want to add a way to go from the sketch in the slideshow to the post, but it might require upgrading the version of Photoswipe I have. I'm currently on 4.x, which hasn't been updated in years.

View org source for this post

Adding an XSL stylesheet for my RSS and Atom feeds

| 11ty, geek, blogging

Inspired by the styling on Susam's blog feed, I followed this tutorial on using XML stylesheets and added XSL stylesheets for my RSS and Atom feeds. I have RSS and Atom feeds for all my posts as well as for each category or tag (ex: emacs).

2024-01-13_19-06-02.png
Figure 1: RSS feed after styling

To make that happen, I added a line like this to my RSS template:

<?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?>

and for my Atom template:

<?xml-stylesheet href="/assets/atom.xsl" type="text/xsl"?>

and those refer to:

rss.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dc="http://purl.org/dc/elements/1.1/"        xmlns:atom="http://www.w3.org/2005/Atom">
  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
      <title>
        RSS Feed | <xsl:value-of select="/rss/channel/title"/>
      </title>
      <link rel="stylesheet" href="/assets/style.css"/>
    </head>
    <body>
      <h1 style="margin-bottom:0">Recent posts: <xsl:value-of select="/rss/channel/title"/></h1>
      <p>
        This is an RSS feed. You can subscribe to <a href=" {/rss/channel/link}"><xsl:value-of select="/rss/channel/link"/></a> in a feed reader such as <a href="https://github.com/skeeto/elfeed">Elfeed</a> for Emacs, <a href="https://www.inoreader.com/">Inoreader</a>, or <a href="https://newsblur.com/">NewsBlur</a>, or you can use tools like <a href="https://github.com/rss2email/rss2email">rss2email</a>. The feed includes the full blog posts.
You can also view the posts on the website at
<a href="{/rss/channel/atom:link[contains(@rel,'alternate')]/@href}"><xsl:value-of select="/rss/channel/atom:link[contains(@rel,'alternate')]/@href" /></a> .
      </p>
      <xsl:for-each select="/rss/channel/item">
        <div style="margin-bottom:20px">
        <div>
          <xsl:value-of select="pubDate" />
        </div>
        <div>
          <a>
            <xsl:attribute name="href">
              <xsl:value-of select="link/@href"/>
            </xsl:attribute>
            <xsl:value-of select="title"/>
          </a></div></div>
      </xsl:for-each>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
atom.xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:atom="http://www.w3.org/2005/Atom">
  <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:template match="/">
  <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
    <head>
      <title>
        Atom Feed | <xsl:value-of select="/atom:feed/atom:title"/>
      </title>
      <link rel="stylesheet" href="/assets/style.css"/>
    </head>
    <body>
      <h1 style="margin-bottom:0">Recent posts: <xsl:value-of select="/atom:feed/atom:title"/></h1>
      <p>
        This is an Atom feed. You can subscribe to <a href=" {/atom:feed/atom:link/@href}"><xsl:value-of select="/atom:feed/atom:link/@href"/></a> in a feed reader such as <a href="https://github.com/skeeto/elfeed">Elfeed</a> for Emacs, <a href="https://www.inoreader.com/">Inoreader</a>, or <a href="https://newsblur.com/">NewsBlur</a>, or you can use tools like <a href="https://github.com/rss2email/rss2email">rss2email</a>. The feed includes the full blog posts.
You can also view the posts on the website at
<a href="{/atom:feed/atom:link[contains(@rel,'alternate')]/@href}"><xsl:value-of select="/atom:feed/atom:link[contains(@rel,'alternate')]/@href" /></a> .
      </p>
      <xsl:for-each select="/atom:feed/atom:entry">
        <div style="margin-bottom:20px">
          <div>
          <xsl:value-of select="substring(atom:updated, 0, 11)" /></div>
          <div><a>
            <xsl:attribute name="href">
              <xsl:value-of select="atom:link/@href"/>
            </xsl:attribute>
            <xsl:value-of select="atom:title"/>
          </a></div></div>
      </xsl:for-each>
    </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
View org source for this post