Commit Diff


commit - 6b4d9ef20633b7e62988eb86b6e18da1e67519b2
commit + 073b25eb0b22b8306c6e711aff1483a20be2f8f8
blob - f109d967bacfc70956ec2c0f243e931c24547d17
blob + b6d8c80d80f6ba9748b686f4db959340645cbdad
--- gemini.lisp
+++ gemini.lisp
@@ -79,7 +79,13 @@ response is fetched, then return the meta and the (dec
       (let ((resp (parse-response (read-until ssl-stream #\newline))))
         (values resp (read-all-stream ssl-stream))))))
 
-(defun request (url)
+(defgeneric request (url)
+  (:documentation "Perform a request for the URL"))
+
+(defmethod request ((url string))
+  (request (quri:uri url)))
+
+(defmethod request ((url quri:uri))
   (let* ((u (quri:uri url))
          (port (or (quri:uri-port u) 1965))
          (host (quri:uri-host u)))
blob - a6728f74ef17bd880c198e6055a4b47da7729ec1
blob + e60cb1bfca592cf15d1b03512995e0e754a48ee2
--- gemtext.lisp
+++ gemtext.lisp
@@ -1,5 +1,7 @@
 (in-package #:phos/gemtext)
 
+(defparameter *relative-to* nil)
+
 (defclass element ()
   ((text :initarg :text)))
 
@@ -26,8 +28,13 @@
                           :text text)))
 
 (defun make-link (url &optional text)
-  (make-instance 'link :url (quri:uri url)
-                       :text text))
+  (if *relative-to*
+      (let ((u (quri:copy-uri *relative-to*)))
+        (setf (quri:uri-path u) url)
+        (make-instance 'link :url u
+                             :text text))
+      (make-instance 'link :url (quri:uri url)
+                           :text text)))
 
 (defun parse-link (s)
   "Parse a line into link."
@@ -52,9 +59,14 @@
 (defmacro markerp (line)
   `(uiop:string-prefix-p "```" ,line))
 
-(defun parse (in)
-  "Parse gemtext from the stream IN."
+(defun parse (in &optional relative-to)
+  "Parse gemtext from the stream IN.
+
+RELATIVE-TO is the base URL of the page, it is used to transform url
+to absolute urls, if null the transformation does not happen."
   (loop with doc = nil
+        with *relative-to* = (when relative-to
+                               (quri:uri relative-to))
         for line = (read-line in nil)
         unless line
           return (nreverse doc)
@@ -68,14 +80,17 @@
                       when (markerp line)
                         return (make-instance 'verbatim
                                               :alt label
-                                              :text (format nil "~{~A~%~^~}" content))
+                                              :text (format nil "~{~A~%~^~}"
+                                                            (nreverse content)))
                       do (push line content))
                 (parse-line line))
             doc)))
 
-(defun parse-string (str)
+(defun parse-string (str &optional relative-to)
+  "Parse the string STR as gemtext.  See the documentation of `parse'
+for more info."
   (with-input-from-string (s str)
-    (parse s)))
+    (parse s relative-to)))
 
 ;; (unparse
 ;;  (with-open-file (stream #P"~/quicklisp/local-projects/phos/test.gmi")
blob - 4dd6d7ccc81049f949f9085d7d6dfb50e2ff71d9
blob + d22930faa65e7e687ff98f6626097ede18476d8f
--- package.lisp
+++ package.lisp
@@ -19,4 +19,4 @@
 
 (defpackage #:phos/ui
   (:documentation "User Interface for phos")
-  (:use #:cl #:ltk))
+  (:use #:cl #:nodgui))
blob - 0034e00ac26d68a3a2db8680e55c96e1fc5d99c4
blob + 4a5b1596b89438c292ec9ac0d0ab15ade98beb82
--- phos.asd
+++ phos.asd
@@ -6,8 +6,9 @@
   :license  "ISC"
   :version "0.0.1"
   :serial t
-  :depends-on ("quri" "cl-ppcre" "trivia" "ltk" "usocket" "cl+ssl" "cl-mime")
+  :depends-on ("quri" "cl-ppcre" "trivia" "nodgui" "usocket" "cl+ssl" "cl-mime")
   :components ((:file "package")
                (:file "phos")
                (:file "gemtext")
-               (:file "gemini")))
+               (:file "gemini")
+               (:file "ui")))
blob - dbccf3c87a5ed3b58666dac25cd29027535476e4
blob + b584cd9f422621febd835f22f0a57b9e44e58fcf
--- ui.lisp
+++ ui.lisp
@@ -1,19 +1,48 @@
 (in-package #:phos/ui)
 
+(defparameter *title-1-font* "serif 22"
+  "Font for the level 1 title.")
+
+(defparameter *title-2-font* "serif 19"
+  "Font for the level 2 title.")
+
+(defparameter *title-3-font* "serif 16"
+  "Font for the level 3 title.")
+
+(defparameter *verbatim-font* "monospace 12"
+  "Font for the verbatim element.")
+
+(defparameter *item-font* "serif 12"
+  "Font for the item.")
+
+(defparameter *link-font* "serif 12"
+  "Font for the links.")
+
+(defparameter *paragraph-font* "serif 12"
+  "Font for the normal text")
+
+(defparameter *window-content* nil)
+
+(defparameter *current-url* nil)
+
 (defgeneric render (obj frame)
-  (:documentation "Render OBJ in the ltk FRAME"))
+  (:documentation "Render OBJ in the nodgui FRAME"))
 
 (defmethod render ((l list) f)
   (dolist (el l)
     (render el f)))
 
 (defmethod render ((title gemtext:title) f)
-  (with-slots ((text phos/gemtext:text)
+  (with-slots ((text  phos/gemtext:text)
                (level phos/gemtext:level))
       title
     (let ((w (make-instance 'label
                             :master f
-                            :text (format nil "#(level ~a) ~a" level text))))
+                            :font (case level
+                                    (1 *title-1-font*)
+                                    (2 *title-2-font*)
+                                    (3 *title-3-font*))
+                            :text (format nil "~v{~A~:*~} ~a" level '("#") text))))
       (pack w :side :top))))
 
 (defmethod render ((link gemtext:link) f)
@@ -22,13 +51,18 @@
       link
     (let ((w (make-instance 'button
                             :master f
-                            :text (format nil "~a" (or text url)))))
+                            ;; :font *link-font*
+                            :text (format nil "~a" (or text url))
+                            :command (lambda ()
+                                       (format t "before rendering ~a~%" url)
+                                       (do-render url)))))
       (pack w :side :top))))
 
 (defmethod render ((item gemtext:item) f)
   (with-slots ((text phos/gemtext:text)) item
     (let ((w (make-instance 'label
                             :master f
+                            :font *item-font*
                             :text (format nil "* ~a" text))))
       (pack w :side :top))))
 
@@ -36,6 +70,7 @@
   (with-slots ((text phos/gemtext:text)) par
     (let ((w (make-instance 'label
                             :master f
+                            :font *paragraph-font*
                             :text text)))
       (pack w :side :top))))
 
@@ -45,18 +80,39 @@
       v
     (let ((w (make-instance 'label
                             :master f
-                            :text (format nil "```~a~%~a~&```"
-                                          (or alt "")
-                                          text))))
-      (pack w :side :top))))
+                            :font *verbatim-font*
+                            :text text)))
+      (pack w :side :top)
+      (when alt
+        (pack (make-instance 'label
+                             :master f
+                             :text alt)
+              :side :top)))))
 
-(defun render-page (page)
-  (with-ltk ()
-    (let ((frame (make-instance 'frame)))
-      (pack frame)
-      (render page frame))))
+(defun clear-window ()
+  (pack-forget-all *window-content*))
 
-(defvar doc (with-open-file (stream #P"~/quicklisp/local-projects/phos/test.gmi")
-              (gemtext:parse stream)))
+(defun do-render (url)
+  (let* ((uri           (quri:uri url))
+         (*current-url* uri)
+         (base          (quri:copy-uri uri)))
+    (setf (quri:uri-path base) nil)
+    (clear-window)
+    (render (gemtext:parse-string "# loading...")
+            *window-content*)
+    (clear-window)
+    (multiple-value-bind (status body) (gemini:request url)
+      (declare (ignore status))
+      (render (gemtext:parse-string body base)
+              *window-content*))))
 
-;; (render-page doc)
+(defun main (url)
+  (with-nodgui (:title "phos")
+    (let ((sf (make-instance 'scrolled-frame)))
+      (setf *window-content* (interior sf))
+      (pack sf :side :top :fill :both :expand t)
+      (do-render url))))
+
+;; (nodgui.demo:demo)
+
+;; (main "gemini://gemini.omarpolo.com/")