Improve the xkcd custom org link, add completion
This commit is contained in:
parent
cc68c303ac
commit
358051b0ee
109
config.org
109
config.org
|
@ -1914,39 +1914,124 @@ The radar chart is a lot more involved, and I've added the following keys
|
|||
This sets the number of ticks. Only works for \(n>2\), or \(n=0\) in which
|
||||
case no ticks are shown.
|
||||
**** Extra links
|
||||
Let's start off with an xkcd link, why not.
|
||||
Nice youtube embed as well, for fun.
|
||||
***** xkcd
|
||||
Because xkcd is cool, let's make it as easy and fun as possible to insert them.
|
||||
Saving seconds adds up after all! (but only so much)
|
||||
|
||||
[[xkcd:1205]]
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(after! org
|
||||
(org-link-set-parameters "xkcd"
|
||||
:image-data-fun #'+org-xkcd-image-fn
|
||||
:follow #'+org-xkcd-open-fn
|
||||
:export #'+org-xkcd-export)
|
||||
:export #'+org-xkcd-export
|
||||
:complete #'+org-xkcd-complete)
|
||||
|
||||
(defun +org-xkcd-open-fn (link)
|
||||
(+org-xkcd-image-fn nil link nil))
|
||||
|
||||
(defun +org-xkcd-fetch-info (num)
|
||||
"Fetch the parsed json info for comic NUM"
|
||||
(require 'xkcd)
|
||||
(let* ((url (format "http://xkcd.com/%d/info.0.json" num))
|
||||
(out (xkcd-get-json url num))
|
||||
(json-assoc (json-read-from-string out)))
|
||||
(json-assoc
|
||||
(if (assoc num +org-xkcd-stored-info)
|
||||
(assoc num +org-xkcd-stored-info)
|
||||
(json-read-from-string (xkcd-get-json url num)))))
|
||||
json-assoc))
|
||||
(defun +org-xkcd-image-fn (_protocol link _description)
|
||||
|
||||
(defvar +org-xkcd-latest-num 0
|
||||
"Latest xkcd number")
|
||||
|
||||
(defun +org-xkcd-complete (&optional arg)
|
||||
"Complete xkcd using `+org-xkcd-stored-info'"
|
||||
(+org-xkcd-update-stored-info)
|
||||
(concat "xkcd:" (let ((num
|
||||
(ivy-read (format "xkcd (%s): " +org-xkcd-latest-num)
|
||||
(mapcar (lambda (info-assoc)
|
||||
(format "%-4s %-30s %s"
|
||||
(propertize (number-to-string (car info-assoc))
|
||||
'face 'counsel-key-binding)
|
||||
(cdr (assoc 'title info-assoc))
|
||||
(propertize (cdr (assoc 'alt info-assoc))
|
||||
'face '(variable-pitch font-lock-comment-face))))
|
||||
+org-xkcd-stored-info))))
|
||||
(if (equal "" num) (number-to-string +org-xkcd-latest-num)
|
||||
(replace-regexp-in-string "\\([0-9]+\\).*" "\\1" num)))))
|
||||
|
||||
;; initialise `+org-xkcd-latest-num' and `+org-xkcd-stored-info' with latest xkcd
|
||||
(add-transient-hook! '+org-xkcd-complete
|
||||
(let* ((out (xkcd-get-json "http://xkcd.com/info.0.json" 0))
|
||||
(json-assoc (json-read-from-string out)))
|
||||
(setq +org-xkcd-latest-num (cdr (assoc 'num json-assoc)))
|
||||
(setq +org-xkcd-stored-info `((,+org-xkcd-latest-num . ,json-assoc)))))
|
||||
|
||||
(defvar +org-xkcd-stored-info nil
|
||||
"Basic info on downloaded xkcds, in the form ((num . title) ...)")
|
||||
|
||||
(defun +org-xkcd-update-stored-info ()
|
||||
"Compare the json files in `xkcd-cache-dir' to the info in `+org-xkcd-stored-info'
|
||||
and ensure that `+org-xkcd-stored-info' has info for every file"
|
||||
(let* ((file-nums (mapcar (lambda (f) (string-to-number (replace-regexp-in-string "\\.json" "" f)))
|
||||
(directory-files xkcd-cache-dir nil "\\.json")))
|
||||
(stored-nums (mapcar #'car +org-xkcd-stored-info))
|
||||
(new-nums (set-difference file-nums stored-nums)))
|
||||
(dolist (num new-nums)
|
||||
(let ((xkcd-info (+org-xkcd-fetch-info num)))
|
||||
(push `(,num . ,xkcd-info) +org-xkcd-stored-info)))))
|
||||
|
||||
(defadvice! xkcd-get-json--and-cache (url &optional num)
|
||||
"Fetch the Json coming from URL.
|
||||
If the file NUM.json exists, use it instead.
|
||||
If NUM is 0, always download from URL.
|
||||
The return value is a string."
|
||||
:override #'xkcd-get-json
|
||||
(let* ((file (format "%s%d.json" xkcd-cache-dir num))
|
||||
(cached (and (file-exists-p file) (not (eq num 0))))
|
||||
(out (with-current-buffer (if cached
|
||||
(find-file file)
|
||||
(url-retrieve-synchronously url))
|
||||
(goto-char (point-min))
|
||||
(unless cached (re-search-forward "^$"))
|
||||
(prog1
|
||||
(buffer-substring-no-properties (point) (point-max))
|
||||
(kill-buffer (current-buffer))))))
|
||||
(unless (or cached (eq num 0))
|
||||
(xkcd-cache-json num out))
|
||||
out))
|
||||
|
||||
(defun +org-xkcd-image-fn (protocol link description)
|
||||
"Get image data for xkcd num LINK"
|
||||
(let* ((json-assoc (+org-xkcd-fetch-info (string-to-number link)))
|
||||
(img (cdr (assoc 'img json-assoc)))
|
||||
(alt (cdr (assoc 'alt json-assoc))))
|
||||
(message alt)
|
||||
(+org-http-image-data-fn "https" (substring img 6) nil)))
|
||||
(+org-image-file-data-fn protocol (xkcd-download img (string-to-number link)) description)))
|
||||
|
||||
(defun +org-xkcd-export (path desc backend _com)
|
||||
"Convert xkcd to html/LaTeX form"
|
||||
(let* ((json-assoc (+org-xkcd-fetch-info (string-to-number path)))
|
||||
(img (cdr (assoc 'img json-assoc)))
|
||||
(alt (cdr (assoc 'alt json-assoc)))
|
||||
(title (cdr (assoc 'title json-assoc))))
|
||||
(title (cdr (assoc 'title json-assoc)))
|
||||
(file (xkcd-download img (string-to-number path))))
|
||||
(cond ((org-export-derived-backend-p backend 'html)
|
||||
(format "<img src='%s' title='%s' alt='%s'>" img alt title))
|
||||
(format "<img src='%s' title=\"%s\" alt='%s'>" img (subst-char-in-string ?\" ?“ alt) title))
|
||||
((org-export-derived-backend-p backend 'latex)
|
||||
(format "\\href{https://xkcd.com/%s}{%s}" path (or desc (concat "xkcd: " title))))
|
||||
(t (format "https://xkcd.com/%s" path)))))
|
||||
|
||||
(format "\\begin{figure}[!htb]
|
||||
\\centering
|
||||
\\includegraphics[scale=0.4]{%s}
|
||||
\\caption*{\\label{xkcd:%s} %s}
|
||||
\\end{figure}" file path (or desc
|
||||
(format "\\textbf{%s} %s" title alt))))
|
||||
(t (format "https://xkcd.com/%s" path))))))
|
||||
#+END_SRC
|
||||
***** YouTube
|
||||
The ~[[yt:...]]~ links preview nicely, but don't export nicely. Thankfully, we can
|
||||
fix that.
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(after! org
|
||||
(org-link-set-parameters "yt" :export #'+org-export-yt)
|
||||
(defun +org-export-yt (path desc backend _com)
|
||||
(cond ((org-export-derived-backend-p backend 'html)
|
||||
|
|
Loading…
Reference in a new issue