skip to content

GnoponEmacs

Components

Package Management

  (defvar straight-install-script-path
  "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el")

(setq straight-repository-branch "develop")

(defvar bootstrap-version)
(let ((bootstrap-file
         (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
        (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
    (url-retrieve-synchronously straight-install-script-path
     'silent 'inhibit-cookies)
        (goto-char (point-max))
        (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))
  (straight-use-package 'use-package)

User Experience

User Configuration

  (setq user-mail-address "emsenn@emsenn.net")
(setq ring-bell-function 'ignore)

(setq make-backup-files nil)
(setq inhibit-startup-message t)
(setq inhibit-startup-screen t)
(setq initial-scratch-message
        ";; LANDBACK")
(menu-bar-mode -1)
(tool-bar-mode -1)
(show-paren-mode 1)
(setq line-number-mode t)
(setq column-number-mode t)
(setq-default truncate-lines t)
(setq-default line-spacing 1)
(setq sentence-end-double-space nil)
(global-visual-line-mode t)
(setq echo-keystrokes 0.1)
(setq fill-column 68)
(setq mouse-wheel-scroll-amount '(1 ((shift) .1)))

Mixed Pitch Mode

(use-package mixed-pitch
  :straight t
  :hook
  (text-mode . mixed-pitch-mode))

Modus Theme

(use-package modus-themes
  :straight t
  :config
  (load-theme 'modus-vivendi t))

Olivetti

(use-package olivetti
:straight t
:hook
(text-mode . olivetti-mode))
(require 'ucs-normalize)

Recordkeeping

Beancount

(straight-use-package
 '(beancount :type git :host github
             :repo "beancount/beancount-mode"))

YASnippet

(use-package
  yasnippet :straight t
  :hook ((text-mode
          prog-mode
          conf-mode
          snippet-mode)
         . yas-minor-mode-on)
  :custom (yas-snippet-dirs '("~/ems/org/met/yas-snippets")))

Org-mode

Org-mode Configuration
(use-package
  org :straight t
  :custom
  (org-directory "~/ems/org")
  (org-startup-folded 'fold)
  (org-hide-block-startup 'hideblocks)
  (org-catch-invisible-edits 'show-and-error)
  (org-agenda-custom-commands
        '(("A" "Agenda and TODO"
           ((agenda "" )
            (alltodo "" )))))
  (org-agenda-todo-ignore-scheduled 'all)
  (org-export-with-section-numbers nil)
  (org-export-with-smart-quotes nil)
  (org-cite-export-processors
    '((latex biblatex)
        (html csl)
        (odt csl)
        (ascii csl)
        (md csl)))
  (org-export-with-toc nil)
  (org-html-htmlize-output-type 'nil)
  (org-html-validation-link nil)
  (org-log-done 'time)
  (org-log-into-drawer 'LOGBOOK)
  (org-list-allow-alphabetical t)
  (org-image-actual-width '(400))
  (org-cite-global-bibliography '("~/ems/org/ref/bibliography.bib"))
  (org-export-global-macros
   '(
     ("nl" . "(eval \"\\n\")")
     ))
  :bind (
         ("C-c l" . org-store-link)
         ("C-c a" . org-agenda)
         ("C-c c" . org-capture)
         ("C-c t" . org-toggle-link-display)
         ("C-c C-q" . counsel-org-tag)
         )
  :defines gpe/emsenn-net-head
  :config

        ;; from https://www.john2x.com/blog/blogging-with-orgmode.html
        (defun gpe/org-publish-format-sitemap (title sitemap)
          (let ((posts (cdr sitemap)))
            (concat
             (format "#+title: %s\n" title)
             "#+options: timestamp:nil date:nil\n"
             (format "#+date: %s\n" (format-time-string "[%Y-%m-%d %a %H:%M:%S]" (current-time)))
             (org-list-to-org (cons (car sitemap) posts)))))
        (setq gpe/emsenn-net-head
              (with-temp-buffer
                (insert "<style>\n")
                (insert-file-contents "~/ems/org/src/emsenn-net/main.css")
                (goto-char (point-max)) ;; move to end before appending
                (insert "\n</style>")
                (buffer-string)))
        (setq gpe/emsenn-net-preamble
              (with-temp-buffer
                (insert-file-contents "~/ems/org/src/emsenn-net/preamble.html")
                (buffer-string)))
  (org-babel-do-load-languages 'org-babel-load-languages
                               '(
                                 (shell . t)
                                 )))

Orc-cite-proc

(use-package citeproc :straight t)

Org-roam

(use-package
  org-roam :straight t
  :after org
  :config
  (cl-defmethod org-roam-node-instantiates ((node org-roam-node))
    (let ((val (cdr (assoc "INSTANTIATES" (org-roam-node-properties node)))))
        (when (stringp val)
          (substring val 43 -2))))
(defun gpe/get-node-properties (node)
  (nth 9 node))
(defun gpe/get-node-property (node prop)
  (cdr (assoc prop (get-node-properties node))))p
  (defun gpe/load-node-acts ()
    (interactive)
    (dolist (file (directory-files "~/ems/org/src/gpe/node-acts/"
                                     t "\\.el$"))
        (let* ((name (file-name-base file))
               (sym  (intern name))
               (nsym (intern (format "gpe/node/%s" name))))
          (load-file file)
          (when (fboundp sym)
            (defalias nsym sym)))))
  (defun gpe/insert-backlinks (backend)
    (when (org-export-derived-backend-p backend 'html)
        (let ((node (org-roam-node-at-point)))
          (when node
            (save-excursion
              (goto-char (point-max))
              (insert "\n* Backlinks\n")
              (dolist (ref (org-roam-backlinks-get node))
                (let* ((source (org-roam-backlink-source-node ref))
                       (props (org-roam-node-properties source))
                       (is-public (string= (cdr (assoc "PUBLIC" props)) "true")))
                  (when is-public
                    (insert (format "- [[id:%s][%s]]\n"
                                    (org-roam-node-id source)
                                    (org-roam-node-title source)))))))))))
  (defun gpe/org-roam-public-nodes ()
    (org-roam-db-query
     [:select
      [*] :from nodes
      :where (like properties '"%public%true%")]))
  (defun gpe/org-roam-public-node-files ()
      (mapcar #'cadr
              (gpe/org-roam-public-nodes)))
  (defun gpe/bibtex-collect-entries ()
    (let ((results ""))
        (dolist (nodes (org-roam-db-query [:select [*] :from nodes]))
          (let ((file (nth 1 nodes)))
            (when (file-exists-p file)
              (with-temp-buffer
                (insert-file-contents file)
                (org-mode)
                (org-babel-map-src-blocks nil
                  (when (and (string= lang "bibtex")
                             (let* ((info (org-babel-get-src-block-info 'light))
                                    (params (nth 2 info)))
                               (string= (alist-get :canonical params) "yes")))
                    (setq results (concat results body "\n\n"))))))))
        results))
  (defun gpe/bibtex-generate-bibliography ()
    (interactive)
    (let* ((entries (gpe/bibtex-collect-entries))
             (outfile (car org-cite-global-bibliography)))
        (unless outfile
          (user-error "No file in `org-cite-global-bibliography`"))
        (with-temp-file outfile
          (insert entries))
        (message "Wrote bibliography to %s" outfile)))
  (defun gpe/bibtex-render-global-bibliography ()
    (let* ((bib (car org-cite-global-bibliography))
             (all-keys (with-temp-buffer
                         (insert-file-contents bib)
                         (bibtex-mode)
                         (goto-char (point-min))
                         (let (keys)
                           (while (re-search-forward "@\\w+{\\([^,]+\\)," nil t)
                             (push (match-string 1) keys))
                           (nreverse keys)))))
        (concat
         (mapconcat (lambda (k) (format "[cite:@%s]" k)) all-keys " ")
         "\n\n#+print_bibliography:\n")))
  (defun gpe/org-roam-open-random-node ()
    "Open a random Org-roam node from the database."
    (interactive)
    (let* ((nodes (org-roam-node-list))
           (count (length nodes)))
      (if (zerop count)
          (message "No Org-roam nodes found.")
        (let* ((random-index (random count))
               (node (nth random-index nodes)))
          (org-roam-node-visit node)))))
  (defun gpe/apply-capture-properties ()
    (let ((properties '(:author :form)))
      (dolist (property properties)
        (let ((value (plist-get org-capture-current-plist property)))
          (when value
            (org-set-property (substring (symbol-name property) 1) value))))))
  (cl-defmethod org-roam-node-slug ((node org-roam-node))
    "Return the slug of NODE."
    (let ((title (org-roam-node-title node))
          (slug-trim-chars '(;; Combining Diacritical Marks https://www.unicode.org/charts/PDF/U0300.pdf
                             768 ; U+0300 COMBINING GRAVE ACCENT
                             769 ; U+0301 COMBINING ACUTE ACCENT
                             770 ; U+0302 COMBINING CIRCUMFLEX ACCENT
                             771 ; U+0303 COMBINING TILDE
                             772 ; U+0304 COMBINING MACRON
                             774 ; U+0306 COMBINING BREVE
                             775 ; U+0307 COMBINING DOT ABOVE
                             776 ; U+0308 COMBINING DIAERESIS
                             777 ; U+0309 COMBINING HOOK ABOVE
                             778 ; U+030A COMBINING RING ABOVE
                             780 ; U+030C COMBINING CARON
                             795 ; U+031B COMBINING HORN
                             803 ; U+0323 COMBINING DOT BELOW
                             804 ; U+0324 COMBINING DIAERESIS BELOW
                             805 ; U+0325 COMBINING RING BELOW
                             807 ; U+0327 COMBINING CEDILLA
                             813 ; U+032D COMBINING CIRCUMFLEX ACCENT BELOW
                             814 ; U+032E COMBINING BREVE BELOW
                             816 ; U+0330 COMBINING TILDE BELOW
                             817 ; U+0331 COMBINING MACRON BELOW
                             )))
      (cl-flet* ((nonspacing-mark-p (char)
                   (memq char slug-trim-chars))
                 (strip-nonspacing-marks (s)
                   (ucs-normalize-NFC-string
                    (apply #'string (seq-remove #'nonspacing-mark-p
                                                (ucs-normalize-NFD-string s)))))
                 (cl-replace (title pair)
                   (replace-regexp-in-string (car pair) (cdr pair) title)))
        (let* ((pairs `(("[^[:alnum:][:digit:]]" . "-") ;; convert anything not alphanumeric
                        ("--*" . "-")                   ;; remove sequential underscores
                        ("^-" . "")                     ;; remove starting underscore
                        ("-$" . "")))                   ;; remove ending underscore
               (slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs)))
          (downcase slug)))))
  (gpe/load-node-acts)
  :hook
  ((org-export-before-processing . gpe/insert-backlinks)
   (org-capture-mode . gpe/apply-capture-properties))
  :custom
  (org-roam-directory (file-truename "~/ems/org"))
  (org-roam-dailies-directory ".")

  (org-roam-db-extra-links-exclude-keys '((node-property "ROAM_REFS")))
  (org-roam-capture-templates
   (let ((files (directory-files "~/ems/org/src/gpe/org-roam-capture-templates/" t "\\.el$")))
     (mapcar (lambda (file)
               (with-temp-buffer
                 (insert-file-contents file)
                 (read (buffer-string))))
             files)))
  (org-roam-node-display-template
    "${title:40} || ${instantiates:20}")
  (org-publish-project-alist
   `(
     ("emsenn-net" :components ("emsenn-net-all"))
     ("emsenn-net-all"
      :base-directory "~/ems/org"
      :exclude ".*\\.org$"
      :include ,(gpe/org-roam-public-node-files)
      :publishing-function org-html-publish-to-html
      :preparation-function gpe/org-publish-prepare-backlinks
      :html-doctype "html5"
      :html-html5-fancy t
      :html-container "section"
      :headline-levels 6
      :recursive t
      :html-divs ((preamble "section" "preamble")
                  (content "main" "content")
                  (postamble "section" "postamble"))
      :html-head-include-scripts nil
      :html-head-include-default-style nil
      :html-head ,gpe/emsenn-net-head
      :html-format-drawer-function gpe/org-html-format-drawer
      :exclude "\\`per/\\|README.org\\|DRAFT\\|PRIVATE"
      :with-footnotes t
      :with-date nil
      :with-timestamps nil
      :with-author nil
      :publishing-directory "~/ems/pub/emsenn-net"
      :makeindex t
      :html-preamble ,gpe/emsenn-net-preamble
      )
     ))
  :bind (
         ("C-c n i" . org-roam-node-insert)
         ("C-c n f" . org-roam-node-find)
         ("C-c n c" . org-roam-node-capture)
         ("C-c n d" . org-roam-dailies-capture-today)
         ("C-c n D" . org-roam-dailies-capture-yesterday)
         )

  )

Org-transclusion

(use-package
  org-transclusion :straight t
  :custom
  (org-transclusion-exclude-elements '(keyword property-drawer))
  :bind (
         ("C-c n t" . org-transclusion-mode)
         ("C-c n T" . org-transclusion-add)
         ))

Publishing

HTMLize

(use-package htmlize :straight t)

Interfaces

Magit

(use-package magit :straight t)

Org-Roam UI

(use-package org-roam-ui
  :straight t)

Learning

Org-drill

;;; Org-drill
(use-package
  org-drill :straight t
  :custom
  (org-drill-scope 'agenda))

Programming

Lua

(use-package lua-mode
:straight t
:mode ("\\.lua\\'" . lua-mode))

Eglot

(use-package eglot
  :straight t
  :commands (eglot eglot-ensure))

Fennel

(use-package fennel-mode
  :straight (:host sourcehut :repo "technomancy/fennel-mode")
  :mode ("\\.fnl\\'" . fennel-mode)
  :commands (fennel-mode fennel-repl)
  :init
  (setq inferior-lisp-program "fennel")
  (autoload 'fennel-proto-repl-minor-mode "fennel-proto-repl" nil t)
  (autoload 'antifennel-mode "antifennel" nil t)
  (with-eval-after-load 'org
    (require 'ob-fennel))
  :hook
  (fennel-mode . fennel-proto-repl-minor-mode)
  (fennel-mode . eglot-ensure)
  (lua-mode . antifennel-mode)
  :config
  (with-eval-after-load 'eglot
    (add-to-list 'eglot-server-programs
                 '(fennel-mode . ("fennel-ls")))))

Plans

SOMEDAY Fix GnoponEmacs requiring restart to see new public files for publishing

SOMEDAY Setup Macros

draft macro

SOMEDAY Setup SEO

SEO is a lot different these days, I want my pages to show up on things like Google Discover.

SOMEDAY Generate quote cards automatically

Supplements

Full Source

;  (setq debug-on-error t)
    (defvar straight-install-script-path
    "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el")

  (setq straight-repository-branch "develop")

  (defvar bootstrap-version)
  (let ((bootstrap-file
         (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
        (bootstrap-version 5))
    (unless (file-exists-p bootstrap-file)
      (with-current-buffer
      (url-retrieve-synchronously straight-install-script-path
       'silent 'inhibit-cookies)
        (goto-char (point-max))
        (eval-print-last-sexp)))
    (load bootstrap-file nil 'nomessage))
    (straight-use-package 'use-package)

    (setq user-mail-address "emsenn@emsenn.net")
  (setq ring-bell-function 'ignore)

  (setq make-backup-files nil)
  (setq inhibit-startup-message t)
  (setq inhibit-startup-screen t)
  (setq initial-scratch-message
        ";; LANDBACK")
  (menu-bar-mode -1)
  (tool-bar-mode -1)
  (show-paren-mode 1)
  (setq line-number-mode t)
  (setq column-number-mode t)
  (setq-default truncate-lines t)
  (setq-default line-spacing 1)
  (setq sentence-end-double-space nil)
  (global-visual-line-mode t)
  (setq echo-keystrokes 0.1)
  (setq fill-column 68)
  (setq mouse-wheel-scroll-amount '(1 ((shift) .1)))

  (use-package mixed-pitch
    :straight t
    :hook
    (text-mode . mixed-pitch-mode))
  (use-package modus-themes
    :straight t
    :config
    (load-theme 'modus-vivendi t))
  (use-package olivetti
  :straight t
  :hook
  (text-mode . olivetti-mode))
  (require 'ucs-normalize)
  (straight-use-package
   '(beancount :type git :host github
             :repo "beancount/beancount-mode"))
  (use-package
    yasnippet :straight t
    :hook ((text-mode
          prog-mode
          conf-mode
          snippet-mode)
         . yas-minor-mode-on)
    :custom (yas-snippet-dirs '("~/ems/org/met/yas-snippets")))
  (use-package
    org :straight t
    :custom
    (org-directory "~/ems/org")
    (org-startup-folded 'fold)
    (org-hide-block-startup 'hideblocks)
    (org-catch-invisible-edits 'show-and-error)
    (org-agenda-custom-commands
        '(("A" "Agenda and TODO"
           ((agenda "" )
            (alltodo "" )))))
    (org-agenda-todo-ignore-scheduled 'all)
    (org-export-with-section-numbers nil)
    (org-export-with-smart-quotes nil)
    (org-cite-export-processors
      '((latex biblatex)
        (html csl)
        (odt csl)
        (ascii csl)
        (md csl)))
    (org-export-with-toc nil)
    (org-html-htmlize-output-type 'nil)
    (org-html-validation-link nil)
    (org-log-done 'time)
    (org-log-into-drawer 'LOGBOOK)
    (org-list-allow-alphabetical t)
    (org-image-actual-width '(400))
    (org-cite-global-bibliography '("~/ems/org/ref/bibliography.bib"))
    (org-export-global-macros
     '(
       ("nl" . "(eval \"\\n\")")
       ))
    :bind (
         ("C-c l" . org-store-link)
         ("C-c a" . org-agenda)
         ("C-c c" . org-capture)
         ("C-c t" . org-toggle-link-display)
         ("C-c C-q" . counsel-org-tag)
         )
    :defines gpe/emsenn-net-head
    :config

          ;; from https://www.john2x.com/blog/blogging-with-orgmode.html
          (defun gpe/org-publish-format-sitemap (title sitemap)
          (let ((posts (cdr sitemap)))
            (concat
             (format "#+title: %s\n" title)
             "#+options: timestamp:nil date:nil\n"
             (format "#+date: %s\n" (format-time-string "[%Y-%m-%d %a %H:%M:%S]" (current-time)))
             (org-list-to-org (cons (car sitemap) posts)))))
        (setq gpe/emsenn-net-head
              (with-temp-buffer
                (insert "<style>\n")
                (insert-file-contents "~/ems/org/src/emsenn-net/main.css")
                (goto-char (point-max)) ;; move to end before appending
                (insert "\n</style>")
                (buffer-string)))
        (setq gpe/emsenn-net-preamble
              (with-temp-buffer
                (insert-file-contents "~/ems/org/src/emsenn-net/preamble.html")
                (buffer-string)))
    (org-babel-do-load-languages 'org-babel-load-languages
                               '(
                                 (shell . t)
                                 )))
  (use-package citeproc :straight t)
  (use-package
    org-roam :straight t
    :after org
    :config
    (cl-defmethod org-roam-node-instantiates ((node org-roam-node))
      (let ((val (cdr (assoc "INSTANTIATES" (org-roam-node-properties node)))))
        (when (stringp val)
          (substring val 43 -2))))
  (defun gpe/get-node-properties (node)
    (nth 9 node))
  (defun gpe/get-node-property (node prop)
    (cdr (assoc prop (get-node-properties node))))p
    (defun gpe/load-node-acts ()
      (interactive)
      (dolist (file (directory-files "~/ems/org/src/gpe/node-acts/"
                                     t "\\.el$"))
        (let* ((name (file-name-base file))
               (sym  (intern name))
               (nsym (intern (format "gpe/node/%s" name))))
          (load-file file)
          (when (fboundp sym)
            (defalias nsym sym)))))
    (defun gpe/insert-backlinks (backend)
      (when (org-export-derived-backend-p backend 'html)
        (let ((node (org-roam-node-at-point)))
          (when node
            (save-excursion
              (goto-char (point-max))
              (insert "\n* Backlinks\n")
              (dolist (ref (org-roam-backlinks-get node))
                (let* ((source (org-roam-backlink-source-node ref))
                       (props (org-roam-node-properties source))
                       (is-public (string= (cdr (assoc "PUBLIC" props)) "true")))
                  (when is-public
                    (insert (format "- [[id:%s][%s]]\n"
                                    (org-roam-node-id source)
                                    (org-roam-node-title source)))))))))))
    (defun gpe/org-roam-public-nodes ()
      (org-roam-db-query
       [:select
        [*] :from nodes
        :where (like properties '"%public%true%")]))
    (defun gpe/org-roam-public-node-files ()
        (mapcar #'cadr
              (gpe/org-roam-public-nodes)))
    (defun gpe/bibtex-collect-entries ()
      (let ((results ""))
        (dolist (nodes (org-roam-db-query [:select [*] :from nodes]))
          (let ((file (nth 1 nodes)))
            (when (file-exists-p file)
              (with-temp-buffer
                (insert-file-contents file)
                (org-mode)
                (org-babel-map-src-blocks nil
                  (when (and (string= lang "bibtex")
                             (let* ((info (org-babel-get-src-block-info 'light))
                                    (params (nth 2 info)))
                               (string= (alist-get :canonical params) "yes")))
                    (setq results (concat results body "\n\n"))))))))
        results))
    (defun gpe/bibtex-generate-bibliography ()
      (interactive)
      (let* ((entries (gpe/bibtex-collect-entries))
             (outfile (car org-cite-global-bibliography)))
        (unless outfile
          (user-error "No file in `org-cite-global-bibliography`"))
        (with-temp-file outfile
          (insert entries))
        (message "Wrote bibliography to %s" outfile)))
    (defun gpe/bibtex-render-global-bibliography ()
      (let* ((bib (car org-cite-global-bibliography))
             (all-keys (with-temp-buffer
                         (insert-file-contents bib)
                         (bibtex-mode)
                         (goto-char (point-min))
                         (let (keys)
                           (while (re-search-forward "@\\w+{\\([^,]+\\)," nil t)
                             (push (match-string 1) keys))
                           (nreverse keys)))))
        (concat
         (mapconcat (lambda (k) (format "[cite:@%s]" k)) all-keys " ")
         "\n\n#+print_bibliography:\n")))
    (defun gpe/org-roam-open-random-node ()
      "Open a random Org-roam node from the database."
      (interactive)
      (let* ((nodes (org-roam-node-list))
           (count (length nodes)))
        (if (zerop count)
          (message "No Org-roam nodes found.")
        (let* ((random-index (random count))
               (node (nth random-index nodes)))
          (org-roam-node-visit node)))))
    (defun gpe/apply-capture-properties ()
      (let ((properties '(:author :form)))
        (dolist (property properties)
        (let ((value (plist-get org-capture-current-plist property)))
          (when value
            (org-set-property (substring (symbol-name property) 1) value))))))
    (cl-defmethod org-roam-node-slug ((node org-roam-node))
      "Return the slug of NODE."
      (let ((title (org-roam-node-title node))
          (slug-trim-chars '(;; Combining Diacritical Marks https://www.unicode.org/charts/PDF/U0300.pdf
                               768 ; U+0300 COMBINING GRAVE ACCENT
                               769 ; U+0301 COMBINING ACUTE ACCENT
                               770 ; U+0302 COMBINING CIRCUMFLEX ACCENT
                               771 ; U+0303 COMBINING TILDE
                               772 ; U+0304 COMBINING MACRON
                               774 ; U+0306 COMBINING BREVE
                               775 ; U+0307 COMBINING DOT ABOVE
                               776 ; U+0308 COMBINING DIAERESIS
                               777 ; U+0309 COMBINING HOOK ABOVE
                               778 ; U+030A COMBINING RING ABOVE
                               780 ; U+030C COMBINING CARON
                               795 ; U+031B COMBINING HORN
                               803 ; U+0323 COMBINING DOT BELOW
                               804 ; U+0324 COMBINING DIAERESIS BELOW
                               805 ; U+0325 COMBINING RING BELOW
                               807 ; U+0327 COMBINING CEDILLA
                               813 ; U+032D COMBINING CIRCUMFLEX ACCENT BELOW
                               814 ; U+032E COMBINING BREVE BELOW
                               816 ; U+0330 COMBINING TILDE BELOW
                               817 ; U+0331 COMBINING MACRON BELOW
                               )))
        (cl-flet* ((nonspacing-mark-p (char)
                     (memq char slug-trim-chars))
                   (strip-nonspacing-marks (s)
                     (ucs-normalize-NFC-string
                    (apply #'string (seq-remove #'nonspacing-mark-p
                                                  (ucs-normalize-NFD-string s)))))
                   (cl-replace (title pair)
                     (replace-regexp-in-string (car pair) (cdr pair) title)))
          (let* ((pairs `(("[^[:alnum:][:digit:]]" . "-") ;; convert anything not alphanumeric
                          ("--*" . "-")                   ;; remove sequential underscores
                          ("^-" . "")                     ;; remove starting underscore
                          ("-$" . "")))                   ;; remove ending underscore
                 (slug (-reduce-from #'cl-replace (strip-nonspacing-marks title) pairs)))
          (downcase slug)))))
    (gpe/load-node-acts)
    :hook
    ((org-export-before-processing . gpe/insert-backlinks)
     (org-capture-mode . gpe/apply-capture-properties))
    :custom
    (org-roam-directory (file-truename "~/ems/org"))
    (org-roam-dailies-directory ".")

    (org-roam-db-extra-links-exclude-keys '((node-property "ROAM_REFS")))
    (org-roam-capture-templates
     (let ((files (directory-files "~/ems/org/src/gpe/org-roam-capture-templates/" t "\\.el$")))
       (mapcar (lambda (file)
                 (with-temp-buffer
                   (insert-file-contents file)
                   (read (buffer-string))))
               files)))
    (org-roam-node-display-template
      "${title:40} || ${instantiates:20}")
    (org-publish-project-alist
     `(
       ("emsenn-net" :components ("emsenn-net-all"))
       ("emsenn-net-all"
        :base-directory "~/ems/org"
        :exclude ".*\\.org$"
        :include ,(gpe/org-roam-public-node-files)
        :publishing-function org-html-publish-to-html
        :preparation-function gpe/org-publish-prepare-backlinks
        :html-doctype "html5"
        :html-html5-fancy t
        :html-container "section"
        :headline-levels 6
        :recursive t
        :html-divs ((preamble "section" "preamble")
                  (content "main" "content")
                  (postamble "section" "postamble"))
        :html-head-include-scripts nil
        :html-head-include-default-style nil
        :html-head ,gpe/emsenn-net-head
        :html-format-drawer-function gpe/org-html-format-drawer
        :exclude "\\`per/\\|README.org\\|DRAFT\\|PRIVATE"
        :with-footnotes t
        :with-date nil
        :with-timestamps nil
        :with-author nil
        :publishing-directory "~/ems/pub/emsenn-net"
        :makeindex t
        :html-preamble ,gpe/emsenn-net-preamble
        )
       ))
    :bind (
         ("C-c n i" . org-roam-node-insert)
         ("C-c n f" . org-roam-node-find)
         ("C-c n c" . org-roam-node-capture)
         ("C-c n d" . org-roam-dailies-capture-today)
         ("C-c n D" . org-roam-dailies-capture-yesterday)
         )

    )
  (use-package
    org-transclusion :straight t
    :custom
    (org-transclusion-exclude-elements '(keyword property-drawer))
    :bind (
         ("C-c n t" . org-transclusion-mode)
         ("C-c n T" . org-transclusion-add)
         ))
  (use-package htmlize :straight t)
  (use-package magit :straight t)
  (use-package org-roam-ui
    :straight t)
  ;;; Org-drill
  (use-package
    org-drill :straight t
    :custom
    (org-drill-scope 'agenda))
(use-package lua-mode
:straight t
:mode ("\\.lua\\'" . lua-mode))
(use-package eglot
  :straight t
  :commands (eglot eglot-ensure))
(use-package fennel-mode
  :straight (:host sourcehut :repo "technomancy/fennel-mode")
  :mode ("\\.fnl\\'" . fennel-mode)
  :commands (fennel-mode fennel-repl)
  :init
  (setq inferior-lisp-program "fennel")
  (autoload 'fennel-proto-repl-minor-mode "fennel-proto-repl" nil t)
  (autoload 'antifennel-mode "antifennel" nil t)
  (with-eval-after-load 'org
    (require 'ob-fennel))
  :hook
  (fennel-mode . fennel-proto-repl-minor-mode)
  (fennel-mode . eglot-ensure)
  (lua-mode . antifennel-mode)
  :config
  (with-eval-after-load 'eglot
    (add-to-list 'eglot-server-programs
                 '(fennel-mode . ("fennel-ls")))))
(use-package gnuplot :straight t)

Backlinks

Created: 2025-10-02 Thu 09:44