summaryrefslogtreecommitdiff
path: root/.config/nyxt/unpdf.lisp
diff options
context:
space:
mode:
authorThanos Apollo <[email protected]>2023-09-27 02:10:25 +0300
committerThanos Apollo <[email protected]>2023-09-27 02:10:25 +0300
commit47b73144d1b30514df003560851de3bd06e88b81 (patch)
tree27b0b2e914c6867d90f6ce456b123606803a8a09 /.config/nyxt/unpdf.lisp
parent696a16039e28e5844a164d69f60006b9c11a0067 (diff)
[New] Add nyxt, slightly modified config from aartaka
Diffstat (limited to '.config/nyxt/unpdf.lisp')
-rw-r--r--.config/nyxt/unpdf.lisp86
1 files changed, 86 insertions, 0 deletions
diff --git a/.config/nyxt/unpdf.lisp b/.config/nyxt/unpdf.lisp
new file mode 100644
index 0000000..8b46457
--- /dev/null
+++ b/.config/nyxt/unpdf.lisp
@@ -0,0 +1,86 @@
+(in-package #:nyxt-user)
+
+;; I'm definining a new scheme to redirect PDF requests to. What it does is:
+;; - Get the original file (if the URL is a filesystem path, simply use it).
+;; - Save it to disk (if remote).
+;; - Run pdftotext over the file.
+;; - Display pdftotext output in a nice HTML page with interlinkable
+;; page numbers and page contents as <pre> tags.
+(define-internal-scheme "unpdf"
+ (lambda (url buffer)
+ (let* ((url (quri:uri url))
+ (original-url (quri:uri (quri:url-decode (quri:uri-path url))))
+ (local-p (or (null (quri:uri-scheme original-url))
+ (string= "file" (quri:uri-scheme original-url))))
+ (original-content (unless local-p
+ (dex:get (quri:render-uri original-url) :force-binary t))))
+ (flet ((display-pdf-contents (file)
+ (if (uiop:file-exists-p file)
+ (let ((pages (ignore-errors
+ (uiop:split-string
+ (uiop:run-program `("pdftotext" "-nodiag" ,(uiop:native-namestring file) "-")
+ :output '(:string :stripped t))
+ :separator '(#\Page)))))
+ (spinneret:with-html-string
+ (:head
+ (:style (style buffer))
+ ;; A class to override the <pre> colors.
+ (:style (theme:themed-css (theme *browser*)
+ #+(or nyxt-2 nyxt-3-pre-release-1)
+ (.override
+ :background-color theme:background
+ :color theme:on-background
+ :font-size "150%"
+ :line-height "150%")
+ #+(and nyxt-3 (not (or nyxt-2 nyxt-3-pre-release-1)))
+ `(.override
+ :background-color ,theme:background
+ :color ,theme:on-background
+ :font-size "150%"
+ :line-height "150%"))))
+ (loop for page in pages
+ for number from 1
+ unless (uiop:emptyp page)
+ do (:section
+ :id (princ-to-string number)
+ (:h2.override (:a :href (format nil "#~d" number)
+ (princ-to-string number)))
+ (:pre.override (or page ""))))))
+ "")))
+ (if local-p
+ (display-pdf-contents (pathname (quri:uri-path original-url)))
+ (uiop:with-temporary-file (:pathname path :type "pdf" :keep t)
+ (log:debug "Temp file for ~a is ~a" url path)
+ (alexandria:write-byte-vector-into-file
+ (coerce original-content '(vector (unsigned-byte 8))) path :if-exists :supersede)
+ (display-pdf-contents path))))))
+ :local-p t)
+
+(define-command-global unpdf-download-this ()
+ "A helper for unpdf: pages to download the original PDF to the regular destination.
+
+Unpdf redirects all requests, even those that you need to read
+elsewhere, thus I need this command."
+ (let* ((buffer (current-buffer))
+ (url (url buffer)))
+ (if (string= "unpdf" (quri:uri-scheme url))
+ (ffi-buffer-download buffer (quri:uri-path url))
+ ;; I need to turn it into a mode someday...
+ (echo-warning "This command is for unpdf: pages only, it's useless elsewhere!"))))
+
+(defun redirect-pdf (request-data)
+ (if (and (toplevel-p request-data)
+ (uiop:string-prefix-p "application/pdf" (mime-type request-data)))
+ ;; I should somehow prompt about downloading instead...
+ (progn
+ (echo "Redirecting to the unpdf URL...")
+ (make-buffer-focus :url (quri:uri (str:concat "unpdf:" (render-url (url request-data)))))
+ ;; Return nil to prevent Nyxt from downloading this PDF.
+ nil)
+ request-data))
+
+(define-configuration :web-buffer
+ ((request-resource-hook (hooks:add-hook %slot-value% 'redirect-pdf))))
+
+(define-configuration nyxt/mode/file-manager:file-source
+ ((supported-media-types `("pdf" ,@%slot-value%))))