;; Author: Tim Vaughan <tgvaughan@gmail.com>
;; Created: 11 April 2019
-;; Version: 2.4.0
+;; Version: 2.4.4
;; Keywords: comm gopher
-;; Homepage: https://github.com/tgvaughan/elpher
+;; Homepage: http://thelambdalab.xyz/elpher
;; Package-Requires: ((emacs "26"))
;; This file is not part of GNU Emacs.
;; - direct visualisation of image files,
;; - a simple bookmark management system,
;; - connections using TLS encryption,
-;; - basic support for the fledgling Gemini protocol.
+;; - support for the fledgling Gemini protocol.
;; To launch Elpher, simply use 'M-x elpher'. This will open a start
;; page containing information on key bindings and suggested starting
;; Full instructions can be found in the Elpher info manual.
;; Elpher is under active development. Any suggestions for
-;; improvements are welcome!
+;; improvements are welcome, and can be made on the official
+;; project page, gopher://thelambdalab.xyz/1/projects/elpher/.
;;; Code:
;;; Global constants
;;
-(defconst elpher-version "2.3.6"
+(defconst elpher-version "2.4.4"
"Current version of elpher.")
(defconst elpher-margin-width 6
""
(substring (url-filename address) 2)))
-;; Node
+;; Page
-(defun elpher-make-node (display-string address &optional parent)
- "Create a node in the page hierarchy.
-
-DISPLAY-STRING records the display string used for the page.
-
-ADDRESS specifies the address object of the page.
-
-The optional PARENT specifies the parent node in the hierarchy.
-This is set every time the node is visited, so while it forms
-an important part of the node data there is no need to set it
-initially."
- (list display-string address parent))
-
-(defun elpher-node-display-string (node)
- "Retrieve the display string of NODE."
- (elt node 0))
-
-(defun elpher-node-address (node)
- "Retrieve the ADDRESS object of NODE."
- (elt node 1))
-
-(defun elpher-node-parent (node)
- "Retrieve the parent node of NODE."
- (elt node 2))
-
-(defun elpher-set-node-parent (node parent)
- "Set the parent node of NODE to be PARENT."
- (setcar (cdr (cdr node)) parent))
;; Cache
"Set the cursor position cache for ADDRESS to POS."
(puthash address pos elpher-pos-cache))
-;; Node graph traversal
+;; Page
-(defvar elpher-current-node nil)
+(defun elpher-make-page (address display-string)
+ (list address display-string))
-(defun elpher-visit-node (node &optional renderer preserve-parent)
- "Visit NODE using its own renderer or RENDERER, if non-nil.
-Additionally, set the parent of NODE to `elpher-current-node',
-unless PRESERVE-PARENT is non-nil."
+(defun elpher-page-address (page)
+ (elt page 0))
+
+(defun elpher-page-display-string (page)
+ (elt page 1))
+
+
+(defvar elpher-current-page nil)
+(defvar elpher-history nil)
+
+(defun elpher-visit-page (page &optional renderer no-history)
+ "Visit PAGE using its own renderer or RENDERER, if non-nil.
+Additionally, push PAGE onto the stack of previously-visited pages,
+unless NO-HISTORY is non-nil."
(elpher-save-pos)
(elpher-process-cleanup)
- (unless preserve-parent
- (if (and (elpher-node-parent elpher-current-node)
- (equal (elpher-node-address elpher-current-node)
- (elpher-node-address node)))
- (elpher-set-node-parent node (elpher-node-parent elpher-current-node))
- (elpher-set-node-parent node elpher-current-node)))
- (setq elpher-current-node node)
- (let* ((address (elpher-node-address node))
+ (unless no-history
+ (push page elpher-history))
+ (setq elpher-current-page page)
+ (let* ((address (elpher-page-address node))
(type (elpher-address-type address))
(type-record (cdr (assoc type elpher-type-map))))
(if type-record
(if renderer
renderer
(cadr type-record)))
- (elpher-visit-parent-node)
+ (elpher-visit-previous-page)
(pcase type
(`(gopher ,type-char)
(error "Unsupported gopher selector type '%c' for '%s'"
(error "Unsupported address type '%S' for '%s'"
other (elpher-address-to-url address)))))))
-(defun elpher-visit-parent-node ()
+(defun elpher-visit-previous-page ()
"Visit the parent of the current node."
- (let ((parent-node (elpher-node-parent elpher-current-node)))
- (when parent-node
- (elpher-visit-node parent-node nil t))))
+ (let ((previous-page (pop elpher-history)))
+ (when previous-page
+ (elpher-visit-node previous-page nil t))))
-(defun elpher-reload-current-node ()
+(defun elpher-reload-current-page ()
"Reload the current node, discarding any existing cached content."
(elpher-cache-content (elpher-node-address elpher-current-node) nil)
(elpher-visit-node elpher-current-node))
;; Text rendering
(defconst elpher-url-regex
- "\\([a-zA-Z]+\\)://\\([a-zA-Z0-9.\-]*[a-zA-Z0-9\-]\\|\[[a-zA-Z0-9:]+\]\\)\\(:[0-9]+\\)?\\(/\\([0-9a-zA-Z\-_~?/@|:.]*[0-9a-zA-Z\-_~?/@|]\\)?\\)?"
+ "\\([a-zA-Z]+\\)://\\([a-zA-Z0-9.\-]*[a-zA-Z0-9\-]\\|\[[a-zA-Z0-9:]+\]\\)\\(:[0-9]+\\)?\\(/\\([0-9a-zA-Z\-_~?/@|:.%#]*[0-9a-zA-Z\-_~?/@|#]\\)?\\)?"
"Regexp used to locate and buttniofy URLs in text files loaded by elpher.")
(defun elpher-buttonify-urls (string)
(insert "\n"
"This page contains your bookmarked sites (also visit with B):\n")
(elpher-insert-index-record "Your Bookmarks" 'bookmarks)
+ (insert "\n"
+ "For Elpher release news or to leave feedback, visit:\n")
+ (elpher-insert-index-record "The Elpher Project Page"
+ (elpher-make-gopher-address ?1
+ "/projects/elpher/"
+ "thelambdalab.xyz"
+ 70))
(insert "\n"
"** Refer to the ")
(let ((help-string "RET,mouse-1: Open Elpher info manual (if available)"))
(insert " for the full documentation. **\n")
(insert (propertize
(concat " (This should be available if you have installed Elpher using\n"
- " MELPA. Otherwise you will have to install the manual yourself.)")
+ " MELPA. Otherwise you will have to install the manual yourself.)\n")
'face 'shadow))
(elpher-restore-pos)))