Collecting Emacs News from Mastodon
Posted: - Modified: | emacs, mastodon
my-org-link-url-from-string
.
One of the things I like about browsing Mastodon in Emacs using
mastodon.el is that I can modify my workflow to make things easier.
For example, I often come across links that I'd like to save for Emacs
News. I want to boost the post and save it to an Org file, and I can
do that with a single keystroke. It uses the my-mastodon-store-link
function
defined elsewhere in my config.
(use-package org :config (add-to-list 'org-capture-templates '("📰" "Emacs News" entry (file+headline "~/sync/orgzly/news.org" "Collect Emacs News") "* %a :news: #+begin_quote %:text #+end_quote " :prepend t :immediate-finish t))) (defun my-mastodon-save-toot-for-emacs-news () (interactive) ;; boost if not already boosted (unless (get-text-property (car (mastodon-tl--find-property-range 'byline (point))) 'boosted-p) (mastodon-toot--toggle-boost-or-favourite 'boost)) ;; store a link and capture the note (org-capture nil "📰")) (use-package mastodon :bind (:map mastodon-mode-map ("w" . my-mastodon-save-toot-for-emacs-news)))
This puts a bunch of notes in my
~/sync/orgzly/news.org
file. Then I can use
my-emacs-news-summarize-mastodon-items
to
summarize a bunch of items I've captured from
Mastodon, taking the title from the first link and
including a link to the toot using the author's
handle. This is what it looks like:

Here's the code that makes that happen:
(defun my-emacs-news-summarize-mastodon-items () (interactive) (while (not (eobp)) (let* ((info (my-mastodon-get-note-info)) (title (when (car (plist-get info :links)) (my-page-title (car (plist-get info :links))))) (summary (read-string (if title (format "Summary (%s): " title) "Summary: ") title))) (org-cut-subtree) (unless (string= summary "") (insert "- " (org-link-make-string (or (car (plist-get info :links)) (plist-get info :url)) summary) (if (and (car (plist-get info :links)) (plist-get info :handle)) (concat " (" (org-link-make-string (plist-get info :url) (plist-get info :handle)) ")") "") "\n"))))) (defun my-match-groups (&optional object) "Return the matching groups, good for debugging regexps." (seq-map-indexed (lambda (entry i) (list i entry (and (car entry) (if object (substring object (car entry) (cadr entry)) (buffer-substring (car entry) (cadr entry)))))) (seq-partition (match-data t) 2))) (defun my-org-link-url-from-string (s) "Return the link URL from S." (if (string-match org-link-any-re s) (or (match-string 7 s) (match-string 2 s)))) (defun my-mastodon-get-note-info () "Return (:handle ... :url ... :links ... :text) for the current subtree." (let ((url (let ((title (org-entry-get (point) "ITEM"))) (if (string-match org-link-any-re title) (or (match-string 7 title) (match-string 2 title))))) beg end handle) (save-excursion (org-back-to-heading) (org-end-of-meta-data) (setq beg (point)) (setq end (org-end-of-subtree)) (cond ((string-match "\\[\\[https://bsky\\.app/.+?\\]\\[\\(.+\\)\\]\\]" url) (setq handle (match-string 1 url))) ((string-match "https://\\(.+?\\)/\\(@.+?\\)/" url) (setq handle (concat (match-string 2 url) "@" (match-string 1 url)))) ((string-match "https://\\(.+?\\)/\\(.+?\\)/p/[0-9]+\\.[0-9]+" url) (setq handle (concat "@" (match-string 2 url) "@" (match-string 1 url))))) (list :handle handle :url (if (string-match org-link-bracket-re url) (match-string 1 url) url) :links (reverse (mapcar (lambda (o) (org-element-property :raw-link o)) (my-org-get-links-in-region beg end))) :text (string-trim (buffer-substring-no-properties beg end)))))) (ert-deftest my-mastodon-get-note-info () (should (equal (with-temp-buffer (insert "** SOMEDAY https://mastodon.online/@jcastp/111762105597746747 :news: :PROPERTIES: :CREATED: [2024-01-22 Mon 05:51] :END: jcastp@mastodon.online - I've shared my emacs config: https://codeberg.org/jcastp/emacs.d After years of reading other's configs, copying really useful snippets, and tinkering a little bit myself, I wanted to give something back, although I'm still an amateur (and it shows, but I want to improve!) If you can find there something you can use, then I'm happy to be useful to the community. #emacs ") (org-mode) (my-mastodon-get-note-info)) '(:handle "@jcastp@mastodon.online" :url "https://mastodon.online/@jcastp/111762105597746747" :links ("https://codeberg.org/jcastp/emacs.d") :text "jcastp@mastodon.online - I've shared my emacs config: https://codeberg.org/jcastp/emacs.d\n\nAfter years of reading other's configs, copying really useful snippets, and tinkering a little bit myself, I wanted to give something back, although I'm still an amateur (and it shows, but I want to improve!)\n\nIf you can find there something you can use, then I'm happy to be useful to the community.\n\n#emacs"))))
It turns headings into something like this:
which I can then copy into my Emacs News Org Mode file and categorize with some keyboard shortcuts.
This works particularly well with my combined Mastodon timelines, because then I can look through all the #emacs posts from mastodon.social, emacs.ch, and social.sachachua.com in one go.