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 b70cc28e578b4ce432d7e81dab33b60eb118ccaf
solene rapenne <solene@dataswamp.org>
2016-08-11 14:51:05 +0200

Gopher export available

 Makefile                 | 32 ++++++++++++++++++--------
 README.md                | 34 +++++++++++++---------------
 data/1.md                |  1 +
 data/1.txt               |  1 -
 data/2.md                |  1 +
 data/2.txt               |  1 -
 data/articles.lisp       |  4 ++++
 generator.lisp           | 58 ++++++++++++++++++++++++++++++++++++++----------
 template/gopher_head.tpl |  5 +++++
 9 files changed, 95 insertions(+), 42 deletions(-)
diff --git a/Makefile b/Makefile
index 55a0d29..d4a2f71 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,9 @@
-LISP=clisp
-PARAM=
+LISP=          sbcl
+MD=            multimarkdown -o
+
+HTMLDIR=       temp/data
+ARTICLES!=     ls data/*.md
+HTML=          $(ARTICLES:.md=.html)
 
 .if "${LISP}" == "sbcl"
 PARAM=--dynamic-space-size 60 --script
@@ -9,14 +13,24 @@ PARAM=
 PARAM=-shell
 .endif
 
-all:
-	mkdir -p output/static
-	cp -fr static/* output/static/
-	LANG=POSIX.UTF-8 $(LISP) $(PARAM) generator.lisp
+all: clean dirs html
+
+html: $(HTML) css
+	LANG=en_US.UTF-8 $(LISP) $(PARAM) generator.lisp
+	rm -fr "temp"
+
+dirs:
+	mkdir -p "$(HTMLDIR)"
+	mkdir -p "output/html/static"
+	mkdir -p "output/gopher"
+
+.SUFFIXES: .md .html
+.md.html:
+	$(MD) "$(HTMLDIR)/$(@F)" "$<"
 
 clean:
-	rm -fr output/*
+	rm -fr output/html/* output/gopher/* "temp"
 
 css:
-	mkdir -p output/static
-	cp -fr static/* output/static/	
+	mkdir -p "output/html/static"
+	cp -fr static/* "output/html/static/"
diff --git a/README.md b/README.md
index ab9e31a..e91494a 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
 # Introduction
 
-cl-yag stands for Common Lisp Yet Another Generator and obviously it's written in Common Lisp.
+cl-yag stands for Common Lisp Yet Another Generator and obviously it's written in Common Lisp. Currently, cl-yag can generate **gopher** and **html** website.
 
-It has only one dependency : a common lisp interpreter. It is regularly tested with sbcl, clisp and ecl which are free, open-source and multi-platform. You don't need quicklisp library manager.
+**It needs a Common Lisp interpreter and a markdown-to-html export tool (like multimarkdown).**
+It is regularly tested with sbcl, clisp and ecl which are free, open-source and multi-platform. You don't need quicklisp library manager.
 
 **This comes with a minimalistic template**, don't expect something good looking without work. You will have to write the CSS entirely and modify the html to fit your need.
 
-As a "demo", there is [my website](https://dataswamp.org/~solene/) using cl-yag.
+As a "demo", there is [my website](https://dataswamp.org/~solene/) using cl-yag for html version, and [my gopher](gopher://perso.pw/) for gopher version.
 
 ## The hierarchy
 
@@ -18,8 +19,10 @@ Here are the files and folder of cl-yag :
 + **static/** : contains the static files like images, css, js etc... that will be published
 + **data/** : 
   + **articles.lisp** : contains metadata about the website and the list of the articles with their id/title/date/tag/*author*/*short description* (fields in *italic* are not mandatory)
-  + **${id}.txt** : contains the html text of the article ${id} that will be used when displayed
-+ **output** : folder where the website is generated when your run *make*. It is cleaned when you run *make clean*; You can make it a symbolic link to the web server folder.
+  + **${id}.md** : contains the article using markdown syntax that will be used when exported
++ **output/** :
+  + **gopher/** : contains the exported website for gopher
+  + **html/** : contains the exported website in html
 
 # Usage
 
@@ -32,6 +35,10 @@ In data/articles.lisp there is a ***config*** variable with the following fields
 + **:description** : This text is used in the *description* field of the Atom RSS
 + **:url** : This is the full url of the blog with the final slash. If the url contains a ~ it should be doubled (e.g. : https://mydomain/~~user/ is a valid url)
 + **:rss-item-number** : This is the number of RSS items you want to published when you generate the files, it will publish the last N articles
++ **html** : t to export html website / nil to disable
++ **gopher** : t to export gopher website / nil to disable
++ **gopher-server**: hostname of the gopher server because gopher doesn't have relative links like html, so you need to know where you put your files
++ **gopher-port** : tcp port of the gopher server, 70 is the default port, it's included in every link as explained in gopher-server
 
 ## How to add an article
  
@@ -53,7 +60,9 @@ The _:tag_ field is used to create a page with all the articles with the same ta
 
 ## How to publish
 
-There is a makefile, all you need to do is to type "make" in the folder, this will create the files in the **output/** location (which can be a symbolic link to somewhere else). If you want to use a different lisp interpreter (default is **sbcl**), you can set the variable LISP to the name of your binary. 
+There is a makefile, all you need to do is to type "make" in the folder, this will create the files in the **output/** location (which can be a symbolic link to somewhere else). The Gopher website will be generated inside **output/gopher** and the html will be generated in **output/html**.
+
+If you want to use a different lisp interpreter (default is **sbcl**), you can set the variable LISP to the name of your binary. 
 
 Example with clisp : 
 
@@ -85,19 +94,6 @@ In **generate-site** function we can load a file, apply the template and save it
   
 This will produce the file **somepage.html** in the output folder.
 
- 
-# How to use markdown for articles
-
- 
-Here is a tip to produce html files from markdown using emacs
-
-1. edit the article file with emacs using ham-mode which will convert the html to markdown
-2. write your text with markdown syntax 
-3. save your file, ham-mode will convert it back to html
-4. run *make* to update your site
-
-The generator don't do it natively because I didn't want it to have dependencies. You can use what you want to produces the html files.
-
 # Known limitations
 
 ## Use of ~ character
diff --git a/data/1.md b/data/1.md
new file mode 100644
index 0000000..7773de5
--- /dev/null
+++ b/data/1.md
@@ -0,0 +1 @@
+This contains the text of the article with id 1
diff --git a/data/1.txt b/data/1.txt
deleted file mode 100644
index c5f482c..0000000
--- a/data/1.txt
+++ /dev/null
@@ -1 +0,0 @@
-<p>This contains the text of the article with id 1</p>
diff --git a/data/2.md b/data/2.md
new file mode 100644
index 0000000..917bbde
--- /dev/null
+++ b/data/2.md
@@ -0,0 +1 @@
+**hello in bold**
diff --git a/data/2.txt b/data/2.txt
deleted file mode 100644
index 302a01f..0000000
--- a/data/2.txt
+++ /dev/null
@@ -1 +0,0 @@
-<p>hello</p>
diff --git a/data/articles.lisp b/data/articles.lisp
index 7b6f9c1..a279aab 100644
--- a/data/articles.lisp
+++ b/data/articles.lisp
@@ -11,6 +11,10 @@
    :description "Yet another website on the net"
    :url "https://my.website/~~user/" ;; the trailing slash is mandatory, rss links will fails without it
    :rss-item-number 10 ;; we want 10 items in our RSS feed
+   :html t ;; t to export html website / nil to disable
+   :gopher t ;; t to export gopher website / nil to disable
+   :gopher-server "my.website" ;; hostname of the gopher server
+   :gopher-port "70" ;; tcp port of the gopher server, 70 usually
    ))
 
 ;; describes articles (ordered on the website as they are displayed here, the first in list is the top of the website)
diff --git a/generator.lisp b/generator.lisp
index c800524..8742edf 100644
--- a/generator.lisp
+++ b/generator.lisp
@@ -43,7 +43,7 @@
 
 ;; save a string in a file
 (defun save-file(path data)
-  (with-open-file (stream (concatenate 'string "output/" path) :direction :output :if-exists :supersede)
+  (with-open-file (stream path :direction :output :if-exists :supersede)
     (format stream data)))
 
 ;; simplify the str replace work
@@ -103,7 +103,7 @@
 	   (template "%%Tags%%" (get-tag-list-article article))
 	   (template "%%Text%%" (if (and tiny (member :tiny article))
 				    (getf article :tiny)
-				  (load-file (format nil "data/~d.txt" (getf article :id)))))))
+				  (load-file (format nil "temp/data/~d.html" (getf article :id)))))))
 
 ;; return a html string
 ;; produce the code of a whole page with title+layout with the parameter as the content
@@ -136,7 +136,7 @@
 	 collect
 	 (prepare "template/rss-item.tpl"
 		  (template "%%Title%%" (getf article :title))
-		  (template "%%Description%%" (load-file (format nil "data/~d.txt" (getf article :id))))
+		  (template "%%Description%%" (load-file (format nil "temp/data/~d.html" (getf article :id))))
 		  (template "%%Url%%"
 			    (format nil "~darticle-~d.html"
 				    (getf *config* :url)
@@ -151,27 +151,61 @@
 	   (template "%%Items%%" (generate-rss-item))))
 
 
-;; ENGINE START !
-;; This is function called when running the tool
-(defun generate-site()
-
+;; We do all the website
+(defun create-html-site()
   ;; produce index.html
-  (generate "index.html" (generate-semi-mainpage))
+  (generate "output/html/index.html" (generate-semi-mainpage))
   
   ;; produce each article file
   (dolist (article *articles*)
-    (generate (format nil "article-~d.html" (getf article :id))
+    (generate (format nil "output/html/article-~d.html" (getf article :id))
 	      (create-article article :tiny nil)
 	      :title (concatenate 'string (getf *config* :title) " : " (getf article :title))))
-
+  
   ;; produce index file for each tag
   (loop for tag in (articles-by-tag) do
-	(generate (format nil"tag-~d.html" (getf tag :NAME))
+	(generate (format nil "output/html/tag-~d.html" (getf tag :NAME))
 		  (generate-tag-mainpage (getf tag :VALUE))))
   
   ;;(generate-file-rss)
-  (save-file "rss.xml" (generate-rss))
+  (save-file "output/html/rss.xml" (generate-rss)))
+
+;; we do all the gopher hole
+(defun create-gopher-hole()
+
+  ;; produce the gophermap file
+  (save-file "output/gopher/gophermap"
+	     (let ((output (load-file "template/gopher_head.tpl")))
+	       (dolist (article *articles*)
+		 (setf output
+		       (concatenate 'string output
+				    (format nil "~a by ~a tagged (~a) ~%0~a	/article-~d.txt	~a	~a~%~%"
+					    (getf article :date)
+					    (getf article :author (getf *config* :webmaster))
+					    (getf article :tag)
+					    (getf article :title)
+					    (getf article :id)
+					    (getf *config* :gopher-server)
+					    (getf *config* :gopher-port)
+					    ))))
+	       output))
+  
+  ;; produce each article file (only a copy/paste in fact)
+  (dolist (article *articles*)
+    (let ((id (getf article :id)))
+      (save-file (format nil "output/gopher/article-~d.txt" id)
+		 (load-file (format nil "data/~d.md" id)))))
   
   )
 
+
+;; ENGINE START !
+;; This is function called when running the tool
+(defun generate-site()
+  (if (getf *config* :html)
+      (create-html-site))
+  (if (getf *config* :gopher)
+      (create-gopher-hole)))
+
 (generate-site)
+
diff --git a/template/gopher_head.tpl b/template/gopher_head.tpl
new file mode 100644
index 0000000..5b990d2
--- /dev/null
+++ b/template/gopher_head.tpl
@@ -0,0 +1,5 @@
+Hello, this is the head of your gophermap page, you can
+customize it how you want !
+
+ -----------------------------------------------------------------
+