From 52bd9a828bdd422d4c4ec8fbd30ba8f5ef253e76 Mon Sep 17 00:00:00 2001 From: Solene Rapenne Date: Wed, 13 Dec 2017 12:08:57 +0100 Subject: [PATCH] Cleaner code using structure for storing articles metadata Posts are declared individually with a function instead of modifying a global variable, this is much cleaner. Gopher index format and index file name can be customized in the config file, no need to tweak generator.lisp anymore Tell multimarkdown to export to html, specifying the output format is now mandatory in multimarkdown Examples of the future way to handle multiple markup language by declaring converters --- Makefile | 2 +- README.md | 31 +++++++++++++++----------- data/1.md | 4 +++- data/README.md | 31 +++++++++++++++----------- data/articles.lisp | 55 +++++++++++++++++++++++++++------------------- generator.lisp | 15 ++++++++++--- 6 files changed, 84 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index 788e4d1..25805ce 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ LISP= sbcl -MD= multimarkdown -o +MD= multimarkdown -t html -o HTMLDIR= temp/data ARTICLES!= ls data/*.md diff --git a/README.md b/README.md index 590efb8..a578d7e 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,18 @@ ## Introduction -cl-yag is a lightweight, static site generator that produces **gopher** sites as well as **html** websites. -The name 'cl-yag' stands for 'Common Lisp - Yet Another website Generator'. -It runs without Quicklisp. +cl-yag is a lightweight, static site generator that produces +**gopher** sites as well as **html** websites. The name 'cl-yag' +stands for 'Common Lisp - Yet Another website Generator'. It runs +without needing Quicklisp (Common LISP library manager). ## Showcase I am using cl-yag to create and maintain my websites in the -world-wide-web (visit: *[Solene's -percent](https://dataswamp.org/~solene/)*) as well as [in -gopher-space](gopher://dataswamp.org/1/~solene/). +world-wide-web (visit: *[Solene's percent] +(https://dataswamp.org/~solene/)*) as well as [in gopher-space] +(gopher://dataswamp.org/1/~solene/). ## Requirements @@ -101,7 +102,7 @@ to set most of the values in this file. **data/articles.lisp** has two parts: 1. A variable called *config*. Its values define your webpage. -2. A variable called *articles*. Its values define your posts. +2. "posts" declaration with their metadata Values are assigned by placing a string (e.g. ``"foo"``) or a boolean (i.e. ``t`` or ``nil``) behind a keyword (e.g. ``:title``). @@ -134,12 +135,16 @@ The *config* variable is used to assign the following values: - Hostname of the gopher server. It needs to be included in each link. - **gopher-port** - tcp port of the gopher server. 70 is the default port. It needs to be included in each link. +- **gopher-format** + - format of the gopher server. default is the geomyidae format, gophernicus format is commented. +- **gopher-index** + - name of the gopher menu file. defaut is index.gph for geomyidae, gophermap file is commented. -### The *articles* Variable +### Posts declarations -The *articles* variable holds post metadata. -So you need to create an entry in the *articles* variable for each of your posts. +Each post is declared with its metadata using the function "post". +So you need to add a new line for each of your posts. Of the following keywords, only ``:author`` and ``:short`` can be omitted. @@ -178,18 +183,18 @@ Then write a corresponding **data/2.md** file, using markdown. ## Howto Publish A Post I prepared a Makefile to facilitate the process of generating and -publishing your static sites. +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 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. ## Howto Add A New Page -You may want to have some dedicated pages besides the index or a post. +You may want to have some dedicated pages besides the index or a post. To create one, edit the *generate-site* function in cl-yag's **generator.lisp** and add a function call, like this: diff --git a/data/1.md b/data/1.md index 7773de5..24594ef 100644 --- a/data/1.md +++ b/data/1.md @@ -1 +1,3 @@ -This contains the text of the article with id 1 +This contains the text of the article with id 1. + +It has two paragraphs and is displayed on the homepage. diff --git a/data/README.md b/data/README.md index 590efb8..a578d7e 100644 --- a/data/README.md +++ b/data/README.md @@ -3,17 +3,18 @@ ## Introduction -cl-yag is a lightweight, static site generator that produces **gopher** sites as well as **html** websites. -The name 'cl-yag' stands for 'Common Lisp - Yet Another website Generator'. -It runs without Quicklisp. +cl-yag is a lightweight, static site generator that produces +**gopher** sites as well as **html** websites. The name 'cl-yag' +stands for 'Common Lisp - Yet Another website Generator'. It runs +without needing Quicklisp (Common LISP library manager). ## Showcase I am using cl-yag to create and maintain my websites in the -world-wide-web (visit: *[Solene's -percent](https://dataswamp.org/~solene/)*) as well as [in -gopher-space](gopher://dataswamp.org/1/~solene/). +world-wide-web (visit: *[Solene's percent] +(https://dataswamp.org/~solene/)*) as well as [in gopher-space] +(gopher://dataswamp.org/1/~solene/). ## Requirements @@ -101,7 +102,7 @@ to set most of the values in this file. **data/articles.lisp** has two parts: 1. A variable called *config*. Its values define your webpage. -2. A variable called *articles*. Its values define your posts. +2. "posts" declaration with their metadata Values are assigned by placing a string (e.g. ``"foo"``) or a boolean (i.e. ``t`` or ``nil``) behind a keyword (e.g. ``:title``). @@ -134,12 +135,16 @@ The *config* variable is used to assign the following values: - Hostname of the gopher server. It needs to be included in each link. - **gopher-port** - tcp port of the gopher server. 70 is the default port. It needs to be included in each link. +- **gopher-format** + - format of the gopher server. default is the geomyidae format, gophernicus format is commented. +- **gopher-index** + - name of the gopher menu file. defaut is index.gph for geomyidae, gophermap file is commented. -### The *articles* Variable +### Posts declarations -The *articles* variable holds post metadata. -So you need to create an entry in the *articles* variable for each of your posts. +Each post is declared with its metadata using the function "post". +So you need to add a new line for each of your posts. Of the following keywords, only ``:author`` and ``:short`` can be omitted. @@ -178,18 +183,18 @@ Then write a corresponding **data/2.md** file, using markdown. ## Howto Publish A Post I prepared a Makefile to facilitate the process of generating and -publishing your static sites. +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 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. ## Howto Add A New Page -You may want to have some dedicated pages besides the index or a post. +You may want to have some dedicated pages besides the index or a post. To create one, edit the *generate-site* function in cl-yag's **generator.lisp** and add a function call, like this: diff --git a/data/articles.lisp b/data/articles.lisp index c94a985..30f1d45 100644 --- a/data/articles.lisp +++ b/data/articles.lisp @@ -8,39 +8,48 @@ :webmaster "Your autor name here" :title "Your website's title." :description "Yet another website on the net" - :url "https://my.website/~~user/" ;; the trailing slash is mandatory! RSS links will fail without it. Notice the '~~' to produce a literal '~' - :rss-item-number 10 ;; limit total amount of items in RSS feed to 10 - :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 - :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 + :url "https://my.website/~~user/" ;; the trailing slash is mandatory! RSS links will fail without it. Notice the '~~' to produce a literal '~' + :rss-item-number 10 ;; limit total amount of items in RSS feed to 10 + :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 + :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 + :gopher-format "[0|~a|~a/article-~d.txt|~a|~a]~%~%" ;; geomyidae + :gopher-index "index.gph" ;; geomyidae + ;; :gopher-format "0~a ~a/article-~d.txt ~a ~a~%~%" ;; gophernicus and others + ;; :gopher-index "gophermap" ;; gophernicus and others )) +(converter :name :markdown :extension ".md" :command "peg-markdown -o %IN") +(converter :name :markdown2 :extension ".md" :command "multimarkdown -o %IN") - - -;; Define your articles and their display-order on the website in *articles* below. +;; Define your articles and their display-order on the website below. ;; Display Order is 'lifo', i.e. the top entry in this list gets displayed as the topmost entry. ;; ;; An Example Of A Minimal Definition: -;; (list :id "4" :date "2015-05-04" :title "The article title" :author "Me" :tiny "Short description for home page") +;; (post :id "4" :date "2015-12-31" :title "Happy new year" :tag "news") + +;; An Example Of A Definitions With Options: +;; (post :id "4" :date "2015-05-04" :title "The article title" :tag "news" :author "Me" :tiny "Short description for home page") ;; ;; A Note On Keywords: ;; :author can be omitted. If so, it's value gets replaced by the value of :webmaster. ;; :tiny can be omitted. If so, the article's full text gets displayed on the all-articles view. (most people don't want this.) -(defvar *articles* - (list - ;; CSS - (list :id "css" :date "02.12.2017" :tag "cl-yag" - :title "CSS For cl-yag" :author "lambda" :tiny "Read more") - ;; README - (list :id "README" :date "23.11.2017" :tag "cl-yag" - :title "README" :author "lambda" :tiny "Read cl-yag's README") - ;; 1 - (list :id "1" :date "29.04.2016" :tag "pony" - :title "My first message" :short "This is my first message" :author "Solène" :tiny "Read more") - )) +;; CSS +(post :title "CSS For cl-yag" + :id "css" :date "02.12.2017" :tag "cl-yag" + :author "lambda" :tiny "Read more") + +;; README +(post :title "README" + :id "README" :date "23.11.2017" :tag "cl-yag" + :author "lambda" :tiny "Read cl-yag's README") + +;; 1 +(post :title "My first post" + :id "1" :date "29.04.2016" :tag "pony" + :tiny "This is the first message" :author "Solène") diff --git a/generator.lisp b/generator.lisp index 50781bb..1e5278e 100644 --- a/generator.lisp +++ b/generator.lisp @@ -1,7 +1,9 @@ (defparameter *articles* '()) +(defparameter *converters* '()) ;; structure to store links (defstruct article title tag date id tiny author short) +(defstruct converter name command extension) (defun post(&optional &key title tag date id (tiny nil) (author nil) (short nil)) (push (make-article :title title @@ -13,7 +15,15 @@ :id id) *articles*)) +;; we add a converter to the list of the one availables +(defun converter(&optional &key name command extension) + (push (make-converter :name name + :command command + :extension extension) + *converters*)) + (load "data/articles.lisp") +(setf *articles* (reverse *articles*)) ;; common-lisp don't have a replace string function natively @@ -200,14 +210,13 @@ (defun create-gopher-hole() ;; produce the gophermap file - (save-file "output/gopher/gophermap" + (save-file (concatenate 'string "output/gopher/" (getf *config* :gopher-index)) (let ((output (load-file "templates/gopher_head.tpl"))) (dolist (article *articles*) (setf output (string (concatenate 'string output - (format nil "0~a ~a/article-~d.txt ~a ~a~%~%" - + (format nil (getf *config* :gopher-format) ;; here we create a 80 width char string with title on the left ;; and date on the right ;; we truncate the article title if it's too large