helpful打开本地html手册

helpful可以一键打开Emacs自带的手册,但是自带的这个看起来没有网上的那个舒服。还有就是网上的那个elisp手册是最新发布版(26.3),但我平时都用最新的开发版(27.0),有时候网上的手册内容会过时。解决方法是让helpful一键打开本地的手册:

https://archive.casouri.cat/note/2020/view-local-html-manual-in-helpful/index.html

编译本地手册只需要

make -e HTML_OPTS="--html --css-ref=./manual.css" elisp.html

helpful魔改:

(defvar helpful-html-manual-dir "/Users/yuan/emacs/doc/lispref/elisp.html"
  "Absolute path to the directory where HTML manuals are.")

(define-minor-mode helpful-html-manual-mode
  "View HTML manuals in helpful."
  :lighter ""
  :global t
  (if helpful-html-manual-mode
      (advice-add #'helpful--manual :override #'helpful--html-manual)
    (advice-remove #'helpful--manual #'helpful--html-manual)))

(defun helpful--html-manual (button)
  "Open the HTML manual for the symbol that BUTTON represents."
  (let ((sym (symbol-name (button-get button 'symbol)))
        (index-file (expand-file-name "Index.html" helpful-html-manual-dir))
        manual-page)
    (with-temp-buffer
      (insert-file-contents index-file)
      (goto-char (point-min))
      (if (not (re-search-forward
                (format "<a href=\"\\(.*\\)\"><code>%s</code>" sym) nil t))
          (message "No manual index for %s" sym)
        (message "%s" (setq manual-page (expand-file-name
                                         (match-string 1) helpful-html-manual-dir)))
        (shell-command-to-string (format "open 'file://%s'" manual-page))))))

我用了mac的open打开手册词条链接,linux上不知道是啥。更多的看博客吧w

3赞

Emacs 在线手册连版本号都不分,贴个链接,说不定哪天内容就变了,甚至 404 了。几年前就吐槽过了, 但是 GNU 项目常教人望而生畏。

The TexInfo source is located under <emacs source>/etc/doc/lispref

<emacs source>/doc/lispref,没有 etc

用 browse-url 函数就 OK 了

mac上用 dash 可好?

改了,谢谢 :smile:

dash有Elisp吗,我都不知道。


我看到你的repo了,比本地的好用多了 :smile: ,已经改为用你的。 FYI gnu上的文档有三个css,我合成一个manual.css了。我还改了一点点,要不然看上去跟网上的不一样。不知道为啥本地生成的HTML和网上的有一点区别。

有的。dash.el 可以直达

1赞

折腾了半天,只生成 HTML 也需要先 ./autogen.sh && ./configure 生成 Makefile,而且不知为何 Emacs 25 的 ./autogen.sh 会报错,这个 repo 用 github action 生成的,早知道这么折腾就本地生成再上传了。

我用的 CSS 是就从你那边下载的

官方的好像是用

M-x load-file $EMACS_SRC/admin/admin.el
C-u M-x make-manuals $EMACS_SRC elisp-node

生成的,不知道是不是有关系。

我有配置把 Info Node 映射到 HTML的,比如把 (elisp) Lisp Data Types 映射到:

每次我贴这样的 Markdown 链接,如 (elisp) Lisp Data Types,都用的是它。

代码
(defvar chunyang-Info-html-alist
  '(
    ;; Special cases come first
    ("org"  . "http://orgmode.org/manual/%s")
    ("find" . "https://www.gnu.org/software/findutils/manual/html_node/find_html/%s")
    ("standards" . "https://www.gnu.org/prep/standards/html_node/%s")
    ("magit" . "https://magit.vc/manual/magit/%s")
    ("slime" . "https://www.common-lisp.net/project/slime/doc/html/%s")
    ("gawk" . "https://www.gnu.org/software/tar/manual/html_node/%s")
    ;; GNU info documents.  Taken from my memory or see https://www.gnu.org/software/
    (("awk" "sed" "tar" "make" "m4" "grep" "coreutils" "guile" "screen"
      "libc" "make" "gzip" "diffutils" "wget" "grub") .
      (lambda (software)
        (format "https://www.gnu.org/software/%s/manual/html_node/%%s" software)))
    ("gcc-5" . "https://gcc.gnu.org/onlinedocs/gcc/%s")
    (("gdb" "stabs") .
     (lambda (software)
       (format "https://sourceware.org/gdb/onlinedocs/%s/%%s" software)))
    ;; Emacs info documents.  Taken from `org-info-emacs-documents'
    (("ada-mode" "auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x"
      "ebrowse" "ede" "ediff" "edt" "efaq-w32" "efaq" "eieio" "eintr" "elisp"
      "emacs-gnutls" "emacs-mime" "emacs" "epa" "erc" "ert" "eshell" "eudc" "eww"
      "flymake" "forms" "gnus" "htmlfontify" "idlwave" "ido" "info" "mairix-el"
      "message" "mh-e" "newsticker" "nxml-mode" "octave-mode" "org" "pcl-cvs"
      "pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic" "ses" "sieve"
      "smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "url" "vip" "viper"
      "widget" "wisent" "woman") .
      (lambda (package)
        (format "https://www.gnu.org/software/emacs/manual/html_node/%s/%%s" package)))))

(defun chunyang-org-info-map-anchor-url (node)
  "Return URL associated to Info NODE."
  (require 'org) ; for `org-trim'
  ;; See (info "(texinfo) HTML Xref Node Name Expansion") for the
  ;; expansion rule
  (let* ((node (replace-regexp-in-string "[ \t\n\r]+" " " (org-trim node)))
         (node (mapconcat (lambda (c)
                            (if (string-match "[a-zA-Z0-9 ]" (string c))
                                (string c)
                              (format "_%04x" c)))
                          (string-to-list node) ""))
         (node (replace-regexp-in-string " " "-" node))
         (url (if (string= node "")
                  ""
                (if (string-match "[0-9]" (substring node 0 1))
                    (concat "g_t" node)
                  node))))
    url))

(defun chunyang-Info-get-current-node-html ()
  (cl-assert (eq major-mode 'Info-mode))
  (let* ((file (file-name-nondirectory Info-current-file))
         (node Info-current-node)
         (html (if (string= node "Top")
                   ""
                 (concat (chunyang-org-info-map-anchor-url node) ".html")))
         (baseurl (cl-loop for (k . v) in chunyang-Info-html-alist
                           when (cond ((stringp k) (equal file k))
                                      ((listp k) (member file k)))
                           return (if (stringp v) v (funcall v file)))))
    ;; Maybe it's a good idea to assuming GNU softwares in this case
    (cl-assert baseurl nil "Unsupported info document '%s'" file)
    (format baseurl html)))

(defun chunyang-Info-copy-current-node-html ()
  (interactive)
  (let ((url (chunyang-Info-get-current-node-html)))
    (kill-new url)
    (message "Copied: %s" url)))

(defun chunyang-Info-browse-current-node-html ()
  (interactive)
  (let ((url (chunyang-Info-get-current-node-html)))
    (browse-url url)))

(defun chunyang-Info-markdown-current-node-html (&optional arg)
  "ARG will be passed to `Info-copy-current-node-name'."
  (interactive "P")
  (let ((description (Info-copy-current-node-name arg))
        (link (chunyang-Info-get-current-node-html)))
    (let ((markdown (format "[%s](%s)" description link)))
      (kill-new markdown)
      (message "Copied: %s" markdown))))
1赞

可以放到 readthedocs 吗?

没用过 readthedocs ,它看起来不支持吧,Emacs 的手册是 texinfo 写的,现有的工具能输出到 info, html 和 pdf。

Fork了你的repo,加了点css符合我个人口味。我还加了个首页:github效果。理论上来说是可以自动生成的,不过不太清楚怎么用shell生成(sed?),用python elisp感觉太重了。

更新的代码

(defvar helpful-html-manual-base-url "https://archive.casouri.cat/emacs-manuals/master/elisp"
  "Base URL for the online manual. No trailing slash.")

(define-minor-mode helpful-html-manual-mode
  "View HTML manuals in helpful."
  :lighter ""
  :global t
  (if helpful-html-manual-mode
      (advice-add #'helpful--manual :override #'helpful--html-manual)
    (advice-remove #'helpful--manual #'helpful--html-manual)))

(defun helpful--html-manual (button)
  "Open the HTML manual for the symbol that this BUTTON represents."
  (let* ((sym (symbol-name (button-get button 'symbol)))
         (manual-file (format "%s.html" (capitalize sym))))
    (browse-url
     (format "%s/%s" helpful-html-manual-base-url manual-file))))

(with-eval-after-load 'helpful
  (helpful-html-manual-mode))

CSS:

2赞

找到问题了,checkout之后加入git clean -xf清除之前编译的产物就行了。25.3到24.4都没问题。24.3莫名没有引入CSS。可能是那时候的makefile还不支持HTML_OPTS这个变量。

你这个好,版本比较全,Emacs 其实还有不少其他的自带手册,比如 cl-lib、url,能加上就更好了。

这个页面 https://archive.casouri.cat/emacs-manuals/master/elisp/JSONRPC.html#JSONRPC 表格被截断了,应该是这个导致的

/* In each node we have index table to all sub-nodes. Make more space
   for the first column, which is the name to each sub-node. */
table.menu tbody tr td:nth-child(1) {
    width: 40%;
}

JSONRPC Overview:

也不清楚为什么有冒号,后面却没内容了。

这里 global minor mode 好像不太对吧(印象中不环保,好像随便新建一个 buffer,任何模式,包括 with-temp-buffer?都会执行),而且 minor mode 也不需要,直接 advice-add 就行了。

不是的,原本也没有:https://xuchunyang.github.io/emacs-manuals/master/elisp/JSONRPC.html

global minor mode是说整个Emacs session只有一个minor mode的instance,不会一个buffer一个。所以用在global advice上是合适的。这个跟我自己写一个开关函数没有区别。这种功能我都爱写一个global minor mode,有免费的开关函数和文档。

我是说显示成了两行

Process-based JSONRPC 
connections

我一开始加那个40%的css就是为了解决这个问题,不加40%会更窄更难看。我又研究了一下,终于找到好了的办法:设white-space: nowrap就不会被断了。

其他的manual编译不难,但是从Emacs跳转有点不好办,因为每个都是单独的info节点。


misc manual加入了:index。24.3的makefile又不合群,干脆不编译了。

1赞

index 里 Emacs MIME 显示成了 emacs,Auth-source 显示成了 auth。

官方 Misc 清单: https://www.gnu.org/software/emacs/manual/index.html

https://ftp.gnu.org/old-gnu/Manuals/ 里有 Emacs 20 和 21 的。

谢谢,我更新一下


改好了。不知道为什么没有Ada mode。