Recently Written · git

cl-yag

Mirror and rewrite of Solène Rapenne's cl-yag SSG of renown

git clone https://github.com/equwal/cl-yag

Log | Files | Refs


commit a9cc963e39455b4f75af129ca00d635a02fc1702
Solene Rapenne <solene@perso.pw>
2020-11-30 21:46:43 +0100

Add gemini export

 Makefile                  |  1 +
 data/README.md            | 22 ++++++++++-----
 data/articles.lisp        |  3 +++
 generator.lisp            | 68 +++++++++++++++++++++++++++++++++++++++++++++++
 templates/gemini_head.tpl |  6 +++++
 templates/gopher_head.tpl |  2 +-
 6 files changed, 94 insertions(+), 8 deletions(-)
diff --git a/Makefile b/Makefile
index cf8981e..bf8741e 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ html: $(HTML) css
 dirs:
 	mkdir -p "output/html/static"
 	mkdir -p "output/gopher"
+	mkdir -p "output/gemini/articles/"
 
 
 clean:
diff --git a/data/README.md b/data/README.md
index a578d7e..f9e98c5 100644
--- a/data/README.md
+++ b/data/README.md
@@ -51,13 +51,15 @@ least the following files and folders:
 	|   `-- articles.lisp
 	|-- generator.lisp
 	|-- output/
-	|   |-- gopher/
+	|   |-- gemini/
+   	|   |-- gopher/
 	|   `-- html/
 	|-- static/
 	|   |-- css/style.css
 	|   `-- img/
 	`-- templates/
 		|-- article.tpl
+		|-- gemini_head.tpl
 		|-- gopher_head.tpl
 		|-- layout.tpl
 		|-- one-tag.tpl
@@ -129,6 +131,12 @@ The *config* variable is used to assign the following values:
     - ``t`` to export html website. Set ``nil`` to disable.
 - **gopher**
     - ``t`` to export gopher website. Set ``nil`` to disable.
+- **gemini**
+    - ``t`` to export gemini capsule. Set ``nil`` to disable.
+- **gemini-path**
+    - This is the absolute public gemini url.
+- **gemini-index**
+    - This is the name of the index file. Default is ``index.md``
 - **gopher-path**
     - This is the full path of the directory to access your gopher hole.
 - **gopher-server**
@@ -187,9 +195,9 @@ publishing your static sites.
 All you need to do in order to publish is to go into your cl-yag
 directory and type ``make``.
 
-The make command creates html and gopher files in the defined location.
-The default is the **output/** directory, but you can use a symbolic link
-pointing to some other directory as well.
+The make command creates html, gemini and gopher files in the defined
+location.  The default is the **output/** directory, but you can use a
+symbolic link pointing to some other directory as well.
 
 
 ## Howto Add A New Page
@@ -261,8 +269,8 @@ displays: "Tags: ".
 ### A Note On Themes
 
 Although cl-yag may ship with a minimalistic template, cl-yag focuses
-on generating html- and gopher-compliant structural markup - not
-themed layouts.
+on generating html-, gemini and gopher-compliant structural markup -
+not themed layouts.
 
 If you want some deeply refined, cross-browser compatible, responsive,
 webscale style sheets, you need to create them yourself.  However,
@@ -272,7 +280,7 @@ style sheets a part of cl-yag you're very welcome to contact me.
 
 # Hacking cl-yag
 
-I tried to make cl-yag easy to extend.  
+I tried to make cl-yag easy to extend.
 If you want to contribute, feel free to contact me and/or to send in a patch.
 
 - If you are looking for a way to contribute:
diff --git a/data/articles.lisp b/data/articles.lisp
index 91acc08..84196e1 100644
--- a/data/articles.lisp
+++ b/data/articles.lisp
@@ -14,6 +14,9 @@
    :default-converter :markdown2
    :html   t                                            ;; 't' to enable export to a html website / 'nil' to disable
    :gopher t                                            ;; 't' to enable export to a gopher website / 'nil' to disable
+   :gemini t                                            ;; 't' to enable export to a gemini capsule / 'nil' to disable
+   :gemini-path      "gemini://perso.pw/blog/"          ;; absolute path of your gemini capsule
+   :gemini-index     "index.md"                         ;; filename of index file
    :gopher-path      "/user"                            ;; absolute path of your gopher directory
    :gopher-server    "my.website"                       ;; hostname of the gopher server
    :gopher-port      "70"                               ;; tcp port of the gopher server, 70 usually
diff --git a/generator.lisp b/generator.lisp
index bb801f6..38523b6 100644
--- a/generator.lisp
+++ b/generator.lisp
@@ -173,6 +173,19 @@
   `(progn
      (save-file ,name (generate-layout ,@data))))
 
+;; generate a gemini index file
+(defun generate-gemini-index(articles)
+  (let ((output (load-file "templates/gemini_head.tpl")))
+    (dolist (article articles)
+      (setf output
+	    (string
+	     (concatenate 'string output
+                          (format nil "=> ~a/articles/~a.txt ~a~%"
+                                  (getf *config* :gemini-path)
+                                  (article-id article)
+                                  (article-title article))))))
+    output))
+
 ;; generate a gopher index file
 (defun generate-gopher-index(articles)
   (let ((output (load-file "templates/gopher_head.tpl")))
@@ -339,6 +352,59 @@
   ;;(generate-file-rss)
   (save-file "output/html/rss.xml" (generate-rss)))
 
+;; we do all the gemini capsule
+(defun create-gemini-capsule()
+
+  ;; produce the index.md file
+  (save-file (concatenate 'string "output/gemini/" (getf *config* :gemini-index))
+             (generate-gemini-index *articles*))
+
+  ;; produce a tag list menu
+  (let* ((directory-path "output/gemini/_tags_/")
+         (index-path (concatenate 'string directory-path (getf *config* :gemini-index))))
+    (ensure-directories-exist directory-path)
+    (save-file index-path
+               (let ((output (load-file "templates/gemini_head.tpl")))
+                 (loop for tag in
+                      ;; sort tags per articles in it
+                      (sort (articles-by-tag) #'>
+                            :key #'(lambda (x) (length (getf x :value))))
+                    do
+                      (setf output
+	                    (string
+	                     (concatenate
+                              'string output
+                              (format nil "=> ~a/~a/index.md ~a ~d~%"
+                                      (getf *config* :gemini-path)
+                                      (getf tag :name)
+                                      (getf tag :name)
+                                      (length (getf tag :value)))))))
+                 output)))
+
+  ;; produce each tag gemini index
+  (loop for tag in (articles-by-tag) do
+       (let* ((directory-path (concatenate 'string "output/gemini/" (getf tag :NAME) "/"))
+              (index-path (concatenate 'string directory-path (getf *config* :gemini-index)))
+              (articles-with-tag (loop for article in *articles*
+                                    when (member (article-id article) (getf tag :VALUE) :test #'equal)
+                                    collect article)))
+         (ensure-directories-exist directory-path)
+         (save-file index-path (generate-gemini-index articles-with-tag))))
+
+  ;; produce each article file (adding some headers)
+  (loop for article in *articles*
+     do
+       (with-converter
+	   (let ((id (article-id article)))
+	     (save-file (format nil "output/gemini/articles/~a.txt" id)
+                        (format nil "~{~a~}"
+                                (list
+                                 "Title : " (article-title article) #\Newline
+                                 "Author: " (article-author article) #\Newline
+                                 "Date  : " (date-format (getf *config* :date-format) (article-date article)) #\Newline
+                                 "Tags  : " (article-tag article) #\Newline #\Newline
+		                 (load-file (format nil "data/~d~d" id (converter-extension converter-object))))))))))
+
 ;; we do all the gopher hole
 (defun create-gopher-hole()
 
@@ -410,6 +476,8 @@
 (defun generate-site()
   (if (getf *config* :html)
       (create-html-site))
+  (if (getf *config* :gemini)
+      (create-gemini-capsule))
   (if (getf *config* :gopher)
       (create-gopher-hole)))
 
diff --git a/templates/gemini_head.tpl b/templates/gemini_head.tpl
new file mode 100644
index 0000000..8845c90
--- /dev/null
+++ b/templates/gemini_head.tpl
@@ -0,0 +1,6 @@
+Hello, this is the head of your gophermap page, you can
+customize it how you want !
+
+=> /index.md Home
+
+------------------------------------------------------------------
diff --git a/templates/gopher_head.tpl b/templates/gopher_head.tpl
index a2fbef5..190e261 100644
--- a/templates/gopher_head.tpl
+++ b/templates/gopher_head.tpl
@@ -2,7 +2,7 @@ Hello, this is the head of your gophermap page, you can
 customize it how you want !
 
 [0|RSS Feed|/~me/rss.xml|server|port]
-[1|Phlog index|/~me/|server|port]
+[1|Phlog index|/~me/|server|port]i
 [1|Browse by tag|/~me/_tags_/|server|port]
 
  -----------------------------------------------------------------