X-Git-Url: https://thelambdalab.xyz/gitweb/index.cgi?p=elpher.git;a=blobdiff_plain;f=elpher.el;h=75ae255ab6aa79c6ef7305e312997af3a72508fb;hp=c3e311fe1cc77eea51dfe46283ea7835920d7f41;hb=0243aa0a1d9ab09ad270b5d3ce6372bbf8c83e15;hpb=98b62fff557b13235be5c39aa0f183494b389b32 diff --git a/elpher.el b/elpher.el index c3e311f..75ae255 100644 --- a/elpher.el +++ b/elpher.el @@ -1,10 +1,10 @@ -;;; elpher.el --- A friendly gopher client. -*- lexical-binding:t -*- +;;; elpher.el --- A friendly gopher client -*- lexical-binding:t -*- ;; Copyright (C) 2019 Tim Vaughan ;; Author: Tim Vaughan ;; Created: 11 April 2019 -;; Version: 2.4.4 +;; Version: 2.5.0 ;; Keywords: comm gopher ;; Homepage: http://thelambdalab.xyz/elpher ;; Package-Requires: ((emacs "26")) @@ -37,7 +37,7 @@ ;; - direct visualisation of image files, ;; - a simple bookmark management system, ;; - connections using TLS encryption, -;; - support for the fledgling Gemini protocol. +;; - 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 @@ -67,7 +67,7 @@ ;;; Global constants ;; -(defconst elpher-version "2.4.4" +(defconst elpher-version "2.5.0" "Current version of elpher.") (defconst elpher-margin-width 6 @@ -163,10 +163,6 @@ Otherwise, use the system browser via the BROWSE-URL function." :type '(boolean)) -(defcustom elpher-buttonify-urls-in-directories t - "If non-nil, turns URLs matched in directories into clickable buttons." - :type '(boolean)) - (defcustom elpher-use-header t "If non-nil, display current page information in buffer header." :type '(boolean)) @@ -181,6 +177,11 @@ allows switching from an encrypted channel back to plain text without user input "Specifies the number of seconds to wait for a network connection to time out." :type '(integer)) +(defcustom elpher-strip-ansi-from-text t + "If non-nil, strip ANSI escape sequences from gopher menus and text/gemini files. +This is occasionally desirable, as these sequences are not understood natively by +Emacs, and tend to result in a garbled display." + :type '(boolean)) ;;; Model ;; @@ -627,9 +628,7 @@ If ADDRESS is not supplied or nil the record is rendered as an (elpher-insert-margin) (let ((propertized-display-string (propertize display-string 'face 'elpher-info))) - (insert (if elpher-buttonify-urls-in-directories - (elpher-buttonify-urls propertized-display-string) - propertized-display-string)))) + (insert (elpher-process-text-for-display propertized-display-string)))) (`(gopher ,selector-type) ;; Unknown (elpher-insert-margin (concat (char-to-string selector-type) "?")) (insert (propertize display-string @@ -653,8 +652,8 @@ If ADDRESS is not supplied or nil the record is rendered as an ;; 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\-_~?/@|#]\\)?\\)?" - "Regexp used to locate and buttniofy URLs in text files loaded by elpher.") + "\\([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 buttinofy URLs in text files loaded by elpher.") (defun elpher-buttonify-urls (string) "Turn substrings which look like urls in STRING into clickable buttons." @@ -673,12 +672,32 @@ If ADDRESS is not supplied or nil the record is rendered as an 'face 'button))) (buffer-string))) +(defconst elpher-ansi-regex "\x1b\\[[^m]*m" + "Wildly incomplete regexp used to strip out some troublesome ANSI escape sequences.") + +(defun elpher-strip-ansi (string) + "Strip ANSI escape codes from STRING." + (with-temp-buffer + (insert string) + (goto-char (point-min)) + (while (re-search-forward elpher-ansi-regex nil t) + (delete-region (match-beginning 0) (match-end 0))) + (buffer-string))) + + +(defun elpher-process-text-for-display (string) + "Perform any desired processing of text prior to display. +Currently includes buttonifying URLs and optionally stripping ANSI escape codes." + (elpher-buttonify-urls (if elpher-strip-ansi-from-text + (elpher-strip-ansi string) + string))) + (defun elpher-render-text (data &optional _mime-type-string) "Render DATA as text. MIME-TYPE-STRING is unused." (elpher-with-clean-buffer (if (not data) t - (insert (elpher-buttonify-urls (elpher-preprocess-text-response data))) + (insert (elpher-process-text-for-display (elpher-preprocess-text-response data))) (elpher-cache-content (elpher-page-address elpher-current-page) (buffer-string))))) @@ -1009,7 +1028,7 @@ For instance, the filename /a/b/../c/./d will reduce to /a/c/d" (defun elpher-render-gemini-plain-text (data _parameters) "Render DATA as plain text file. PARAMETERS is currently unused." (elpher-with-clean-buffer - (insert (elpher-buttonify-urls data)) + (insert (elpher-process-text-for-display data)) (elpher-cache-content (elpher-page-address elpher-current-page) (buffer-string)))) @@ -1235,15 +1254,15 @@ If ADDRESS is already bookmarked, update the label only." (interactive) (push-button)) -(defun elpher-go () - "Go to a particular gopher site read from the minibuffer." - (interactive) - (let ((page - (let ((host-or-url (read-string "Gopher or Gemini URL: "))) - (elpher-make-page host-or-url - (elpher-address-from-url host-or-url))))) +(defun elpher-go (host-or-url) + "Go to a particular gopher site HOST-OR-URL. +When run interactively HOST-OR-URL is read from the minibuffer." + (interactive "sGopher or Gemini URL: ") + (let ((page (elpher-make-page host-or-url + (elpher-address-from-url host-or-url)))) (switch-to-buffer "*elpher*") - (elpher-visit-page page))) + (elpher-visit-page page) + '())) (defun elpher-go-current () "Go to a particular site read from the minibuffer, initialized with the current URL."