;;; notes-url.el --- Simplified url management routines for notes-mode ;;; Copyright (C) 1994-1998,2012 Free Software Foundation, Inc. ;; Author: ;; This file is part of GNU Emacs. ;; GNU Emacs 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. ;; GNU Emacs 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 GNU Emacs. If not, see . ;;; Commentary: ;; This code was originallly cribbed from w3.el ;; by William M. Perry , ;; but has since been completely rewritten. ;; ;; Why don't I just call his code? Because to use ;; w3-follow-link I need to pull in at least 150k of w3.el ;; and 150k of url.el, all just to open a file on the local ;; computer. Instead I've hacked his code down to the 3k ;; needed for opening local files. ;;; Code: (require 'notes-variables) (require 'notes-aux) (defvar notes-last-url nil "Last URL interpreted. This record is useful for debugging.") ;;;###autoload (defun notes-w3-url (url &optional where best-effort) "Open a notes-url. Handle simple URLs here, or call notes-w3-alternate-url. Takes the URL as an argument. Optionally you specify WHERE the information should appear (either `otherwindow' or nil, defaults to nil). BEST-EFFORT causes notes-w3-url allows the tag portion of the URL to not match. If there's no tag match, it looks for the nearest matching prefix. URLs optionally can begin with an URL: tag, which will be ignored. notes-w3-url handles only (or ) URLs. Other URLs it hands off to the routine in notes-w3-alternate-url for processing. If you use w3-mode, then (setq notes-w3-alternate-url \\='w3-follow-link) will have w3 handle tough URLs." (if (string-match "\\`[Uu][Rr][Ll]:" url) (setq url (substring url 4))) (if (not (string-match "\\`file://\\(localhost\\)?/\\(.*\\)\\'" url)) (if (string-match "none" url) (error "Notes-mode can't follow URL .") (funcall notes-w3-alternate-url url where)) ;; now, with where! (emacs-20.4) (let ((filetag (match-string 2 url)) fname tag count count-string) ;; pick out the tag, if any (if (string-match "\\`\\([^#]*\\)#\\([0-9]+\\)?\\(.*\\)\\'" filetag) (setq fname (match-string 1 filetag) count-string (match-string 2 filetag) count (if count-string (string-to-number count-string) 1) tag (match-string 3 filetag)) (setq fname filetag count 1 tag nil)) ;; Hack---url's refering to notes-index files have different tags. ;; Otherwise notes-goto-index-entry fails on subjects like "* 252A". (if (and count-string tag (string-match "/index\\'" fname)) (setq tag (concat count-string tag) count-string "1" count 1)) (if (not (string-match "\\`~" fname)) ; non-~ fnames start at fs root (setq fname (concat "/" fname))) ;; open the file (cond ((equal where 'otherwindow) (find-file-other-window fname)) (t (find-file (expand-file-name fname)))) ;; handle the tag (if tag (notes-w3-url-tag tag best-effort) t)))) (defun notes-w3-url-tag-backup (tag) "Strip the last “part” off of TAG." (let ((result) (separators " /\t.:") (buf (get-buffer-create " *notes-w3-url-tag-backup"))) (with-current-buffer buf (erase-buffer) (insert tag) (goto-char (point-max)) (skip-chars-backward (concat "^" separators)) (skip-chars-backward separators) (delete-region (point) (point-max)) (setq result (buffer-string))) (kill-buffer buf) result)) (defun notes-w3-url-tag (tag best-effort) "Find the TAG in the current buffer according to MODE. BEST-EFFORT is either t (do prefix matching), nil find the tag exactly, or `searching' (used internally)." (cond ((not tag) nil) ((and (string= tag "") (eq best-effort 'searching)) nil) (t (goto-char (point-min)) (if (re-search-forward (concat "^" (regexp-quote tag) (if (not (eq best-effort 'searching)) (if (eq major-mode 'notes-index-mode) ": " "$"))) (point-max) t count) t ;; hit (if (not best-effort) (error "Cannot find tag ``%s'' in %s." tag fname)) (notes-w3-url-tag (notes-w3-url-tag-backup tag) 'searching))))) (defun notes-w3-pass-through-alternate-url (url &optional where) "Pass a click event through to the old binding for notes-w3-url. Try this combination: (add-hook \\='notes-mode-load-hooks (function (lambda () (define-key notes-mode-map [mouse-2] \\='notes-w3-follow-link-mouse) (setq notes-w3-alternate-url \\='notes-w3-my-alternate-url))))" (let ((event last-input-event)) (funcall (lookup-key (current-global-map) (vector (car event))) event nil))) ;;;###autoload (defun notes-w3-follow-link (pt &optional where) "* Follow the URL at the point. Takes a PT to look at and a WHERE to open the URL (`otherwindow' or nil). This code works hard to recognize URLs based on context information. URLs can be quoted by whitespace, beginning and end of lines, or the official < and >. As a special case we also recognize (and skip) the text \"prev:\" and \"next:\" before the URL. Notes-mode uses these fields to link entries." (interactive "d") (let* ((whitespace-regexp "[ \t\n]") (quote-regexp whitespace-regexp) start end direction) (save-excursion ;; If we're on the URL header, skip over it so the next search works. (if (looking-at "[ quoted URL which presumably ;; follows. (This hack is to support a guy who doesn't use ;; the mouse and so looks up urls at the beginning of the line.) (if (looking-at "\\(prev\\|next\\):") (skip-chars-forward "^<" (line-end-position))) ;; Check for a quoting character. (cond ((equal (char-after (point)) ?<) (progn (setq quote-regexp ">") (forward-char 1))) ((equal (char-after (point)) ?\") (progn (setq quote-regexp "\"") (forward-char 1)))) ;; Remember start of url. (setq start (point)) ;; Search for end of url. (if (re-search-forward quote-regexp (line-end-position) 1) (forward-char -1)) (setq end (point)) ;; Interpret it (outside the save-excursion so we can go ;; to places in the same buffer). (setq notes-last-url (buffer-substring start end))) (notes-w3-url notes-last-url where))) ;;;###autoload (defun notes-w3-follow-link-mouse (e) "* Follow the URL where the mouse is." (interactive "e") (mouse-set-point e) (notes-w3-follow-link (point) (if notes-w3-follow-link-mouse-other-window 'otherwindow nil))) (provide 'notes-url) ;;; notes-url.el ends here