This commit is contained in:
Akko
2025-10-25 18:58:30 +02:00
parent fa280d0c8a
commit e3c7037dab
55 changed files with 3459 additions and 804 deletions

View File

@@ -1,6 +1,211 @@
#+TITLE: Index
* Hello There!
Welcome to my website! I'm [[./about.org][akk0]]. I blog about Emacs, programming, meditation, otaku stuff, and other things that interest me. You can view the full list of pages on the [[./sitemap.org][sitemap]].
This site launched recently and is still under construction; please pardon the dust! I maintain a [[./projects/blog.org][somewhat up-to-date TO-DO list]]; don't hestitate to reach out to me through the email address in the footer for feedback or feature suggestions ^^".
Find me on [[https://bsky.app/profile/webbieweb.org][bsky]]!
Here's this week's [[./journal/w43-2025.org][journal]]!
** /Pro Tips/
- You can fold and unfold sections by clicking the headline. Try it!
- Click on any cell with a dotted outline in the habit tracker to see my journal entry for it. The currently selected cell will be highlighted in pink.
** Habits
#+BEGIN_CENTER
/Today is Saturday, 25th October./
#+END_CENTER
#+BEGIN_SRC emacs-lisp :exports results :results value html :cache no
(defun akk0/org-to-html (org-string)
"Convert ORG-STRING to HTML."
(with-temp-buffer
(insert org-string)
(org-mode)
(org-export-as 'html nil nil t nil)))
(defun akk0/sort-habits (habit-alist)
"Sort habit-alist by a predefined order of custom-ids."
(let ((order '("dailies-blogging" "dailies-meditation" "dailies-french" "dailies-engineering"
"dailies-exercise" "dailies-drawing" "dailies-reading" "dailies-social")))
(sort (copy-sequence habit-alist)
(lambda (a b)
(let ((pos-a (or (cl-position (car a) order :test #'equal) 999))
(pos-b (or (cl-position (car b) order :test #'equal) 999)))
(< pos-a pos-b))))))
(defun akk0/extract-habits (file)
"Extract habits with date context from FILE.
Returns a list of plists with :custom-id, :todo-state, :date, :day-of-year."
(with-temp-buffer
(insert-file-contents file)
(org-mode)
(let (results)
(org-element-map (org-element-parse-buffer) 'headline
(lambda (hl)
(let ((custom-id (org-element-property :CUSTOM_ID hl))
(todo-state (org-element-property :todo-keyword hl)))
(when (and custom-id todo-state)
;; Get parent properties for context
(let* ((parent (org-element-property :parent hl))
(day-of-year (or (org-element-property :DAILIES-DAY parent)
(let ((grandparent (org-element-property :parent parent)))
(when grandparent
(org-element-property :DAILIES-DAY grandparent)))))
(body (org-element-interpret-data
(org-element-contents hl))))
(push (list :custom-id custom-id
:todo-state todo-state
:day-of-year day-of-year
:file file
:body body)
results))))))
(nreverse results))))
(defun akk0/extract-all-habits (files)
(mapcan #'akk0/extract-habits files))
(setq akk0/journal-files
(directory-files "~/Blog/org/journal/" t "^w.*\\.org$"))
(defun akk0/habits-alist (habits)
"Transform HABITS list into nested alists: custom-id → day-of-year → habit-data."
(let (result)
(dolist (habit habits)
(let* ((custom-id (plist-get habit :custom-id))
(day-of-year (plist-get habit :day-of-year))
(todo-state (plist-get habit :todo-state))
(body (plist-get habit :body))
;; Get the alist for this custom-id
(inner-alist (alist-get custom-id result nil nil #'equal))
;; Store full data instead of just todo-state
(habit-data (list :todo-state todo-state :body body :day-of-year day-of-year))
;; Update the inner alist
(updated-inner (cons (cons day-of-year habit-data) inner-alist)))
;; Update result
(setf (alist-get custom-id result nil nil #'equal) updated-inner)))
result))
(setq habit-alist (akk0/habits-alist (akk0/extract-all-habits akk0/journal-files)))
(defun akk0/get-habit-history (habit-alist custom-id day-number days-back window-size)
(let* ((inner-alist (alist-get custom-id habit-alist nil nil #'equal))
(result nil)
(all-states nil)
(score-for-state (lambda (state)
(cond ((equal state "NO") -1)
((equal state "YES") 1)
((equal state "EXCELLENT") 2)
(t 0)))))
(dotimes (i days-back)
(let* ((current-day (+ (- day-number days-back) i 1))
(current-day-str (number-to-string current-day))
(habit-data (alist-get current-day-str inner-alist nil nil #'equal))
(todo-state (if habit-data
(plist-get habit-data :todo-state)
"NODATA"))
(body (if habit-data
(plist-get habit-data :body)
""))
(doy (if habit-data
(plist-get habit-data :day-of-year)
""))
)
(push todo-state all-states)
(let* ((window-states (seq-take all-states window-size))
(rolling-score (apply #'+ (mapcar score-for-state window-states))))
(push (list :todo-state todo-state
:score (max 1 (min 5 (/ (+ rolling-score 5) 2)))
:body body
:doy doy)
result))))
(nreverse result)))
(defun akk0/habits-to-html-table (habit-alist day-number days-back window-size)
"Generate HTML table of habits with rolling scores.
Rows are custom-ids, columns are days."
(let ((color-map '(("NODATA" . "grey")
("YES" . "green")
("NO" . "red")
("FREED" . "purple")
("EXCELLENT" . "blue")))
(symbol-map '(("NODATA" . "")
("YES" . "")
("NO" . "×")
("FREED" . "")
("EXCELLENT" . "")))
(sorted-habits (akk0/sort-habits habit-alist))
(html ""))
;; Start table
(setq html (concat html "<table style='margin-left: auto; margin-right:auto; margin-bottom: 0.8rem;'>\n"))
;; Header row with day numbers
(setq html (concat html " <tr>\n <th></th>\n"))
(dotimes (i days-back)
(let ((day (+ (- day-number days-back) i 1)))
(setq html (concat
html
(cond ((= day day-number) "<th>●</th>")
((= 0 (% (- day day-number) 7)) "<th>○</th>")
(t "<th />"))))))
(setq html (concat html " </tr>\n"))
;; Data rows - one per habit
(dolist (entry sorted-habits)
(let* ((custom-id (car entry))
(history (akk0/get-habit-history habit-alist custom-id day-number days-back window-size)))
(setq html (concat html (format " <tr>\n <td style='padding-right: 20px; padding-top: 5px; padding-bottom: 5px;'><i>%s</i></td>\n" (capitalize (string-remove-prefix "dailies-" custom-id)))))
;; Cell for each day
(dolist (day-data history)
(let* ((todo-state (plist-get day-data :todo-state))
(score (plist-get day-data :score))
(body (plist-get day-data :body))
(doy (plist-get day-data :doy))
(body-html (if (and body (not (string-empty-p body)))
(akk0/org-to-html body)
""))
(color (alist-get todo-state color-map nil nil #'equal))
(symbol (alist-get todo-state symbol-map nil nil #'equal))
(class (format "habit-brightness-%d" score))
(style-var (format "--%s%d" color score))
(escaped-body (replace-regexp-in-string "\"" "&quot;"
(replace-regexp-in-string "\n" "&#10;" body-html)))
)
(setq html (concat html (format " <td class=\"%s habit-cell\" style=\"background-color:var(%s)\" data-body=\"%s\" onclick=\"showHabitPopup(this)\" data-doy=\"%s\" data-activity=\"%s\"
data-status=\"%s\">%s</td>\n"
class style-var
escaped-body
doy
custom-id
todo-state
symbol)))))
(setq html (concat html " </tr>\n"))))
;; End table
(setq html (concat html "</table>\n"))
html))
(akk0/habits-to-html-table habit-alist 298 30 5)
#+END_SRC
#+BEGIN_EXPORT html
<span class="center"><b>Key:</b>
<span style="color: var(--grey3);">Unknown</span> |
<span style="color: var(--red3);">× No</span> |
<span style="color: var(--green3);">● Yes</span> |
<span style="color: var(--blue3);">♦ Excellent</span> |
<span style="color: var(--purple3);">♣ Freed Up</span>
</span>
<hr />
<div class="habit-popup" id="habitPopup">
<div class="habit-popup-content" id="habitPopupContent">
<span class='center'><i>This section intentionally left blank.</i></span>
</div>
</div>
#+END_EXPORT

38
org/journal/template.org Normal file
View File

@@ -0,0 +1,38 @@
#+FILETAGS: :no_sitemap:
#+TODO: NO(n) | YES(y) EXCELLENT(e) FREED(f)
#+title: Journal Week XX, 2025
* Journal Week XX, 2025
** Monday, YYth ZZZ
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: NNN
:END:
*** NO Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
*** NO Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
*** NO Blogging
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
*** NO Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
*** NO Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
*** NO French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
*** NO Social
:PROPERTIES:
:CUSTOM_ID: dailies-social
:END:

102
org/journal/w42-2025.org Normal file
View File

@@ -0,0 +1,102 @@
#+TODO: NO(n) | YES(y) EXCELLENT(e) FREED(f)
#+title: Journal Week 42, 2025
* Journal Week 42, 2025
** Thursday, 16th October
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: 289
:END:
*** YES Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
*** YES Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
*** EXCELLENT Blogging
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
*** NO Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
*** EXCELLENT Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
*** NO French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
** Friday, 17th October
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: 290
:END:
*** EXCELLENT Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
*** EXCELLENT Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
*** NO Blogging
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
*** NO Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
*** NO Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
*** NO French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
*** EXCELLENT Social
:PROPERTIES:
:CUSTOM_ID: dailies-social
:END:
** Sunday, 19th October
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: 292
:END:
*** YES Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
*** YES Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
*** NO Blogging
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
*** NO Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
*** NO Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
*** NO French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
*** EXCELLENT Social
:PROPERTIES:
:CUSTOM_ID: dailies-social
:END:

157
org/journal/w43-2025.org Normal file
View File

@@ -0,0 +1,157 @@
#+TODO: NO(n) | YES(y) EXCELLENT(e) FREED(f)
#+title: Journal Week 43, 2025
#+BEGIN_CENTER
[[./w42-2025.org][Previous]] | [[./index.org][Index]]
#+END_CENTER
* Journal Week 43, 2025
** Thursday, 23th October
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: 296
:END:
*** EXCELLENT Journal
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
**** Four Fields
I've been feeling as though I've been /bootlooping/ for a while now... like there's never enough momentum to really get the habits I'm trying to build online. Especially with work-hunting and French studies this is starting to become a real problem.
Last night I came up with the following time management system, which I'll be trying for a while. In this system, the business of life divides into four /fields/:
- *Body* -- Care for the physical body /e.g./ exercise, preparing and eating food, personal hygiene;
- *Mind* -- Care for the mind, /e.g./ studying, playing games, reading, meditation;
- *House* -- Things concerning not only the actual household, anything /of the environment/, /e.g./ tidying up, finances, all manner of chores, administrating digital systems;
- *Role* -- Things as they relate to interpersonal relations and society /e.g./ family, friendship, neighborliness.
Things are grouped into fields moreso on /intention/ than on /activity/. Every *hour* I choose one field to work on, and resolve to limit my activities to that field. I started today with an hour of /Body/, which included eating breakfast, stretching, showering and brushing my teeth and so on. I write this now in an hour of /House/, under which I count this writing, after which I will clean up my browser tabs, set hourly alarms on my phone to help me stick to the system, and maybe do some more chores around the website if there's time. I'll probably follow with either an hour of /Role/ (French study), /Mind/ (meditation), or /Body/ (taking a walk and a nap), depending on how I feel.
In principle this system should ensure that I can constrain myself to thinking about only ¼ of reality for only 1 hour at a time.
**** Cleaning House
#+BEGIN_center
#+ATTR_HTML: :width 100%
#+CAPTION:/I'm not fucking around./
[[../../static/images/journal/yes_chad_tabs.png]]
#+END_center
Got rid of over 1500 tabs. Good riddance. I'm sure whatever was in there was totally worth looking at, and I look forward to running into it again. Life's too busy to be hoarding /intentions./
*** Habits :autocollapse:
**** YES Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
**** NO Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
**** EXCELLENT Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
Added tons of features to the website, primarily to the habit tracker.
**** YES French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
Added 39 words to anki. Started going through [[https://www.lawlessfrench.com/learn-french/checklist/unit-01/][Lawless French]].
**** YES Social
:PROPERTIES:
:CUSTOM_ID: dailies-social
:END:
**** YES Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
Walkies
**** YES Reading
:PROPERTIES:
:CUSTOM_ID: dailies-reading
:END:
Resumed reading /After the Ecstasy, the Laundry/.
** Friday, 24th October
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: 297
:END:
*** YES Journal
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
Luminous.
*** Habits :autocollapse:
**** YES Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
**** NO Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
**** FREED Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
**** YES French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
**** YES Social
:PROPERTIES:
:CUSTOM_ID: dailies-social
:END:
**** EXCELLENT Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
**** YES Reading
:PROPERTIES:
:CUSTOM_ID: dailies-reading
:END:
** Saturday, 25th October
:PROPERTIES:
:DAILIES-YEAR: 2025
:DAILIES-DAY: 298
:END:
*** YES Journal
:PROPERTIES:
:CUSTOM_ID: dailies-blogging
:END:
Thanks to the chickens for laying eggs for me, grass and buggies for feeding those chickens, truckers for transporting them, the people of the supermarket for stocking them, and the electricity company for allowing my induction plate to work.
Went to the forest and farm today. First time printing PETG with the 3D printer -- hard to get right. Broke the streak of not drawing! Found out the supermarket stocks fantastic tiny star-shaped gnocchis.
*** Habits :autocollapse:
**** YES Meditation
:PROPERTIES:
:CUSTOM_ID: dailies-meditation
:END:
**** EXCELLENT Drawing
:PROPERTIES:
:CUSTOM_ID: dailies-drawing
:END:
#+BEGIN_center
#+ATTR_HTML: :width 70%
[[../../static/images/journal/drawing-25102025.jpg]]
#+END_center
**** FREED Engineering
:PROPERTIES:
:CUSTOM_ID: dailies-engineering
:END:
**** NO French
:PROPERTIES:
:CUSTOM_ID: dailies-french
:END:
**** YES Social
:PROPERTIES:
:CUSTOM_ID: dailies-social
:END:
**** EXCELLENT Exercise
:PROPERTIES:
:CUSTOM_ID: dailies-exercise
:END:
**** YES Reading
:PROPERTIES:
:CUSTOM_ID: dailies-reading
:END:

View File

@@ -1,11 +1,14 @@
#+TITLE: Sitemap for project pages
- [[file:friends.org][Friends]]
- [[file:index.org][Index]]
- [[file:friends.org][Friends]]
- [[file:todo.org][To Do]]
- [[file:about.org][About]]
- [[file:journal/index.org][Journal]]
- [[file:journal/w43-2025.org][Journal Week 43, 2025]]
- [[file:journal/w42-2025.org][Journal Week 42, 2025]]
- [[file:journal/w41-2025.org][Journaly Week 41, 2025]]
- [[file:journal/w31-2025.org][Journal Week 31, 2025]]
- [[file:journal/w30-2025.org][Journal Week 30, 2025]]
- [[file:journal/w29-2025.org][Journal Week 29, 2025 (July 14 to 20)]]