;;; wiki-engine.el -- client to wiki engines -*- lexical-binding: t -*- ;; Copyright (C) 2023 Free Software Foundation, Inc. ;; Author: Yuchen Pei ;; 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: ;; client to wiki engines, wiki server software. Each engine defines ;; how emacs interacts with the remote server, including how to ;; construct a url to fetch from. ;;; Code: (require 'wiki-utils) (require 'wiki-markup) (defun wiki-engine-html-url (site title) "Return the url of the html webpage of TITLE on SITE." (format "%s%s" (plist-get (alist-get site wiki-sites) :base-url) title)) (defun wiki-current-html-url () "Return the url of the html webpage of the current wiki buffer." (unless (and wiki-site wiki-title) (error "Nil wiki-site or wiki-title!")) (wiki-engine-html-url wiki-site wiki-title)) (defun wiki-engine-mediawiki-fetch (wiki-site title) "Fetch a mediawiki entry describing TITLE. The site handle is passed as a symbol WIKI-SITE." (let ((wiki-site-info (alist-get wiki-site wiki-sites))) (cl-assert (eq (plist-get wiki-site-info :engine) 'mediawiki)) (when (string-empty-p title) (setq title "Main Page")) (unless (and wiki-fetch-prefer-local (wiki-find-file title (wiki-locate-dir wiki-site))) (wiki-fetch-url (format "%s%s?action=raw" (plist-get wiki-site-info :base-url) title) (wiki-locate-dir wiki-site) (lambda () (wiki-mode) (setq-local wiki-site wiki-site wiki-title title) ) )))) (defun wiki-engine-oddmuse-fetch (wiki-site title) (let ((wiki-site-info (alist-get wiki-site wiki-sites))) (cl-assert (eq (plist-get wiki-site-info :engine) 'oddmuse)) (unless (and wiki-fetch-prefer-local (wiki-find-file title (wiki-locate-dir wiki-site))) (wiki-fetch-url (format "%s?action=download;id=%s" (plist-get wiki-site-info :base-url) title) (wiki-locate-dir wiki-site) (lambda () (wiki-mode) (setq-local wiki-site wiki-site wiki-title title) ) title)))) (defun wiki-engine-moinmoin-fetch (wiki-site title) (let ((wiki-site-info (alist-get wiki-site wiki-sites))) (cl-assert (eq (plist-get wiki-site-info :engine) 'moinmoin)) (unless (and wiki-fetch-prefer-local (wiki-find-file title (wiki-locate-dir wiki-site))) (wiki-fetch-url (format "%s%s?action=raw" (plist-get wiki-site-info :base-url) title) (wiki-locate-dir wiki-site) (lambda () (wiki-mode) (setq-local wiki-site wiki-site wiki-title title) ) title)))) (defun wiki-locate-dir (wiki-site) "Locate the directory for a WIKI-SITE." (expand-file-name (format "%s" wiki-site) wiki-local-dir)) (defun wiki-find-file (title &optional dir create-if-not-exists extension) "Find local TITLE in DIR. Returns the file-name if success, and nil otherwise. If CREATE-IF-NOT-EXISTS is non-nil, creates the file is not found. DIR defaults to `default-directory'." (interactive (list (read-file-name "Find wiki file: "))) (unless dir (setq dir default-directory)) (let ((file-name (expand-file-name (if extension (file-name-extension title extension) title) dir))) (when (or (file-exists-p file-name) create-if-not-exists) (find-file file-name) (wiki-mode) file-name))) (defalias #'wiki-local-fetch #'wiki-find-file) (defun wiki-engine-fetcher (wiki-site-info) (intern (format "wiki-engine-%s-fetch" (plist-get wiki-site-info :engine)))) (defmacro defun-wiki-fetchers () (cons 'progn (mapcar (lambda (pair) (pcase-let ((`(,id . ,info) pair)) `(defun ,(wiki-site-fetcher id) (title) (interactive ,(format "sFetch title for %s: " (plist-get info :display-name))) (,(wiki-engine-fetcher info) ',id title)))) (seq-filter #'cdr wiki-sites) ))) (defun-wiki-fetchers) (defun wiki-open-url (url) "Open the raw wiki corresponding to the URL of a html wiki page. If URL points to html title, open the corresponding raw title." (interactive "sURL: ") (when-let ((found-site (seq-find (lambda (site-pair) (when-let ((base-url (plist-get (cdr site-pair) :base-url))) (string-prefix-p base-url url))) wiki-sites))) (pcase-let ((`(,site-id . ,site-info) found-site)) (funcall (wiki-site-fetcher site-id) (string-remove-prefix (plist-get site-info :base-url) url)))) ) (provide 'wiki-engine) ;;; wiki-engine.el ends here