* bug#13989: Make Info support footnotes
@ 2013-03-18 10:24 Xue Fuqiao
2013-03-18 22:35 ` Juri Linkov
0 siblings, 1 reply; 6+ messages in thread
From: Xue Fuqiao @ 2013-03-18 10:24 UTC (permalink / raw)
To: 13989
Severity: wishlist
Hello,
It would be nice if Info supports footnotes, just like
`org-footnote-action' in Org:
(1) When at a footnote reference, jump to the definition.
(2) When at a definition, jump to the references if they exist, offer
to create them otherwise.
Or another choice: make footnote.el support Info.
--
Xue Fuqiao
http://www.gnu.org/software/emacs/
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13989: Make Info support footnotes
2013-03-18 10:24 bug#13989: Make Info support footnotes Xue Fuqiao
@ 2013-03-18 22:35 ` Juri Linkov
2013-03-19 22:30 ` Juri Linkov
0 siblings, 1 reply; 6+ messages in thread
From: Juri Linkov @ 2013-03-18 22:35 UTC (permalink / raw)
To: Xue Fuqiao; +Cc: 13989
> It would be nice if Info supports footnotes, just like
> `org-footnote-action' in Org:
> (1) When at a footnote reference, jump to the definition.
> (2) When at a definition, jump to the references if they exist, offer
> to create them otherwise.
>
> Or another choice: make footnote.el support Info.
Thanks for the suggestion. Footnotes like in Org and Wikipedia
would be nice to have. And it's pretty straightforward to implement:
=== modified file 'lisp/info.el'
--- lisp/info.el 2013-02-21 06:55:19 +0000
+++ lisp/info.el 2013-03-18 22:34:07 +0000
@@ -3840,7 +3861,21 @@ (defun Info-try-follow-nearest-node (&op
((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)"))
(Info-goto-node "Top" fork))
((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)"))
- (Info-goto-node node fork)))
+ (Info-goto-node node fork))
+ ;; footnote
+ ((setq node (Info-get-token (point) "(" "\\(([0-9]+)\\)"))
+ (let ((old-point (point)) new-point)
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward "^[ \t]*-+ Footnotes -+$" nil t)
+ (setq new-point (if (< old-point (point))
+ ;; Go to footnote reference
+ (search-forward node nil t)
+ ;; Go to footnote definition
+ (search-backward node nil t)))))
+ (when new-point
+ (goto-char new-point)
+ (setq node t)))))
node))
(defun Info-mouse-follow-link (click)
@@ -4896,6 +4931,20 @@ (defun Info-fontify-node ()
mouse-face highlight
help-echo "mouse-2: go to this URL"))))
+ ;; Fontify footnotes
+ (goto-char (point-min))
+ (when (and not-fontified-p (re-search-forward "^[ \t]*-+ Footnotes -+$" nil t))
+ (let ((limit (point)))
+ (goto-char (point-min))
+ (while (re-search-forward "\\(([0-9]+)\\)" nil t)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ `(font-lock-face info-xref
+ mouse-face highlight
+ help-echo
+ ,(if (< (point) limit)
+ "mouse-2: go to footnote definition"
+ "mouse-2: go to footnote reference"))))))
+
;; Hide empty lines at the end of the node.
(goto-char (point-max))
(skip-chars-backward "\n")
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13989: Make Info support footnotes
2013-03-18 22:35 ` Juri Linkov
@ 2013-03-19 22:30 ` Juri Linkov
2013-03-20 3:50 ` Eli Zaretskii
0 siblings, 1 reply; 6+ messages in thread
From: Juri Linkov @ 2013-03-19 22:30 UTC (permalink / raw)
To: Xue Fuqiao; +Cc: 13989
> And it's pretty straightforward to implement:
But footnotes are still not navigable. Typing `TAB' should navigate
to the next/previous footnote as it does for the cross-node references
and URLs.
Since adding a footnote regexp to `Info-next-reference' will create
false positives such as e.g. `TAB' will find plain text "(1)" and "(2)"
in the node (info "(emacs) Copying"), a better approach would be
to support text-property links like used in the *Help* buffers where
links have a special text property that `TAB' (`forward-button')
searches for to navigate to the next link.
These two approaches can co-exist in Info, so `TAB' will move point
to the closest position found either by `re-search-forward' or
`next-single-char-property-change'.
Later these text properties could be added to links in virtual nodes
because this approach is more efficient and reliable.
=== modified file 'lisp/info.el'
--- lisp/info.el 2013-02-21 06:55:19 +0000
+++ lisp/info.el 2013-03-19 22:28:00 +0000
@@ -3057,6 +3078,38 @@ (defun Info-mouse-scroll-down (e)
(select-window (posn-window (event-start e))))
(Info-scroll-down)))
+(defun Info-next-reference-or-link (pat prop)
+ "Move point to the next pattern-based cross-reference or property-based link.
+The next cross-reference is searched using the regexp PAT, and the next link
+is searched using the text property PROP. Move point to the closest found position
+of either a cross-reference found by `re-search-forward' or a link found by
+`next-single-char-property-change'. Return the new position of point, or nil."
+ (let ((pcref (save-excursion (re-search-forward pat nil t)))
+ (plink (next-single-char-property-change (point) prop)))
+ (when (and (< plink (point-max)) (not (get-char-property plink prop)))
+ (setq plink (next-single-char-property-change plink prop)))
+ (if (< plink (point-max))
+ (if (and pcref (<= pcref plink))
+ (goto-char (or (match-beginning 1) (match-beginning 0)))
+ (goto-char plink))
+ (if pcref (goto-char (or (match-beginning 1) (match-beginning 0)))))))
+
+(defun Info-prev-reference-or-link (pat prop)
+ "Move point to the previous pattern-based cross-reference or property-based link.
+The previous cross-reference is searched using the regexp PAT, and the previous link
+is searched using the text property PROP. Move point to the closest found position
+of either a cross-reference found by `re-search-backward' or a link found by
+`previous-single-char-property-change'. Return the new position of point, or nil."
+ (let ((pcref (save-excursion (re-search-backward pat nil t)))
+ (plink (previous-single-char-property-change (point) prop)))
+ (when (and (> plink (point-min)) (not (get-char-property plink prop)))
+ (setq plink (previous-single-char-property-change plink prop)))
+ (if (> plink (point-min))
+ (if (and pcref (>= pcref plink))
+ (goto-char (or (match-beginning 1) (match-beginning 0)))
+ (goto-char plink))
+ (if pcref (goto-char (or (match-beginning 1) (match-beginning 0)))))))
+
(defun Info-next-reference (&optional recur count)
"Move cursor to the next cross-reference or menu item in the node.
If COUNT is non-nil (interactively with a prefix arg), jump over
@@ -3071,14 +3124,13 @@ (defun Info-next-reference (&optional re
(old-pt (point))
(case-fold-search t))
(or (eobp) (forward-char 1))
- (or (re-search-forward pat nil t)
+ (or (Info-next-reference-or-link pat 'link)
(progn
(goto-char (point-min))
- (or (re-search-forward pat nil t)
+ (or (Info-next-reference-or-link pat 'link)
(progn
(goto-char old-pt)
(user-error "No cross references in this node")))))
- (goto-char (or (match-beginning 1) (match-beginning 0)))
(if (looking-at "\\* Menu:")
(if recur
(user-error "No cross references in this node")
@@ -3099,14 +3151,13 @@ (defun Info-prev-reference (&optional re
(let ((pat "\\*note[ \n\t]+\\([^:]+\\):\\|^\\* .*:\\|[hf]t?tps?://")
(old-pt (point))
(case-fold-search t))
- (or (re-search-backward pat nil t)
+ (or (Info-prev-reference-or-link pat 'link)
(progn
(goto-char (point-max))
- (or (re-search-backward pat nil t)
+ (or (Info-prev-reference-or-link pat 'link)
(progn
(goto-char old-pt)
(user-error "No cross references in this node")))))
- (goto-char (or (match-beginning 1) (match-beginning 0)))
(if (looking-at "\\* Menu:")
(if recur
(user-error "No cross references in this node")
@@ -3840,7 +3892,25 @@ (defun Info-try-follow-nearest-node (&op
((setq node (Info-get-token (point) "File: " "File: \\([^,\n\t]*\\)"))
(Info-goto-node "Top" fork))
((setq node (Info-get-token (point) "Prev: " "Prev: \\([^,\n\t]*\\)"))
- (Info-goto-node node fork)))
+ (Info-goto-node node fork))
+ ;; footnote
+ ((setq node (Info-get-token (point) "(" "\\(([0-9]+)\\)"))
+ (let ((old-point (point)) new-point)
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward "^[ \t]*-+ Footnotes -+$" nil t)
+ (setq new-point (if (< old-point (point))
+ ;; Go to footnote reference
+ (and (search-forward node nil t)
+ ;; Put point at beginning of link
+ (match-beginning 0))
+ ;; Go to footnote definition
+ (search-backward node nil t)))))
+ (if new-point
+ (progn
+ (goto-char new-point)
+ (setq node t))
+ (setq node nil)))))
node))
(defun Info-mouse-follow-link (click)
@@ -4896,6 +4966,21 @@ (defun Info-fontify-node ()
mouse-face highlight
help-echo "mouse-2: go to this URL"))))
+ ;; Fontify footnotes
+ (goto-char (point-min))
+ (when (and not-fontified-p (re-search-forward "^[ \t]*-+ Footnotes -+$" nil t))
+ (let ((limit (point)))
+ (goto-char (point-min))
+ (while (re-search-forward "\\(([0-9]+)\\)" nil t)
+ (add-text-properties (match-beginning 0) (match-end 0)
+ `(font-lock-face info-xref
+ link t
+ mouse-face highlight
+ help-echo
+ ,(if (< (point) limit)
+ "mouse-2: go to footnote definition"
+ "mouse-2: go to footnote reference"))))))
+
;; Hide empty lines at the end of the node.
(goto-char (point-max))
(skip-chars-backward "\n")
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13989: Make Info support footnotes
2013-03-19 22:30 ` Juri Linkov
@ 2013-03-20 3:50 ` Eli Zaretskii
2013-03-20 23:05 ` Juri Linkov
0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2013-03-20 3:50 UTC (permalink / raw)
To: Juri Linkov; +Cc: xfq.free, 13989
> From: Juri Linkov <juri@jurta.org>
> Date: Wed, 20 Mar 2013 00:30:21 +0200
> Cc: 13989@debbugs.gnu.org
>
> > And it's pretty straightforward to implement:
>
> But footnotes are still not navigable. Typing `TAB' should navigate
> to the next/previous footnote as it does for the cross-node references
> and URLs.
>
> Since adding a footnote regexp to `Info-next-reference' will create
> false positives such as e.g. `TAB' will find plain text "(1)" and "(2)"
> in the node (info "(emacs) Copying"), a better approach would be
> to support text-property links like used in the *Help* buffers where
> links have a special text property that `TAB' (`forward-button')
> searches for to navigate to the next link.
>
> These two approaches can co-exist in Info, so `TAB' will move point
> to the closest position found either by `re-search-forward' or
> `next-single-char-property-change'.
>
> Later these text properties could be added to links in virtual nodes
> because this approach is more efficient and reliable.
What if the footnote style is set to 'Separate' in the Texinfo
sources?
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13989: Make Info support footnotes
2013-03-20 3:50 ` Eli Zaretskii
@ 2013-03-20 23:05 ` Juri Linkov
2013-03-21 8:09 ` Xue Fuqiao
0 siblings, 1 reply; 6+ messages in thread
From: Juri Linkov @ 2013-03-20 23:05 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: xfq.free, 13989-done
> What if the footnote style is set to 'Separate' in the Texinfo
> sources?
If the footnote style is 'Separate' then `makeinfo' creates
a separate node with a normal cross reference that leads to it.
I tested both footnote styles, and they work consistently
with Info navigation, so I'm closing this report as fixed.
^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13989: Make Info support footnotes
2013-03-20 23:05 ` Juri Linkov
@ 2013-03-21 8:09 ` Xue Fuqiao
0 siblings, 0 replies; 6+ messages in thread
From: Xue Fuqiao @ 2013-03-21 8:09 UTC (permalink / raw)
To: Juri Linkov; +Cc: 13989-done
On Thu, 21 Mar 2013 01:05:01 +0200
Juri Linkov <juri@jurta.org> wrote:
> > What if the footnote style is set to 'Separate' in the Texinfo
> > sources?
>
> If the footnote style is 'Separate' then `makeinfo' creates
> a separate node with a normal cross reference that leads to it.
> I tested both footnote styles, and they work consistently
> with Info navigation, so I'm closing this report as fixed.
Thank you. It's a very useful feature.
--
Xue Fuqiao
http://www.gnu.org/software/emacs/
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-03-21 8:09 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-18 10:24 bug#13989: Make Info support footnotes Xue Fuqiao
2013-03-18 22:35 ` Juri Linkov
2013-03-19 22:30 ` Juri Linkov
2013-03-20 3:50 ` Eli Zaretskii
2013-03-20 23:05 ` Juri Linkov
2013-03-21 8:09 ` Xue Fuqiao
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).