diff --git a/lisp/org-info.el b/lisp/org-info.el
index cbe4289fc..79b9bcc3d 100644
--- a/lisp/org-info.el
+++ b/lisp/org-info.el
@@ -113,6 +113,19 @@ See `org-info-emacs-documents' and `org-info-other-documents' for details."
((cdr (assoc filename org-info-other-documents)))
(t (concat filename ".html"))))
+(defun org-info--expand-node-name (node)
+ "Expand Info NODE to HTML cross reference."
+ ;; See (info "(texinfo) HTML Xref Node Name Expansion") for the
+ ;; expansion rule.
+ (let ((node (replace-regexp-in-string
+ "\\([ \t\n\r]+\\)\\|\\([^a-zA-Z0-9]\\)"
+ (lambda (m)
+ (if (match-end 1) "-" (format "_%04x" (string-to-char m))))
+ (org-trim node))))
+ (cond ((string= node "") "")
+ ((string-match-p "\\`[0-9]" node) (concat "g_t" node))
+ (t node))))
+
(defun org-info-export (path desc format)
"Export an info link.
See `org-link-parameters' for details about PATH, DESC and FORMAT."
@@ -123,7 +136,7 @@ See `org-link-parameters' for details about PATH, DESC and FORMAT."
(node (or (match-string 2 path) "Top")))
(format "%s"
(org-info-map-html-url filename)
- (replace-regexp-in-string " " "-" node)
+ (org-info--expand-node-name node)
(or desc path)))))
(provide 'org-info)
diff --git a/testing/lisp/test-org-info.el b/testing/lisp/test-org-info.el
new file mode 100644
index 000000000..df0ef3195
--- /dev/null
+++ b/testing/lisp/test-org-info.el
@@ -0,0 +1,57 @@
+;;; test-org-info.el --- Tests for "org-info.el" -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Nicolas Goaziou
+
+;; Author: Nicolas Goaziou
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program 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 General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see .
+
+;;; Code:
+
+(ert-deftest test-org-info/export ()
+ "Test `org-info-export' specifications."
+ ;; Regular export to HTML, with node. Without node, refer to "Top".
+ (should
+ (equal (org-info-export "filename#node" nil 'html)
+ "filename#node"))
+ (should
+ (equal (org-info-export "filename" nil 'html)
+ "filename"))
+ ;; When exporting to HTML, ensure node names are expanded according
+ ;; to (info "(texinfo) HTML Xref Node Name Expansion").
+ (should
+ (equal "_005f"
+ (let ((name (org-info-export "#_" nil 'html)))
+ (and (string-match "#\\(.*\\)\"" name)
+ (match-string 1 name)))))
+ (should
+ (equal "_002d"
+ (let ((name (org-info-export "#-" nil 'html)))
+ (and (string-match "#\\(.*\\)\"" name)
+ (match-string 1 name)))))
+ (should
+ (equal "A-node"
+ (let ((name (org-info-export "#A node" nil 'html)))
+ (and (string-match "#\\(.*\\)\"" name)
+ (match-string 1 name)))))
+ (should
+ (equal "A-node-_002d_002d_002d-with-_005f_0027_0025"
+ (let ((name (org-info-export "#A node --- with _'%" nil 'html)))
+ (and (string-match "#\\(.*\\)\"" name)
+ (match-string 1 name))))))
+
+
+
+(provide 'test-org-info)
+;;; test-org-info.el ends here