From b70cc28e578b4ce432d7e81dab33b60eb118ccaf Mon Sep 17 00:00:00 2001 From: solene rapenne Date: Thu, 11 Aug 2016 14:51:05 +0200 Subject: [PATCH] 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(-) create mode 100644 data/1.md delete mode 100644 data/1.txt create mode 100644 data/2.md delete mode 100644 data/2.txt create mode 100644 template/gopher_head.tpl 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 @@ -

This contains the text of the article with id 1

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 @@ -

hello

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 ! + + ----------------------------------------------------------------- +