Tagged view
Table of Contents
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")