Fix docker pull command's if logic
[kiwix.el.git] / org-kiwix.el
blob173d4f6ab1b8b6c7c698d75afb42965466c4e7c5
1 ;;; org-kiwix.el --- Org Mode link support -*- lexical-binding: t; -*-
3 ;;; Time-stamp: <2020-12-29 17:50:34 stardiviner>
5 ;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
7 ;; This file is part of GNU Emacs.
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
22 ;;; Commentary:
24 ;; Support Org-mode
26 ;; - [[wikipedia:(library):query]]
27 ;; - [[wikipedia:query]]
29 ;; links:
30 ;; - wikipedia:(zh):%E7%A6%85%E5%AE%97
31 ;; - wikipedia:(en):linux
32 ;; - wikipedia:linux
34 ;; - parameter `link' will be (en):linux" or linux".
36 ;; elisp regexp: "\\(?:(\\(.*\\)):\\)?\\([^] \n\t\r]*\\)"
37 ;; - non capturing group (\(?:...\)) for optional library
38 ;; - group 1: library (en or zh)
39 ;; - group 2: link? (match everything but ], space, tab, carriage return, linefeed by using [^] \n\t\r]*)
40 ;; for open wiki search query with local application database.
42 ;; Usage:
44 ;; (add-hook 'org-load-hook #'org-kiwix-setup-link)
46 ;;; Code:
48 (require 'kiwix)
50 (autoload 'org-link-set-parameters "org")
51 (autoload 'org-store-link-props "org")
53 (defun chinese-string-p (string)
54 "Return t if STRING is a Chinese string."
55 (if (string-match (format "\\cC\\{%s\\}" (length string)) string)
57 nil))
59 (defun kiwix-org-get-library (link)
60 "Get library from Org-mode `LINK'."
61 (let ((library (catch 'args-out-of-range
62 (when (string-match "(\\([^)].*\\)):\\(.*\\)" link)
63 (match-string 1 link)))))
64 (or library
65 (cond
66 ((chinese-string-p link)
67 (kiwix-select-library "zh"))
68 ((string-match-p "[a-zA-Z\ ]+" link)
69 ;; convert between libraries full name and abbrev.
70 (kiwix-select-library "en"))
71 (t (kiwix-select-library))))))
73 (defun org-wikipedia-open-link (link)
74 "Open LINK in external Wikipedia program."
75 ;; The regexp: (library):query
76 ;; - query : should not exclude space
77 ;; match link spec: "(library):query" with regexp "([^).]*):?:.*"
78 ;; (string-match "\\(?:(\\(.*\\)):\\)?\\([^]\n\t\r]*\\)" link)
79 (string-match "(\\([^)].*\\)):\\(.*\\)" link)
80 (let* ((library (kiwix-org-get-library link))
81 (query (cond
82 ((chinese-string-p link) link)
83 ((string-match-p "(\\([^)].*\\)):\\(.*\\)" link)
84 (match-string 2 link))
85 (t link)))
86 (url (concat
87 kiwix-server-url
88 "/" library "/A/"
89 ;; query need to be convert to URL encoding: "禅宗" https://zh.wikipedia.org/wiki/%E7%A6%85%E5%AE%97
90 (url-encode-url
91 ;; convert space to underline: "Beta distribution" "Beta_distribution"
92 (replace-regexp-in-string
93 " " "_"
94 ;; only capitalize the first word. like: "meta-circular interpreter" -> "Meta-circular interpreter"
95 (kiwix-capitalize-first query)
96 nil nil))
97 ".html")))
98 ;; (prin1 (format "library: %s, query: %s, url: %s" library query url))
99 (browse-url url)))
101 (defun org-wikipedia-export-link (link description format)
102 "Export the Wikipedia LINK with DESCRIPTION for FORMAT from Org files."
103 (when (string-match "\\(?:(\\(.*\\)):\\)?\\([^] \n\t\r]*\\)" link)
104 (let* ((library (kiwix-org-get-library link))
105 (query (url-encode-url (or (match-string 2 link) description)))
106 ;; "http://en.wikipedia.org/wiki/Linux"
107 ;; --
108 ;; ^- library: en, zh
109 (path (concat "http://" library ".wikipedia.org/wiki/" query))
110 (desc (or (match-string 2 link) description)))
111 (when (stringp path)
112 (cond
113 ((eq format 'html) (format "<a href=\"%s\">%s</a>" path desc))
114 ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
115 (t path))))))
117 (defun org-wikipedia-store-link ()
118 "Store a link to a Wikipedia link."
119 ;; [C-c o C-l l] `org-store-link'
120 ;; remove those interactive functions. use normal function instead.
121 (when (eq major-mode 'wiki-mode)
122 (let* ((query (read-string "Wikipedia Query with Kiwix: "))
123 (library (kiwix-select-library))
124 (link (concat "wikipedia:" "(" library "):" query)))
125 (org-store-link-props :type "wikipedia"
126 :link link
127 :description query)
128 link)))
130 (defun org-wikipedia-complete-link (&optional arg)
131 "Use kiwix AJAX request to provide available completion keywords."
132 (let* ((query (or arg (read-from-minibuffer "Search keyword: ")))
133 (library (kiwix-select-library))
134 (keywords (kiwix-ajax-search-hints query library)))
135 (concat "wikipedia:"
136 "(" library "):"
137 (completing-read "Available keywords: " keywords))))
139 ;;;###autoload
140 (defun org-kiwix-setup-link ()
141 "Setup Org link for org-kiwix."
142 (org-link-set-parameters "wikipedia" ; NOTE: use `wikipedia' for future backend changing.
143 :follow #'org-wikipedia-open-link
144 :store #'org-wikipedia-store-link
145 :export #'org-wikipedia-export-link
146 :complete #'org-wikipedia-complete-link)
147 (add-hook 'org-store-link-functions 'org-wikipedia-store-link))
151 (provide 'org-kiwix)
153 ;;; org-kiwix.el ends here