Function: help-make-xrefs

help-make-xrefs is an autoloaded, interactive and byte-compiled function defined in help-mode.el.gz.

Signature

(help-make-xrefs &optional BUFFER)

Documentation

Parse and hyperlink documentation cross-references in the given BUFFER.

Find cross-reference information in a buffer and activate such cross references for selection with help-follow-symbol. Cross-references have the canonical form ... and the type of reference may be disambiguated by the preceding word(s) used in help-xref-symbol-regexp. Faces only get cross-referenced if preceded or followed by the word face. Variables without variable documentation do not get cross-referenced, unless preceded by the word variable or option.

If the variable help-xref-mule-regexp is non-nil, find also cross-reference information related to multilingual environment
(e.g., coding-systems). This variable is also used to disambiguate
the type of reference as the same way as help-xref-symbol-regexp.

A special reference back is made to return back through a stack of help buffers. Variable help-back-label specifies the text for that.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/help-mode.el.gz
;;;###autoload
(defun help-make-xrefs (&optional buffer)
  "Parse and hyperlink documentation cross-references in the given BUFFER.

Find cross-reference information in a buffer and activate such cross
references for selection with `help-follow-symbol'.  Cross-references have
the canonical form `...'  and the type of reference may be
disambiguated by the preceding word(s) used in
`help-xref-symbol-regexp'.  Faces only get cross-referenced if
preceded or followed by the word `face'.  Variables without
variable documentation do not get cross-referenced, unless
preceded by the word `variable' or `option'.

If the variable `help-xref-mule-regexp' is non-nil, find also
cross-reference information related to multilingual environment
\(e.g., coding-systems).  This variable is also used to disambiguate
the type of reference as the same way as `help-xref-symbol-regexp'.

A special reference `back' is made to return back through a stack of
help buffers.  Variable `help-back-label' specifies the text for
that."
  (interactive "b")
  (with-current-buffer (or buffer (current-buffer))
    (save-excursion
      (goto-char (point-min))
      ;; Skip the first bit, which has already been buttonized.
      (forward-paragraph)
      (let ((old-modified (buffer-modified-p)))
        (let ((stab (syntax-table))
              (case-fold-search t)
              (inhibit-read-only t))
          (set-syntax-table help-mode-syntax-table)
          ;; The following should probably be abstracted out.
          (unwind-protect
              (progn
                ;; Info references
                (save-excursion
                  (while (re-search-forward help-xref-info-regexp nil t)
                    (let ((data (match-string 2)))
                      (save-match-data
                        (unless (string-match "^([^)]+)" data)
                          (setq data (concat "(emacs)" data)))
			(setq data ;; possible newlines if para filled
			      (replace-regexp-in-string "[ \t\n]+" " " data t t)))
                      (help-xref-button 2 'help-info data))))
                ;; Man references
                (save-excursion
                  (while (re-search-forward help-xref-man-regexp nil t)
                    (help-xref-button 1 'help-man (match-string 1))))
                ;; Customization groups.
                (save-excursion
                  (while (re-search-forward
                          help-xref-customization-group-regexp nil t)
                    (help-xref-button 1 'help-customization-group
                                      (intern (match-string 1)))))
                ;; URLs
                (save-excursion
                  (while (re-search-forward help-xref-url-regexp nil t)
                    (let ((data (match-string 1)))
                      (help-xref-button 1 'help-url data))))
                ;; Mule related keywords.  Do this before trying
                ;; `help-xref-symbol-regexp' because some of Mule
                ;; keywords have variable or function definitions.
                (if help-xref-mule-regexp
                    (save-excursion
                      (while (re-search-forward help-xref-mule-regexp nil t)
                        (let* ((data (match-string 7))
                               (sym (intern-soft data)))
                          (cond
                           ((match-string 3) ; coding system
                            (and sym (coding-system-p sym)
                                 (help-xref-button 6 'help-coding-system sym)))
                           ((match-string 4) ; input method
                            (and (assoc data input-method-alist)
                                 (help-xref-button 7 'help-input-method data)))
                           ((or (match-string 5) (match-string 6)) ; charset
                            (and sym (charsetp sym)
                                 (help-xref-button 7 'help-character-set sym)))
                           ((assoc data input-method-alist)
                            (help-xref-button 7 'help-input-method data))
                           ((and sym (coding-system-p sym))
                            (help-xref-button 7 'help-coding-system sym))
                           ((and sym (charsetp sym))
                            (help-xref-button 7 'help-character-set sym)))))))
                ;; Quoted symbols
                (save-excursion
                  (while (re-search-forward help-xref-symbol-regexp nil t)
                    (let* ((data (match-string 8))
                           (sym (intern-soft data)))
                      (if sym
                          (cond
                           ((match-string 3) ; `variable' &c
                            (and (or (boundp sym) ; `variable' doesn't ensure
                                        ; it's actually bound
                                     (get sym 'variable-documentation))
                                 (help-xref-button 8 'help-variable sym)))
                           ((match-string 4) ; `function' &c
                            (and (fboundp sym) ; similarly
                                 (help-xref-button 8 'help-function sym)))
                           ((match-string 5) ; `face'
                            (and (facep sym)
                                 (help-xref-button 8 'help-face sym)))
                           ((match-string 6)) ; nothing for `symbol'
                           ((match-string 7)
                            (help-xref-button 8 'help-function-def sym))
                           ((cl-some (lambda (x) (funcall (nth 1 x) sym))
                                     describe-symbol-backends)
                            (help-xref-button 8 'help-symbol sym)))))))
                ;; An obvious case of a key substitution:
                (save-excursion
                  (while (re-search-forward
                          ;; Assume command name is only word and symbol
                          ;; characters to get things like `use M-x foo->bar'.
                          ;; Command required to end with word constituent
                          ;; to avoid `.' at end of a sentence.
                          "\\<M-x\\s-+\\(\\sw\\(\\sw\\|\\s_\\)*\\sw\\)" nil t)
                    (let ((sym (intern-soft (match-string 1))))
                      (if (fboundp sym)
                          (help-xref-button 1 'help-function sym)))))
                ;; Look for commands in whole keymap substitutions:
                (save-excursion
                  ;; Make sure to find the first keymap.
                  (goto-char (point-min))
                  ;; Find a header and the column at which the command
                  ;; name will be found.

                  ;; If the keymap substitution isn't the last thing in
                  ;; the doc string, and if there is anything on the same
                  ;; line after it, this code won't recognize the end of it.
                  (while (re-search-forward "^key +binding\n\\(-+ +\\)-+\n\n"
                                            nil t)
                    (let ((col (- (match-end 1) (match-beginning 1))))
                      (while
                          (and (not (eobp))
                               ;; Stop at a pair of blank lines.
                               (not (looking-at-p "\n\\s-*\n")))
                        ;; Skip a single blank line.
                        (and (eolp) (forward-line))
                        (end-of-line)
                        (skip-chars-backward "^ \t\n")
                        (if (and (>= (current-column) col)
                                 (looking-at "\\(\\sw\\|\\s_\\)+$"))
                            (let ((sym (intern-soft (match-string 0))))
                              (if (fboundp sym)
                                  (help-xref-button 0 'help-function sym))))
                        (forward-line))))))
            (set-syntax-table stab))
          ;; Delete extraneous newlines at the end of the docstring
          (goto-char (point-max))
          (while (and (not (bobp)) (bolp))
            (delete-char -1))
          (insert "\n")
          (when (or help-xref-stack help-xref-forward-stack)
            (insert "\n"))
          ;; Make a back-reference in this buffer if appropriate.
          (when help-xref-stack
            (help-insert-xref-button help-back-label 'help-back
                                     (current-buffer)))
          ;; Make a forward-reference in this buffer if appropriate.
          (when help-xref-forward-stack
            (when help-xref-stack
              (insert "\t"))
            (help-insert-xref-button help-forward-label 'help-forward
                                     (current-buffer)))
          (when (or help-xref-stack help-xref-forward-stack)
            (insert "\n")))
        (set-buffer-modified-p old-modified)))))