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
This commit is contained in:
Solene Rapenne 2017-12-13 12:08:57 +01:00
parent bbf0687d39
commit 52bd9a828b
6 changed files with 84 additions and 54 deletions

View File

@ -1,5 +1,5 @@
LISP= sbcl
MD= multimarkdown -o
MD= multimarkdown -t html -o
HTMLDIR= temp/data
ARTICLES!= ls data/*.md

View File

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

View File

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

View File

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

View File

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

View File

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