Package: emacs;
Reported by: Eshel Yaron <me <at> eshelyaron.com>
Date: Sat, 17 Jun 2023 11:08:01 UTC
Severity: normal
Tags: patch
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
Message #17 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Eshel Yaron <me <at> eshelyaron.com> To: Eshel Yaron via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org> Cc: 64126 <at> debbugs.gnu.org, Eli Zaretskii <eliz <at> gnu.org> Subject: Re: bug#64126: [PATCH] New command 'eww-copy-alternate-url' Date: Wed, 21 Jun 2023 09:01:03 +0300
Hi all, Any further comments about this addition? > I'm attaching yet another updated patch (v3), the difference compared to > the former patch is that now the alignment of completion candidate > annotations is based on `string-pixel-width` and `display` text > properties instead of padding with spaces. > > This deals better with more exotic strings that may appear in the link's > title (again gnu.org is a good example here, as there are alternate link > titles in different languages). Still I wonder if there's a more > principled way to align such annotations, any suggestions? > > From 2337ba007e2d0512b2a4445e6749ef51df343417 Mon Sep 17 00:00:00 2001 > From: Eshel Yaron <me <at> eshelyaron.com> > Date: Sat, 17 Jun 2023 13:48:51 +0300 > Subject: [PATCH v3] New command 'eww-copy-alternate-url' > > This adds a new command to EWW that copies an alternate link to the > currently visited page into the kill ring. This is useful for > subscribing to website feeds, etc. > > * lisp/net/eww.el (eww--alternate-urls) > (eww-read-alternate-url): New functions. > (eww-copy-alternate-url): New command. > (eww-mode-map): Bind it to 'A'. > > * doc/misc/eww.texi (Basics): Document it. > > * etc/NEWS: Announce it. > --- > doc/misc/eww.texi | 15 +++++++++ > etc/NEWS | 5 +++ > lisp/net/eww.el | 79 +++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 99 insertions(+) > > diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi > index c02e9db11c9..cff48bd601e 100644 > --- a/doc/misc/eww.texi > +++ b/doc/misc/eww.texi > @@ -115,6 +115,21 @@ Basics > @kbd{w} calls @code{eww-copy-page-url}, which will copy the current > page's URL to the kill ring instead. > > +@findex eww-copy-alternate-url > +@kindex A > + The @kbd{A} command (@code{eww-copy-alternate-url}) copies the URL > +of an alternate link of the current page into the kill ring. If the > +page specifies multiple alternate links, this command prompts for one > +of them in the minibuffer, with completion. Alternate links are > +references that an @acronym{HTML} page may include to point to other > +documents that act as its alternative representations. Notably, > +@acronym{HTML} pages can use alternate links to point to their > +translated versions and to @acronym{RSS} feeds. Alternate links > +appear in the @samp{<head>} section of @acronym{HTML} pages as > +@samp{<link>} elements with @samp{rel} attribute equal to > +@samp{``alternate''}, they are part of the page's metadata and are not > +visible in its rendered content. > + > @findex eww-open-in-new-buffer > @kindex M-RET > The @kbd{M-@key{RET}} command (@code{eww-open-in-new-buffer}) opens the > diff --git a/etc/NEWS b/etc/NEWS > index 61e6e161665..7c94c3efa89 100644 > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -253,6 +253,11 @@ The interactive minibuffer prompt when invoking 'eww' now provides > completions from 'eww-suggest-uris'. 'eww-suggest-uris' now includes > bookmark URIs. > > ++++ > +*** New command 'eww-copy-alternate-url'. > +It copies an alternate link to the page currently visited in EWW into > +the kill ring. > + > ** go-ts-mode > > +++ > diff --git a/lisp/net/eww.el b/lisp/net/eww.el > index 61f0f47373d..89f7ba37cc1 100644 > --- a/lisp/net/eww.el > +++ b/lisp/net/eww.el > @@ -1086,6 +1086,7 @@ eww-mode-map > "&" #'eww-browse-with-external-browser > "d" #'eww-download > "w" #'eww-copy-page-url > + "A" #'eww-copy-alternate-url > "C" #'url-cookie-list > "v" #'eww-view-source > "R" #'eww-readable > @@ -2576,4 +2577,82 @@ eww-bookmark-jump > > (provide 'eww) > > +;;; Alternate links (RSS and Atom feeds, etc.) > + > +(defun eww--alternate-urls (dom &optional base) > + "Return an alist of alternate links in DOM. > + > +Each element is a list of the form (URL TYPE TITLE) where URL is > +the href attribute of the link expanded relative to BASE, TYPE is > +its type attribute, and TITLE is its title attribute. If any of > +these attributes is absent, the corresponding element is nil." > + (let ((alternates > + (seq-filter > + (lambda (attrs) (string= (alist-get 'rel attrs) > + "alternate")) > + (mapcar #'dom-attributes (dom-by-tag dom 'link))))) > + (mapcar (lambda (alternate) > + (list (url-expand-file-name (alist-get 'href alternate) > + base) > + (alist-get 'type alternate) > + (alist-get 'title alternate))) > + alternates))) > + > +(defun eww-read-alternate-url () > + "Get the URL of an alternate link of this page. > + > +If there is just one alternate link, return its URL. If there > +are multiple alternate links, prompt for one in the minibuffer > +with completion. If there are none, return nil." > + (when-let ((alternates (eww--alternate-urls > + (plist-get eww-data :dom) > + (plist-get eww-data :url)))) > + (let ((url-max-width > + (seq-max (mapcar #'string-pixel-width > + (mapcar #'car alternates)))) > + (title-max-width > + (seq-max (mapcar #'string-pixel-width > + (mapcar #'caddr alternates)))) > + (sep-width (string-pixel-width " "))) > + (if (cdr alternates) > + (let ((completion-extra-properties > + (list :annotation-function > + (lambda (feed) > + (let* ((attrs (alist-get feed > + alternates > + nil > + nil > + #'string=)) > + (type (car attrs)) > + (title (cadr attrs))) > + (concat > + (propertize " " 'display > + `(space :align-to > + (,(+ sep-width > + url-max-width)))) > + title > + (when type > + (concat > + (propertize " " 'display > + `(space :align-to > + (,(+ (* 2 sep-width) > + url-max-width > + title-max-width)))) > + "[" type "]")))))))) > + (completing-read "Alternate URL: " alternates nil t)) > + (caar alternates))))) > + > +(defun eww-copy-alternate-url () > + "Copy an alternate URL of the current page into the kill ring. > + > +Alternate links are references that an HTML page may include to > +point to its alternative representations, such as a translated > +version or an RSS feed." > + (interactive nil eww-mode) > + (if-let ((url (eww-read-alternate-url))) > + (progn > + (kill-new url) > + (message "Copied %s to kill ring" url)) > + (user-error "No alternate links found on this page!"))) > + > ;;; eww.el ends here -- Thanks, Eshel
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.