commit | author | age
|
76bbd0
|
1 |
;;; org-info.el --- Support for Links to Info Nodes -*- lexical-binding: t; -*- |
C |
2 |
|
|
3 |
;; Copyright (C) 2004-2018 Free Software Foundation, Inc. |
|
4 |
|
|
5 |
;; Author: Carsten Dominik <carsten at orgmode dot org> |
|
6 |
;; Keywords: outlines, hypermedia, calendar, wp |
|
7 |
;; Homepage: https://orgmode.org |
|
8 |
;; |
|
9 |
;; This file is part of GNU Emacs. |
|
10 |
;; |
|
11 |
;; GNU Emacs is free software: you can redistribute it and/or modify |
|
12 |
;; it under the terms of the GNU General Public License as published by |
|
13 |
;; the Free Software Foundation, either version 3 of the License, or |
|
14 |
;; (at your option) any later version. |
|
15 |
|
|
16 |
;; GNU Emacs is distributed in the hope that it will be useful, |
|
17 |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
18 |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
19 |
;; GNU General Public License for more details. |
|
20 |
|
|
21 |
;; You should have received a copy of the GNU General Public License |
|
22 |
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. |
|
23 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
24 |
;; |
|
25 |
;;; Commentary: |
|
26 |
|
|
27 |
;; This file implements links to Info nodes from within Org mode. |
|
28 |
;; Org mode loads this module by default - if this is not what you want, |
|
29 |
;; configure the variable `org-modules'. |
|
30 |
|
|
31 |
;;; Code: |
|
32 |
|
|
33 |
(require 'org) |
|
34 |
|
|
35 |
;; Declare external functions and variables |
|
36 |
|
|
37 |
(declare-function Info-find-node "info" |
|
38 |
(filename nodename &optional no-going-back strict-case)) |
|
39 |
(defvar Info-current-file) |
|
40 |
(defvar Info-current-node) |
|
41 |
|
|
42 |
;; Install the link type |
|
43 |
(org-link-set-parameters "info" |
|
44 |
:follow #'org-info-open |
|
45 |
:export #'org-info-export |
|
46 |
:store #'org-info-store-link) |
|
47 |
|
|
48 |
;; Implementation |
|
49 |
(defun org-info-store-link () |
|
50 |
"Store a link to an Info file and node." |
|
51 |
(when (eq major-mode 'Info-mode) |
|
52 |
(let ((link (concat "info:" |
|
53 |
(file-name-nondirectory Info-current-file) |
|
54 |
"#" Info-current-node)) |
|
55 |
(desc (concat (file-name-nondirectory Info-current-file) |
|
56 |
"#" Info-current-node))) |
|
57 |
(org-store-link-props :type "info" :file Info-current-file |
|
58 |
:node Info-current-node |
|
59 |
:link link :desc desc) |
|
60 |
link))) |
|
61 |
|
|
62 |
(defun org-info-open (path) |
|
63 |
"Follow an Info file and node link specified by PATH." |
|
64 |
(org-info-follow-link path)) |
|
65 |
|
|
66 |
|
|
67 |
(defun org-info-follow-link (name) |
|
68 |
"Follow an Info file and node link specified by NAME." |
|
69 |
(if (or (string-match "\\(.*\\)[#:]:?\\(.*\\)" name) |
|
70 |
(string-match "\\(.*\\)" name)) |
|
71 |
(let ((filename (match-string 1 name)) |
|
72 |
(nodename-or-index (or (match-string 2 name) "Top"))) |
|
73 |
(require 'info) |
|
74 |
;; If nodename-or-index is invalid node name, then look it up |
|
75 |
;; in the index. |
|
76 |
(condition-case nil |
|
77 |
(Info-find-node filename nodename-or-index) |
|
78 |
(user-error (Info-find-node filename "Top") |
|
79 |
(condition-case nil |
|
80 |
(Info-index nodename-or-index) |
|
81 |
(user-error "Could not find '%s' node or index entry" |
|
82 |
nodename-or-index))))) |
|
83 |
(user-error "Could not open: %s" name))) |
|
84 |
|
|
85 |
(defconst org-info-emacs-documents |
|
86 |
'("ada-mode" "auth" "autotype" "bovine" "calc" "ccmode" "cl" "dbus" "dired-x" |
|
87 |
"ebrowse" "ede" "ediff" "edt" "efaq-w32" "efaq" "eieio" "eintr" "elisp" |
|
88 |
"emacs-gnutls" "emacs-mime" "emacs" "epa" "erc" "ert" "eshell" "eudc" "eww" |
|
89 |
"flymake" "forms" "gnus" "htmlfontify" "idlwave" "ido" "info" "mairix-el" |
|
90 |
"message" "mh-e" "newsticker" "nxml-mode" "octave-mode" "org" "pcl-cvs" |
|
91 |
"pgg" "rcirc" "reftex" "remember" "sasl" "sc" "semantic" "ses" "sieve" |
|
92 |
"smtpmail" "speedbar" "srecode" "todo-mode" "tramp" "url" "vip" "viper" |
|
93 |
"widget" "wisent" "woman") |
|
94 |
"List of emacs documents available. |
|
95 |
Taken from <https://www.gnu.org/software/emacs/manual/html_mono/.>") |
|
96 |
|
|
97 |
(defconst org-info-other-documents |
|
98 |
'(("libc" . "https://www.gnu.org/software/libc/manual/html_mono/libc.html") |
|
99 |
("make" . "https://www.gnu.org/software/make/manual/make.html")) |
|
100 |
"Alist of documents generated from Texinfo source. |
|
101 |
When converting info links to HTML, links to any one of these manuals are |
|
102 |
converted to use these URL.") |
|
103 |
|
|
104 |
(defun org-info-map-html-url (filename) |
|
105 |
"Return URL or HTML file associated to Info FILENAME. |
|
106 |
If FILENAME refers to an official GNU document, return a URL pointing to |
|
107 |
the official page for that document, e.g., use \"gnu.org\" for all Emacs |
|
108 |
related documents. Otherwise, append \".html\" extension to FILENAME. |
|
109 |
See `org-info-emacs-documents' and `org-info-other-documents' for details." |
|
110 |
(cond ((member filename org-info-emacs-documents) |
|
111 |
(format "https://www.gnu.org/software/emacs/manual/html_mono/%s.html" |
|
112 |
filename)) |
|
113 |
((cdr (assoc filename org-info-other-documents))) |
|
114 |
(t (concat filename ".html")))) |
|
115 |
|
|
116 |
(defun org-info--expand-node-name (node) |
|
117 |
"Expand Info NODE to HTML cross reference." |
|
118 |
;; See (info "(texinfo) HTML Xref Node Name Expansion") for the |
|
119 |
;; expansion rule. |
|
120 |
(let ((node (replace-regexp-in-string |
|
121 |
"\\([ \t\n\r]+\\)\\|\\([^a-zA-Z0-9]\\)" |
|
122 |
(lambda (m) |
|
123 |
(if (match-end 1) "-" (format "_%04x" (string-to-char m)))) |
|
124 |
(org-trim node)))) |
|
125 |
(cond ((string= node "") "") |
|
126 |
((string-match-p "\\`[0-9]" node) (concat "g_t" node)) |
|
127 |
(t node)))) |
|
128 |
|
|
129 |
(defun org-info-export (path desc format) |
|
130 |
"Export an info link. |
|
131 |
See `org-link-parameters' for details about PATH, DESC and FORMAT." |
|
132 |
(let* ((parts (split-string path "[#:]:?")) |
|
133 |
(manual (car parts)) |
|
134 |
(node (or (nth 1 parts) "Top"))) |
|
135 |
(pcase format |
|
136 |
(`html |
|
137 |
(format "<a href=\"%s#%s\">%s</a>" |
|
138 |
(org-info-map-html-url manual) |
|
139 |
(org-info--expand-node-name node) |
|
140 |
(or desc path))) |
|
141 |
(`texinfo |
|
142 |
(let ((title (or desc ""))) |
|
143 |
(format "@ref{%s,%s,,%s,}" node title manual))) |
|
144 |
(_ nil)))) |
|
145 |
|
|
146 |
(provide 'org-info) |
|
147 |
|
|
148 |
;;; org-info.el ends here |