From 8d612cb1905ab3d989ab795e08495d9c716fb007 Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Sun, 9 Jul 2023 17:17:41 +1000 Subject: Implement wikilink following --- wiki-engine.el | 25 +++++++++++++------------ wiki-markup.el | 15 ++++++++++++--- wiki-utils.el | 18 +++++++++++++----- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/wiki-engine.el b/wiki-engine.el index a2fcaef..a9f65d5 100644 --- a/wiki-engine.el +++ b/wiki-engine.el @@ -25,22 +25,23 @@ ;; client to wiki engines, wiki server software. ;;; Code: -(require 'wiki-markup) +(require 'wiki-utils) -(defvar-local wiki-engine-host "https://en.wikipedia.org" - "The host of the current wiki engine instance.") +(defun wiki-make-wikilink-url (title)) -(defvar-local wiki-engine-path "/wiki/" - "The path to the current wiki engine instance.") - -(defun wiki-engine-mediawiki-fetch (title) - (interactive "sFetch wiki title: ") +(defun wiki-engine-mediawiki-fetch (base-url title fetcher) + "Fetch a mediawiki entry describing TITLE." (wiki-fetch-url - (format "%s%s%s?action=raw" - wiki-engine-host wiki-engine-path title)) - (wiki-mode)) - + (format "%s%s?action=raw" base-url title) + (lambda () + (wiki-mode) + (setq-local wiki-fetcher fetcher) + ))) +(defun wiki-wikipedia-fetch (title) + (interactive "sFetch wiki title: ") + (wiki-engine-mediawiki-fetch "https://en.wikipedia.org/wiki/" title + 'wiki-wikipedia-fetch)) (provide 'wiki-engine) ;;; wiki-engine.el ends here diff --git a/wiki-markup.el b/wiki-markup.el index 0675c44..4a74974 100644 --- a/wiki-markup.el +++ b/wiki-markup.el @@ -68,8 +68,14 @@ (defvar wiki-outline-regexp "=+.*=+\ *$") +(defvar-local wiki-fetcher nil + "Buffer-local function to fetch a wiki title") +(defun wiki-follow-wikilink-action (data) + "Button action to follow a wikilink" + (funcall wiki-fetcher (alist-get 'title data))) + (defun wiki-outline-level () - (when (looking-at "\\(=+\\).*\\(=+\\)\ *$") + (when (looking-at "\\(=+\\).*[^=]\\(=+\\)\\ *$") (min (length (match-string 1)) (length (match-string 2)) 6))) @@ -83,9 +89,13 @@ (end (match-end 0)) (visible-start (or (match-beginning 2) (match-beginning 1))) (visible-end (or (match-end 2) (match-end 1))) + (title (buffer-substring-no-properties (match-beginning 1) + (match-end 1))) ) (put-text-property start visible-start 'invisible t) - (put-text-property start end 'font-lock-face 'wiki-link) + (make-text-button start end + 'action 'wiki-follow-wikilink-action + 'button-data `((title . ,title))) (put-text-property visible-end end 'invisible t) (add-text-properties (1- visible-start) visible-start '(rear-nonsticky (invisible))) @@ -105,7 +115,6 @@ (setq-local comment-start "") - ;; FIXME: this should not be necessary in outline mode (setq-local font-lock-defaults '(wiki-font-lock-keywords t diff --git a/wiki-utils.el b/wiki-utils.el index 80680b7..53b7bd0 100644 --- a/wiki-utils.el +++ b/wiki-utils.el @@ -25,14 +25,21 @@ ;; wiki utility functions. ;;; Code: +(require 'url-parse) + (defvar wiki-download-dir "~/Downloads") -(defun wiki-fetch-url (url) - "Fetch url and returns the buffer." +(defun wiki-fetch-url (url &optional callback) + "Fetch URL asynchronously. + +Then calls CALLBACK which is a closure taking no argument." (interactive "sURL: ") (let ((file-name (expand-file-name (wiki-make-file-name-from-url url) - wiki-download-dir))) - (url-retrieve url 'wiki-fetch-url-save-and-switch (list file-name))) + wiki-download-dir)) + (cb (lambda (status file-name) + (wiki-fetch-url-save-and-switch status file-name) + (when callback (funcall callback))))) + (url-retrieve url cb (list file-name))) ) (defun wiki-fetch-url-save-and-switch (status file-name) @@ -41,7 +48,8 @@ (write-file file-name) (let ((coding-system-for-read 'utf-8)) (revert-buffer t t)) - (switch-to-buffer (current-buffer)))) + (switch-to-buffer (current-buffer)) + )) (defun wiki-delete-http-header () (delete-region (point-min) (progn (wiki-skip-http-header) (point)))) -- cgit v1.2.3