Replace `sideline` with `post-command-hook` and displaying with posframe
[org-tag-eldoc.git] / org-tag-eldoc-moegirl.el
blob2879c8fb916146da4132712741e2f61e5483eea0
1 ;;; org-tag-eldoc-moegirl.el --- org-tag-eldoc backend with moegril.org.cn -*- lexical-binding: t; -*-
2 ;; -*- coding: utf-8 -*-
4 ;; Copyright (C) 2024-2025 Christopher M. Miles, all rights reserved.
6 ;;; Commentary:
8 ;;; Code:
9 \f
10 (require 'url)
11 (require 'url-http) ; for `url-http-end-of-headers'
12 (require 'request)
13 (require 'dom)
14 (require 'elquery nil t) ; optionally use elquery.el to replace dom.el.
15 (require 'org-tag-eldoc-common)
18 (defvar org-tag-eldoc-moegirl-url nil
19 "A variable to store the url of moegirl.")
21 (defun org-tag-eldoc-moegirl--request (tag)
22 "Send HTTP GET request to get TAG explanation data."
23 (let ((request-backend 'url-retrieve) ; use `url-retrieve' backend for proxy.
24 (request-message-level -1)
25 (url-proxy-services org-tag-eldoc-request-proxy)
26 (url (format "https://zh.moegirl.org.cn/%s" (url-hexify-string tag))))
27 (request url
28 :type "GET"
29 :parser (lambda ()
30 (cond
31 ((fboundp 'libxml-parse-html-region) ; convert HTML -> Elisp alist structure
32 (libxml-parse-html-region (point-min) (point-max)))
33 ((featurep 'elquery) ; convert HTML -> elquery object structure
34 (elquery-read-buffer (current-buffer)))))
35 :success (cl-function
36 (lambda (&key data &allow-other-keys)
37 ;; DEBUG: (setq request-result data)
38 (cond
39 ((featurep 'dom)
40 ;; for `libxml' parser
41 (setq org-tag-eldoc--explanation
42 (org-tag-eldoc-common--format-explanation
43 (dom-texts
44 ;; FIXME: The content text is dynamically loaded by JavaScript.
45 (dom-search (dom-by-id data "mw-content-text")
46 (lambda (node) (and (eq (cl-first node) 'p) (null (cl-second node)))))))))
47 ((featurep 'elquery)
48 ;; for `elquery' parser
49 (setq org-tag-eldoc--explanation
50 (elquery-text (car (elquery-$ "#mw-content-text > div > p" data))))))))
51 :error (cl-function
52 (lambda (&rest args &key error-thrown &allow-other-keys)
53 ;; (message "[org-tag-eldoc] (萌娘百科) request error %s!" error-thrown)
54 nil))
55 :status-code '((404 . (lambda (&rest _) nil))
56 (500 . (lambda (&rest _) nil))))
58 ;; (with-current-buffer (url-retrieve-synchronously url)
59 ;; (let ((dom (progn
60 ;; (goto-char url-http-end-of-headers)
61 ;; (libxml-parse-html-region (point) (point-max)))))
62 ;; ;; DEBUG:
63 ;; (setq request-result dom)
64 ;; (org-tag-eldoc-common--format-explanation
65 ;; (cond
66 ;; ((featurep 'dom)
67 ;; (dom-texts
68 ;; ;; FIXME: The content text is dynamically loaded by JavaScript.
69 ;; (dom-search (dom-by-id dom "mw-content-text")
70 ;; (lambda (node) (and (eq (cl-first node) 'p) (null (cl-second node)))))))
71 ;; ((featurep 'elquery)
72 ;; (elquery-text (car (elquery-$ "#mw-content-text > div > p" data))))))))
75 ;;; TEST:
76 ;;; search tag: https://zh.moegirl.org.cn/index.php?search=linux
77 ;;; tag page: https://zh.moegirl.org.cn/Linux娘, https://zh.moegirl.org.cn/Linux%E5%A8%98
78 ;; (org-tag-eldoc-moegirl--request "Linux娘")
80 ;;; TEST
81 ;; (dom-texts
82 ;; (dom-search (dom-by-id request-result "mw-content-text")
83 ;; (lambda (node) (and (eq (car node) 'p) (null (cl-second node))))))
86 (defun org-tag-eldoc-moegirl-query (tag)
87 "Query TAG on moegirl.org.cn then return a cons cell of tag and explanation."
88 (if (stringp org-tag-eldoc--explanation)
89 org-tag-eldoc--explanation
90 (org-tag-eldoc-moegirl--request tag)
91 (sit-for 1.0)
92 (org-tag-eldoc-database-save tag org-tag-eldoc--explanation)))
96 (provide 'org-tag-eldoc-moegirl)
98 ;;; org-tag-eldoc-moegirl.el ends here