"Return an IRI for ADDRESS.
Decode percent-escapes and handle punycode in the domain name.
Drop the password, if any."
- (let ((data (match-data))) ; Prevent parsing clobbering match data
+ (let ((data (match-data)) ; Prevent parsing clobbering match data
+ (host (url-host address))
+ (pass (url-password address)))
(unwind-protect
(let* ((host (url-host address))
(pass (url-password address)))
(setf (url-host address) (puny-decode-domain host)))
(when pass ; RFC 3986 says we should not render
(setf (url-password address) nil)) ; the password as clear text
- (url-recreate-url address))
+ (elpher-decode (url-unhex-string (url-recreate-url address))))
+ (setf (url-host address) host)
+ (setf (url-password address) pass)
(set-match-data data))))
(defvar elpher-current-page nil
(defun elpher-gemini-get-link-display-string (link-line)
"Extract the display string portion of LINK-LINE, a gemini map file link line.
-Returns the url portion in the event that the display-string portion is empty."
+Return nil if this portion is not provided."
(let* ((rest (string-trim (elt (split-string link-line "=>") 1)))
(idx (string-match "[ \t]" rest)))
- (string-trim (if idx
- (substring rest (+ idx 1))
- rest))))
+ (and idx
+ (elpher-color-filter-apply (string-trim (substring rest (+ idx 1)))))))
(defun elpher-collapse-dot-sequences (filename)
"Collapse dot sequences in the (absolute) FILENAME.
(defun elpher-gemini-insert-link (link-line)
"Insert link described by LINK-LINE into a text/gemini document."
- (let* ((url (elpher-gemini-get-link-url link-line))
- (display-string (elpher-gemini-get-link-display-string link-line))
- (address (elpher-address-from-gemini-url url))
- (type (if address (elpher-address-type address) nil))
- (type-map-entry (cdr (assoc type elpher-type-map)))
- (fill-prefix (make-string (+ 1 (length elpher-gemini-link-string)) ?\s)))
- (when display-string
- (insert elpher-gemini-link-string)
- (if type-map-entry
- (let* ((face (elt type-map-entry 3))
- (filtered-display-string (elpher-color-filter-apply display-string))
- (page (elpher-make-page filtered-display-string address)))
- (insert-text-button filtered-display-string
- 'face face
- 'elpher-page page
- 'action #'elpher-click-link
- 'follow-link t
- 'help-echo #'elpher--page-button-help))
- (insert (propertize display-string 'face 'elpher-unknown)))
- (newline))))
-
-(defvar elpher--gemini-page-headings nil
- "List of headings on the page.")
+ (let ((url (elpher-gemini-get-link-url link-line)))
+ (when url
+ (let* ((given-display-string (elpher-gemini-get-link-display-string link-line))
+ (address (elpher-address-from-gemini-url url))
+ (type (if address (elpher-address-type address) nil))
+ (type-map-entry (cdr (assoc type elpher-type-map)))
+ (fill-prefix (make-string (+ 1 (length elpher-gemini-link-string)) ?\s))
+ (insert elpher-gemini-link-string))
+ (if type-map-entry
+ (let* ((face (elt type-map-entry 3))
+ (display-string (or given-display-string
+ (elpher-address-to-iri address)))
+ (page (elpher-make-page display-string
+ address)))
+ (insert-text-button display-string
+ 'face face
+ 'elpher-page page
+ 'action #'elpher-click-link
+ 'follow-link t
+ 'help-echo #'elpher--page-button-help))
+ (insert (propertize display-string 'face 'elpher-unknown)))
+ (newline)))))
(defun elpher-gemini-insert-header (header-line)
"Insert header described by HEADER-LINE into a text/gemini document.
(/ (* fill-column
(font-get (font-spec :name (face-font 'default)) :size))
(font-get (font-spec :name (face-font face)) :size)) fill-column)))
- (setq elpher--gemini-page-headings (cons (cons header (point))
- elpher--gemini-page-headings))
(unless (display-graphic-p)
(insert (make-string level ?#) " "))
- (insert (propertize header 'face face 'rear-nonsticky t))
+ (insert (propertize header
+ 'face face
+ 'gemini-heading t
+ 'rear-nonsticky t))
(newline))))
(defun elpher-gemini-insert-text (text-line)
(defun elpher-render-gemini-map (data _parameters)
"Render DATA as a gemini map file, PARAMETERS is currently unused."
(elpher-with-clean-buffer
- (setq elpher--gemini-page-headings nil)
(let ((preformatted nil))
(auto-fill-mode 1)
(setq-local fill-column (min (window-width) elpher-gemini-max-fill-width))
(elpher-gemini-insert-link line))
((string-prefix-p "#" line) (elpher-gemini-insert-header line))
(t (elpher-gemini-insert-text line)))))
- (setq elpher--gemini-page-headings (nreverse elpher--gemini-page-headings))
(elpher-cache-content
(elpher-page-address elpher-current-page)
(buffer-string))))
(elpher-page-address elpher-current-page)
(buffer-string))))
+(defun elpher-build-current-imenu-index ()
+ (save-excursion
+ (goto-char (point-min))
+ (let ((match nil)
+ (headers nil))
+ (while (setq match (text-property-search-forward 'gemini-heading t t))
+ (push (cons
+ (buffer-substring-no-properties (prop-match-beginning match)
+ (prop-match-end match))
+ (prop-match-beginning match))
+ headers))
+ (reverse headers))))
;; Finger page connection
This mode is automatically enabled by the interactive
functions which initialize the client, namely
`elpher', and `elpher-go'."
- (setq-local elpher--gemini-page-headings nil)
(setq-local elpher-current-page nil)
(setq-local elpher-history nil)
(setq-local elpher-buffer-name (buffer-name))
(setq-local bookmark-make-record-function #'elpher-bookmark-make-record)
- (setq-local imenu-create-index-function (lambda () elpher--gemini-page-headings))
+ (setq-local imenu-create-index-function #'elpher-build-current-imenu-index)
(setq-local xterm-color-preserve-properties t))
(when (fboundp 'evil-set-initial-state)