;;; wiki-utils.el -- wiki utility functions -*- lexical-binding: t -*- ;; Copyright (C) 2023 Free Software Foundation. ;; Author: Yuchen Pei ;; Package-Requires: ((emacs "28.2")) ;; This file is part of wiki.el. ;; wiki.el is free software: you can redistribute it and/or modify it under ;; the terms of the GNU Affero General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; wiki.el is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General ;; Public License for more details. ;; You should have received a copy of the GNU Affero General Public ;; License along with wiki.el. If not, see . ;;; Commentary: ;; wiki utility functions. ;;; Code: (require 'url-parse) (defvar wiki-local-dir (locate-user-emacs-file "wiki") "Path to local directory of wiki files.") (defvar wiki-fetch-prefer-local t "If non-nil, visit the local file if exists when instructed for fetching.") (defun wiki-fetch-url (url dir &optional callback title) "Fetch URL asynchronously. Then calls CALLBACK which is a closure taking no argument." (interactive "sURL: ") (let ((file-name (expand-file-name (or title (wiki-make-file-name-from-url url)) 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) (when (plist-get status :error) (error "Wiki fetch failed: %s" (plist-get status :error))) (wiki-delete-http-header) (let ((to-insert (buffer-string)) (buffer (find-file-noselect file-name)) (coding-system-for-write 'utf-8)) (kill-buffer) (with-current-buffer buffer (insert to-insert) (goto-char (point-min)) (save-buffer) (revert-buffer t t)) (switch-to-buffer buffer)) ) (defun wiki-delete-http-header () (delete-region (point-min) (progn (wiki-skip-http-header) (point)))) (defun wiki-skip-http-header () (goto-char (point-min)) (re-search-forward "\r?\n\r?\n")) (defun wiki-make-file-name-from-url (url) (file-name-nondirectory (directory-file-name (car (url-path-and-query (url-generic-parse-url (url-unhex-string url))))))) ;; TODO: add wikihow; generalise fandom ;; TODO: default engine to mediawiki (defvar wiki-sites '((local) (archwiki :base-url "https://wiki.archlinux.org/title/" :engine mediawiki :display-name "ArchWiki") (debian-wiki :base-url "https://wiki.debian.org/" :engine moinmoin :display-name "Debian Wiki") (emacswiki :base-url "https://www.emacswiki.org/emacs/" :engine oddmuse :display-name "EmacsWiki") (esp :base-url "https://wiki.endsoftwarepatents.org/wiki/" :engine mediawiki :display-name "ESP Wiki") (fandom-recipes :base-url "https://recipes.fandom.com/wiki/" :engine mediawiki :display-name "Fandom Recipes Wiki") (fsd :base-url "https://directory.fsf.org/wiki/" :engine mediawiki :display-name "Free Software Directory") (haskell-wiki :base-url "https://wiki.haskell.org/" :engine mediawiki :display-name "Haskell Wiki") (libreplanet :base-url "https://libreplanet.org/wiki/" :engine mediawiki :display-name "Libreplanet Wiki") (oddmuse :base-url "https://oddmuse.org/wiki/" :engine oddmuse :display-name "Oddmuse") (parabolawiki :base-url "https://wiki.parabola.nu/" :engine mediawiki :display-name "ParabolaWiki") (python-wiki :base-url "https://wiki.python.org/moin/" :engine moinmoin :display-name "Python Wiki") (termux-wiki :base-url "https://wiki.termux.com/wiki/" :engine mediawiki :display-name "Termux Wiki") (ubuntu-wiki :base-url "https://wiki.ubuntu.com/" :engine moinmoin :display-name "Ubuntu Wiki") (ubuntu-community-help-wiki :base-url "https://help.ubuntu.com/community/" :engine moinmoin :display-name "Ubuntu Community Help Wiki") (wikiindex :base-url "https://wikiindex.org/" :engine mediawiki :display-name "WikiIndex") (wikipedia-en :base-url "https://en.wikipedia.org/wiki/" :engine mediawiki :display-name "Wikipedia EN") (wikipedia-zh :base-url "https://zh.wikipedia.org/wiki/" :engine mediawiki :display-name "Wikipedia ZH") (wikivoyage-en :base-url "https://en.wikivoyage.org/wiki/" :engine mediawiki :display-name "Wikivoyage EN") (wiktionary-en :base-url "https://en.wiktionary.org/wiki/" :engine mediawiki :display-name "Wiktionary EN") ) "Alist of wiki sites. Each item is in the form of (identifier . properties), where identifier is a symbol, and properties is a plist of the site. One of the sites is (local), meaning a local filesystem.") (defun wiki-site-fetcher (wiki-site) (if wiki-site (intern (format "wiki-%s-fetch" wiki-site)) 'wiki-find-file)) (provide 'wiki-utils) ;;; wiki-utils.el ends here