Tagged view

Table of Contents

Go back to index.

Implementation details

This page is an experiment to implement tag based index page. And I have pretty much achieved that.

(require 'project)
(defun p/get-posts-files (&optional directory)
  "Get the file names of all the posts from DIRECTORY."
  (remq nil (mapcar
             (lambda (filename)
               (if (not (or (string-match "draft.*" filename)
                            (string-match (rx ".el") filename)))
                   filename))
             (directory-files
              (or directory
                  (expand-file-name "content"
                                    (project-root (project-current))))
              t directory-files-no-dot-files-regexp))))

(defun p/get-tags (filename)
  "Get the tags in FILENAME."
  (condition-case nil
      (save-excursion
        (find-file filename)
        (goto-char (point-min))
        (search-forward "#+tags:")
        (string-split
         (string-trim (thing-at-point 'line t) ".*tags:\s*")
         ":"))
    (error nil)))
(defun p/get-title (filename)
  "Get the title in FILENAME."
  (condition-case nil
      (save-excursion
        (find-file filename)
        (goto-char (point-min))
        (search-forward "#+title:")
        (string-trim (thing-at-point 'line t) ".*title:\s*"))
    (error nil)))

(defun p/tags-table(&optional directory)
  "Get a tags-table for all posts."
  (mapcar
   (lambda (post) `(,post ,(p/get-title post) ,(p/get-tags post))) (p/get-posts-files directory)))

(defun p/group-by-tags (tags-table)
  "Group TAGS-TABLE by the tags."
  (mapcar (lambda (tag)
            `(,tag ,(delete nil
                            (mapcar (lambda (item)
                                      (if (member tag (flatten-list (last item)))
                                          (take 2 item)))
                                    tags-table))))
          (delete-dups (flatten-tree (mapcar #'last tags-table)))))

(mapconcat
 (lambda (taglist)
   (let ((tag (car taglist))
         (articles (cadr taglist)))
     (format "* %s\n:PROPERTIES:\n:CUSTOM_ID: %s\n:END:\n%s\n" tag tag
             (mapconcat (lambda (article)
                          (format "- [[./%s][%s]]"
                                  (file-name-nondirectory (car article))
                                  (cadr article)))
                        articles "\n"))))
 (p/group-by-tags (p/tags-table)) "\n")

special

meta

programming

emacs

philosophy

linux

ram

freesoftware

story

git

tutorial

unix

Author: tusharhero

emailreplace [at] with @, and put the domain for username, and vice versa: sdf.org [at] tusharhero

© tusharhero 2024-2025, check licenses page for details.

Date: 2025-05-09 Fri 10:28

Emacs 31.0.50 (Org mode 9.7.11)