dotfiles/emacs-lisp/org_roam.org
Magic_RB 71dc54cb68
Embed SVGs when exporting Org-Roam
Signed-off-by: Magic_RB <magic_rb@redalder.org>
2023-02-10 00:33:23 +01:00

6 KiB

Org Roam

#

When exporting, running (org-id-update-id-locations (directory-files-recursively org-roam-directory ".org"))

(defun replace-in-string (what with in)
  (replace-regexp-in-string (regexp-quote what) with in nil 'literal))

(defun org-html--format-image (source attributes info)
  (progn
    (setq source (replace-in-string "%20" " " source))
    (format "<img src=\"data:image/%s+xml;base64,%s\"%s />"
            (or (file-name-extension source) "")
            (base64-encode-string
             (with-temp-buffer
               (insert-file-contents-literally source)
              (buffer-string)))
            (file-name-nondirectory source))))

Org-roam is a plain-text knowledge management system. It brings some of Roam's more powerful features into the Org-mode ecosystem.

SQLite3 must be on Emacs' PATH!

  (use-package org-roam
    :straight
    (org-roam
     :type git
     :host github
     :repo "org-roam/org-roam"
     :branch "main")
    :init
    (setq org-roam-v2-ack t)
    :config
    (add-hook 'after-init-hook 'org-roam-setup)

    ;; Add ignore for SyncThing
    (setq org-roam-file-exclude-regexp (regexp-opt '(".stversions" ".sync-conflict-" "logseq")))

    (setq org-roam-directory "~/roam")
    ;; Add more informative completion interface
    (setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:30}" 'face 'org-tag)))

    (defun magic_rb/org-roam-buffer-hook ()
      (when (org-roam-buffer-p)
        (make-local-variable 'org-link-frame-setup)
        (add-to-list 'org-link-frame-setup '(file . find-file))))
    (add-hook 'org-mode-hook 'magic_rb/org-roam-buffer-hook)

    (defun magic_rb/org-roam-hook ()
      (visual-line-mode))
    (add-hook 'org-roam-mode-hook 'magic_rb/org-roam-hook))

  (use-package shackle
    :straight t
    :init
    (shackle-mode))

  (setq shackle-rules
        '((org-roam-mode
           :align right
           :size 0.25
           :popup t)))

Ref Capture

Using org-protocol, one can capture a website from their browser directly into Org Roam.

  (with-eval-after-load "org-roam"
    (require 'org-roam-protocol)
    (setq org-roam-capture-ref-templates
          `(("r" "ref" plain "%?"
             :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n\n${body}")
             :unnarrowed t))))

Then you need a desktop entry for org-protocol. Such as:

  [Desktop Entry]
  Name=org-protocol
  Exec=emacsclient %u
  Type=Application
  Terminal=false
  Categories=System;
  MimeType=x-scheme-handler/org-protocol;

or in Nix form:

  makeDesktopItem {
    name = "Org-Protocol";
    exec = "emacsclient %u";
    comment = "Org protocol";
    desktopName = "org-protocol";
    type = "Application";
    mimeType = "x-scheme-handler/org-protocol";
  }

Lastly a bookmarklet in Firefox.

  javascript:location.href ='org-protocol://roam-ref?template=rw&ref=' + encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title) + '&body=' + encodeURIComponent(window.getSelection())

Export

  (require 'org-roam-export)

  (require 'nxml-mode)

  (defun magic_rb/org-html-publish-to-html-continue (plist filename pub-dir)
    (org-html-publish-to-html plist filename pub-dir))

  (defcustom org+-html-embed-svg nil
    "Embed SVG images.
    You can set this variable in Org files with
    ,#+HTML_EMBED_SVG: t
    or
    ,#+OPTIONS: html-embed-svg:t"
    :type 'boolean
    :group 'org-export-html)

  (cl-pushnew
   '(:html-embed-svg "HTML_EMBED_SVG" "html-embed-svg" org+-html-embed-svg)
   (org-export-backend-options (org-export-get-backend 'html)))

  (defun org+-html-svg-image-embed (fun source attributes info)
    "Make embedding of SVG images possible in org HTML export.
    SVG images are embedded if :html-embed-svg is non-nil in the plist INFO.
    Otherwise FUN called with SOURCE, ATTRIBUTES, and INFO as arguments.
    SOURCE is the file name of the SVG file.
    This is an around advice for `org-html--svg-image' as FUN."
    (if (and
         (member (plist-get info :html-embed-svg) '("yes" "t" t))
         (string-equal "svg" (file-name-extension source)))
        (with-temp-buffer
          (message "embedding svg: %s" source)
          (insert-file-contents source)
          (with-syntax-table nxml-mode-syntax-table
            (while (and (search-forward "<svg") ;; barfs if a "<svg" is not found in code
                        (nth 8 (syntax-ppss)))))
          (delete-region (point-min) (match-beginning 0))
          (buffer-string))
      (funcall fun (concat "../" source) attributes info)))

  (advice-add 'org-html--format-image :around #'org+-html-svg-image-embed)

  (setq org-publish-project-alist
        `(("org"
           :base-directory "~/roam/"
           :publishing-function org-html-publish-to-html ;; magic_rb/org-html-publish-to-html-continue
           :publishing-directory "~/roam/published"
           :exclude "^.*$"
           :include ,(seq-map #'car
                              (org-roam-db-query
                               [:select [nodes:file]
                                        :from tags
                                        :left-join nodes
                                        :on (= tags:node-id nodes:id)
                                        :where (like tag (quote "%\"public-publish\""))]))
           )))

  (org-publish "org" t)

https://emacs.stackexchange.com/questions/59149/why-is-latex-preview-and-latex-to-html-export-via-dvisvgm-not-working-in-org-mod