From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrea Subject: Bug: org-eww-copy-for-org-mode Empty Link problem + easy fix [9.0.4 (9.0.4-elpaplus @ /home/andrea/.emacs.d/elpa/org-plus-contrib-20170124/)] Date: Sat, 11 Feb 2017 16:21:09 +0000 Message-ID: <87k28w7l6y.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:42867) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ccaQI-0005Fx-Tx for emacs-orgmode@gnu.org; Sat, 11 Feb 2017 11:21:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ccaQF-0006fx-I7 for emacs-orgmode@gnu.org; Sat, 11 Feb 2017 11:21:18 -0500 Received: from mail-wr0-x22a.google.com ([2a00:1450:400c:c0c::22a]:33295) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ccaQF-0006eO-5o for emacs-orgmode@gnu.org; Sat, 11 Feb 2017 11:21:15 -0500 Received: by mail-wr0-x22a.google.com with SMTP id i10so127143215wrb.0 for ; Sat, 11 Feb 2017 08:21:12 -0800 (PST) Received: from nixos.smtp.gmail.com (cpc82094-leic19-2-0-cust351.8-1.cable.virginm.net. [86.19.159.96]) by smtp.gmail.com with ESMTPSA id e72sm5650431wma.16.2017.02.11.08.21.10 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 11 Feb 2017 08:21:10 -0800 (PST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: emacs-orgmode@gnu.org Hello, thanks hugely for org mode: the more I learn about it the easier is my life organization! I was trying to use org-eww-copy-for-org-mode (org-eww package in the contrib/ directory) within eww in website like www.indeed.co.uk, and every time I tried, I was receiving the error "Empty Link". The error is due to the presence of input forms (e.g., in www.indeed.co.uk where you can add the job you are looking for), that are considered like urls by this function [1]. When the input form is passed to org-make-link-string, org-make-link-string complains that the link is empty. Now I solved this by adding an if statement that makes the link only if the info passed is not nil [2], but maybe someone knows a better check for org-eww-goto-next-url-property-change than the one using 'shr-url? Thanks a lot for org mode, Andrea [1] org-eww-copy-for-org-mode uses org-eww-goto-next-url-property-change to get the position of the next link, which uses (next-single-property-change (point) 'shr-url) which considers input forms 'shr-url. [2] this is the fixed version (the only change is highlighted by a FIXED HERE comment): #+BEGIN_SRC elisp (defun org-eww-copy-for-org-mode () "Copy current buffer content or active region with `org-mode' style links. This will encode `link-title' and `link-location' with `org-make-link-string', and insert the transformed test into the kill ring, so that it can be yanked into an Org mode buffer with links working correctly. Further lines starting with a star get quoted with a comma to keep the structure of the Org file." (interactive) (let* ((regionp (org-region-active-p)) (transform-start (point-min)) (transform-end (point-max)) return-content link-location link-title temp-position out-bound) (when regionp (setq transform-start (region-beginning)) (setq transform-end (region-end)) ;; Deactivate mark if current mark is activate. (when (fboundp 'deactivate-mark) (deactivate-mark))) (message "Transforming links...") (save-excursion (goto-char transform-start) (while (and (not out-bound) ; still inside region to copy (org-eww-has-further-url-property-change-p)) ; there is a next link ;; Store current point before jump next anchor. (setq temp-position (point)) ;; Move to next anchor when current point is not at anchor. (or (org-eww-url-below-point) (org-eww-goto-next-url-property-change)) (cl-assert (org-eww-url-below-point) t "program logic error: point must have an url below but it hasn't") (if (<= (point) transform-end) ; if point is inside transform bound (progn ;; Get content between two links. (when (< temp-position (point)) (setq return-content (concat return-content (buffer-substring temp-position (point))))) ;; Get link location at current point. (setq link-location (org-eww-url-below-point)) ;; Get link title at current point. (setq link-title (buffer-substring (point) (org-eww-goto-next-url-property-change))) ;; concat `org-mode' style url to `return-content'. (setq return-content (if (and ;; FIXED HERE added if statement (if (stringp link-location) (string-blank-p link-location) nil) (string-blank-p link-title) ) (concat return-content (org-make-link-string link-location link-title)) return-content ))) (goto-char temp-position) ; reset point before jump next anchor (setq out-bound t) ; for break out `while' loop )) ;; Add the rest until end of the region to be copied. (when (< (point) transform-end) (setq return-content (concat return-content (buffer-substring (point) transform-end)))) ;; Quote lines starting with *. (org-kill-new (replace-regexp-in-string "^\\*" ",*" return-content)) (message "Transforming links...done, use C-y to insert text into Org mode file")))) #+END_SRC ------------------------------------------------------------------------ Emacs : GNU Emacs 25.1.1 (x86_64-unknown-linux-gnu, GTK+ Version 2.24.31) of 2017-02-03 Package: Org mode version 9.0.4 (9.0.4-elpaplus @ /home/andrea/.emacs.d/elpa/org-plus-contrib-20170124/) current state: ============== (setq org-capture-prepare-finalize-hook '(org-id-get-create) org-reveal-mathjax t org-pandoc-epub-rights "Copyright 2017 Andrea <>" org-tab-first-hook '(org-babel-hide-result-toggle-maybe org-babel-header-arg-expand) org-speed-command-hook '(org-speed-command-default-hook org-babel-speed-command-hook) org-occur-hook '(org-first-headline-recenter) org-metaup-hook '(org-babel-load-in-session-maybe) org-html-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"] org-src-window-setup 'current-window org-latex-format-inlinetask-function 'org-latex-format-inlinetask-default-function org-confirm-shell-link-function 'yes-or-no-p org-image-actual-width 550 org-ascii-format-inlinetask-function 'org-ascii-format-inlinetask-default org-highlight-latex-and-related '(latex script entities) org-latex-format-headline-function 'org-latex-format-headline-default-function org-default-notes-file "/home/andrea/workspace/agenda/myTasks.org" org-capture-templates '(("t" "Todo" entry (file+headline "~/workspace/agenda/myTasks.org" "On the fly") "** TODO %? \n SCHEDULED:%t\nSee: %a \n\n") ("c" "Todo with quote" entry (file+headline "~/workspace/agenda/myTasks.org" "On the fly") "** TODO %? %t \n #+BEGIN_QUOTE \n%i\n #+END_QUOTE\nreference: %a \n") ("q" "Quote good text" entry (file+headline "~/workspace/agenda/myTasks.org" "Interesting quotations") "** %? \n Taken on:%t from: %a\n #+begin_src text \n%i\n #+end_src \n") ) org-after-todo-state-change-hook '(org-clock-out-if-current) org-latex-format-drawer-function #[514 "\207" [] 3 "\n\n(fn _ CONTENTS)"] org-odt-format-headline-function 'org-odt-format-headline-default-function org-from-is-user-regexp "\\" org-loop-over-headlines-in-active-region 'start-level org-src-mode-hook '(org-src-babel-configure-edit-buffer org-src-mode-configure-edit-buffer) org-agenda-before-write-hook '(org-agenda-add-entry-text) org-babel-pre-tangle-hook '(save-buffer) org-babel-tangle-use-relative-file-links nil org-mode-hook '((lambda nil (local-set-key "\357" (quote org-mime-org-buffer-htmlize))) org-toggle-blocks turn-on-flyspell #[0 "\300\301\302\303\304$\207" [add-hook change-major-mode-hook org-show-block-all append local] 5] #[0 "\300\301\302\303\304$\207" [add-hook change-major-mode-hook org-babel-show-result-all append local] 5] org-babel-result-hide-spec org-babel-hide-all-hashes org-eldoc-load) org-archive-hook '(org-attach-archive-delete-maybe) org-use-speed-commands t org-ascii-format-drawer-function #[771 "\207" [] 4 "\n\n(fn NAME CONTENTS WIDTH)"] org-pomodoro-ticking-sound "/home/andrea/.emacs.d/elpa/org-pomodoro-20161119.226/resources/tick.wav" org-odt-format-inlinetask-function 'org-odt-format-inlinetask-default-function org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-hide-drawers org-cycle-show-empty-lines org-optimize-window-after-visibility-change) org-pomodoro-start-sound "/home/andrea/.emacs.d/elpa/org-pomodoro-20161119.226/resources/bell.wav" org-plantuml-jar-path "/run/current-system/sw/lib/plantuml.jar" org-preview-latex-image-directory "/tmp/ltxpng" org-babel-tangle-lang-exts '(("scala" . "scala") ("ruby" . "rb") ("python" . "py") ("ocaml" . "ml") ("java" . "java") ("haskell" . "hs") ("clojure" . "clj") ("emacs-lisp" . "el") ("elisp" . "el")) org-confirm-elisp-link-function 'yes-or-no-p org-metadown-hook '(org-babel-pop-to-session-maybe) org-odt-format-drawer-function #[514 "\207" [] 3 "\n\n(fn NAME CONTENTS)"] org-html-format-headline-function 'org-html-format-headline-default-function org-link-parameters '(("id" :follow org-id-open) ("rmail" :follow org-rmail-open :store org-rmail-store-link) ("mhe" :follow org-mhe-open :store org-mhe-store-link) ("irc" :follow org-irc-visit :store org-irc-store-link) ("info" :follow org-info-open :export org-info-export :store org-info-store-link) ("gnus" :follow org-gnus-open :store org-gnus-store-link) ("docview" :follow org-docview-open :export org-docview-export :store org-docview-store-link) ("bibtex" :follow org-bibtex-open :store org-bibtex-store-link) ("bbdb" :follow org-bbdb-open :export org-bbdb-export :complete org-bbdb-complete-link :store org-bbdb-store-link) ("w3m" :store org-w3m-store-link) ("eww" :follow eww :store org-eww-store-link) ("mu4e" :follow org-mu4e-open :export nil :store org-mu4e-store-link) ("file+sys") ("file+emacs") ("doi" :follow org--open-doi-link) ("elisp" :follow org--open-elisp-link) ("file" :complete org-file-complete-link) ("ftp" :follow (lambda (path) (browse-url (concat "ftp:" path)))) ("help" :follow org--open-help-link) ("http" :follow (lambda (path) (browse-url (concat "http:" path)))) ("https" :follow (lambda (path) (browse-url (concat "https:" path)))) ("mailto" :follow (lambda (path) (browse-url (concat "mailto:" path)))) ("message" :follow (lambda (path) (browse-url (concat "message:" path)))) ("news" :follow (lambda (path) (browse-url (concat "news:" path)))) ("shell" :follow org--open-shell-link)) org-structure-template-alist '(("n" "#+BEGIN_NOTES\n?\n#+END_NOTES") ("u" "#+BEGIN_SRC plantuml :file uml.png \n?\n#+END_SRC") ("s" "#+BEGIN_SRC ?\n\n#+END_SRC") ("e" "#+BEGIN_EXAMPLE\n?\n#+END_EXAMPLE") ("q" "#+BEGIN_QUOTE\n?\n#+END_QUOTE") ("v" "#+BEGIN_VERSE\n?\n#+END_VERSE") ("V" "#+BEGIN_VERBATIM\n?\n#+END_VERBATIM") ("c" "#+BEGIN_CENTER\n?\n#+END_CENTER") ("l" "#+BEGIN_EXPORT latex\n?\n#+END_EXPORT") ("L" "#+LaTeX: ") ("h" "#+BEGIN_EXPORT html\n?\n#+END_EXPORT") ("H" "#+HTML: ") ("a" "#+BEGIN_EXPORT ascii\n?\n#+END_EXPORT") ("A" "#+ASCII: ") ("i" "#+INDEX: ?") ("I" "#+INCLUDE: %file ?")) org-pomodoro-long-break-sound "/home/andrea/.emacs.d/elpa/org-pomodoro-20161119.226/resources/bell_multiple.wav" org-babel-load-languages '((clojure . t) (dot . t) (gnuplot . t) (haskell . t) (java . t) (ocaml . t) (org . t) (plantuml . t) (python . t) (ruby . t) (scala . t) (shell . t)) org-pomodoro-finished-sound "/home/andrea/.emacs.d/elpa/org-pomodoro-20161119.226/resources/bell.wav" org-feed-alist '(("icuk" "https://www.indeed.co.uk/rss?q=clojure&l=&sort=date&rs=1" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :clojure:uk: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "icuk") ("igsuk" "https://www.indeed.co.uk/rss?q=graduate+software+%C2%A330,000&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:uk: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsuk") ("icnl" "https://www.indeed.nl/rss?q=clojure&l=&sort=date&rs=1" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :clojure:nl: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "icnl") ("igsnl" "https://www.indeed.nl/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:nl: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsnl") ("ijsnl" "https://www.indeed.nl/rss?q=as+a+junior+software" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :junior:nl: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "ijsnl") ("isnl" "https://www.indeed.nl/rss?q=scala+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :scala:nl: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "isnl") ("igsdk" "https://dk.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:dk: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsdk") ("igsca" "https://ca.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:ca: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsca") ("igsse" "https://se.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:se: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsse") ("igsch" "http://www.indeed.ch/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:ch: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsch") ("igsno" "https://no.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:no: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsno") ("igslu" "https://www.indeed.lu/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:lu: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igslu") ("igsjp" "https://jp.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:jp: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsjp") ("igsit" "https://it.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:it: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsit") ("igsbe" "https://be.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:be: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsbe") ("igsfi" "https://www.indeed.fi/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:fi: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsfi") ("igsfr" "https://www.indeed.fr/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:fr: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsfr") ("igsde" "https://de.indeed.com/rss?q=graduate+software&sort=date" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :graduate:de: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "igsde") ("functionaljobs" "https://functionaljobs.com/jobs/?format=rss" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :functionaljobs: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "functionaljobs" :parse-feed org-feed-parse-atom-feed :parse-entry org-feed-parse-atom-entry) ("socj" "http://stackoverflow.com/jobs/feed?q=clojure" "~/workspace/agenda/myTasks.org" "Job Feeds" :template "\n* %h :socj: \nCreated: %U\nOriginal: %a \n\n%description \n\n" :drawer "socj") ) org-src-preserve-indentation t org-html-format-inlinetask-function 'org-html-format-inlinetask-default-function org-pomodoro-short-break-sound "/home/andrea/.emacs.d/elpa/org-pomodoro-20161119.226/resources/bell.wav" org-agenda-files '("/home/andrea/workspace/agenda/myTasks.org") org-clock-out-hook '(org-clock-remove-empty-clock-drawer) )