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:
parent
bbf0687d39
commit
52bd9a828b
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
LISP= sbcl
|
LISP= sbcl
|
||||||
MD= multimarkdown -o
|
MD= multimarkdown -t html -o
|
||||||
|
|
||||||
HTMLDIR= temp/data
|
HTMLDIR= temp/data
|
||||||
ARTICLES!= ls data/*.md
|
ARTICLES!= ls data/*.md
|
||||||
|
|
25
README.md
25
README.md
|
@ -3,17 +3,18 @@
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
cl-yag is a lightweight, static site generator that produces **gopher** sites as well as **html** websites.
|
cl-yag is a lightweight, static site generator that produces
|
||||||
The name 'cl-yag' stands for 'Common Lisp - Yet Another website Generator'.
|
**gopher** sites as well as **html** websites. The name 'cl-yag'
|
||||||
It runs without Quicklisp.
|
stands for 'Common Lisp - Yet Another website Generator'. It runs
|
||||||
|
without needing Quicklisp (Common LISP library manager).
|
||||||
|
|
||||||
|
|
||||||
## Showcase
|
## Showcase
|
||||||
|
|
||||||
I am using cl-yag to create and maintain my websites in the
|
I am using cl-yag to create and maintain my websites in the
|
||||||
world-wide-web (visit: *[Solene's
|
world-wide-web (visit: *[Solene's percent]
|
||||||
percent](https://dataswamp.org/~solene/)*) as well as [in
|
(https://dataswamp.org/~solene/)*) as well as [in gopher-space]
|
||||||
gopher-space](gopher://dataswamp.org/1/~solene/).
|
(gopher://dataswamp.org/1/~solene/).
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
@ -101,7 +102,7 @@ to set most of the values in this file.
|
||||||
**data/articles.lisp** has two parts:
|
**data/articles.lisp** has two parts:
|
||||||
|
|
||||||
1. A variable called *config*. Its values define your webpage.
|
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
|
Values are assigned by placing a string (e.g. ``"foo"``) or a boolean
|
||||||
(i.e. ``t`` or ``nil``) behind a keyword (e.g. ``:title``).
|
(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.
|
- Hostname of the gopher server. It needs to be included in each link.
|
||||||
- **gopher-port**
|
- **gopher-port**
|
||||||
- tcp port of the gopher server. 70 is the default port. It needs to be included in each link.
|
- 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.
|
Each post is declared with its metadata using the function "post".
|
||||||
So you need to create an entry in the *articles* variable for each of your posts.
|
So you need to add a new line for each of your posts.
|
||||||
|
|
||||||
Of the following keywords, only ``:author`` and ``:short`` can be omitted.
|
Of the following keywords, only ``:author`` and ``:short`` can be omitted.
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -3,17 +3,18 @@
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
cl-yag is a lightweight, static site generator that produces **gopher** sites as well as **html** websites.
|
cl-yag is a lightweight, static site generator that produces
|
||||||
The name 'cl-yag' stands for 'Common Lisp - Yet Another website Generator'.
|
**gopher** sites as well as **html** websites. The name 'cl-yag'
|
||||||
It runs without Quicklisp.
|
stands for 'Common Lisp - Yet Another website Generator'. It runs
|
||||||
|
without needing Quicklisp (Common LISP library manager).
|
||||||
|
|
||||||
|
|
||||||
## Showcase
|
## Showcase
|
||||||
|
|
||||||
I am using cl-yag to create and maintain my websites in the
|
I am using cl-yag to create and maintain my websites in the
|
||||||
world-wide-web (visit: *[Solene's
|
world-wide-web (visit: *[Solene's percent]
|
||||||
percent](https://dataswamp.org/~solene/)*) as well as [in
|
(https://dataswamp.org/~solene/)*) as well as [in gopher-space]
|
||||||
gopher-space](gopher://dataswamp.org/1/~solene/).
|
(gopher://dataswamp.org/1/~solene/).
|
||||||
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
@ -101,7 +102,7 @@ to set most of the values in this file.
|
||||||
**data/articles.lisp** has two parts:
|
**data/articles.lisp** has two parts:
|
||||||
|
|
||||||
1. A variable called *config*. Its values define your webpage.
|
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
|
Values are assigned by placing a string (e.g. ``"foo"``) or a boolean
|
||||||
(i.e. ``t`` or ``nil``) behind a keyword (e.g. ``:title``).
|
(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.
|
- Hostname of the gopher server. It needs to be included in each link.
|
||||||
- **gopher-port**
|
- **gopher-port**
|
||||||
- tcp port of the gopher server. 70 is the default port. It needs to be included in each link.
|
- 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.
|
Each post is declared with its metadata using the function "post".
|
||||||
So you need to create an entry in the *articles* variable for each of your posts.
|
So you need to add a new line for each of your posts.
|
||||||
|
|
||||||
Of the following keywords, only ``:author`` and ``:short`` can be omitted.
|
Of the following keywords, only ``:author`` and ``:short`` can be omitted.
|
||||||
|
|
||||||
|
|
|
@ -15,32 +15,41 @@
|
||||||
:gopher-path "/user" ;; absolute path of your gopher directory
|
:gopher-path "/user" ;; absolute path of your gopher directory
|
||||||
:gopher-server "my.website" ;; hostname of the gopher server
|
:gopher-server "my.website" ;; hostname of the gopher server
|
||||||
:gopher-port "70" ;; tcp port of the gopher server, 70 usually
|
: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 below.
|
||||||
|
|
||||||
;; Define your articles and their display-order on the website in *articles* below.
|
|
||||||
;; Display Order is 'lifo', i.e. the top entry in this list gets displayed as the topmost entry.
|
;; Display Order is 'lifo', i.e. the top entry in this list gets displayed as the topmost entry.
|
||||||
;;
|
;;
|
||||||
;; An Example Of A Minimal Definition:
|
;; 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:
|
;; A Note On Keywords:
|
||||||
;; :author can be omitted. If so, it's value gets replaced by the value of :webmaster.
|
;; :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.)
|
;; :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")
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
(defparameter *articles* '())
|
(defparameter *articles* '())
|
||||||
|
(defparameter *converters* '())
|
||||||
|
|
||||||
;; structure to store links
|
;; structure to store links
|
||||||
(defstruct article title tag date id tiny author short)
|
(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))
|
(defun post(&optional &key title tag date id (tiny nil) (author nil) (short nil))
|
||||||
(push (make-article :title title
|
(push (make-article :title title
|
||||||
|
@ -13,7 +15,15 @@
|
||||||
:id id)
|
:id id)
|
||||||
*articles*))
|
*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")
|
(load "data/articles.lisp")
|
||||||
|
(setf *articles* (reverse *articles*))
|
||||||
|
|
||||||
|
|
||||||
;; common-lisp don't have a replace string function natively
|
;; common-lisp don't have a replace string function natively
|
||||||
|
@ -200,14 +210,13 @@
|
||||||
(defun create-gopher-hole()
|
(defun create-gopher-hole()
|
||||||
|
|
||||||
;; produce the gophermap file
|
;; 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")))
|
(let ((output (load-file "templates/gopher_head.tpl")))
|
||||||
(dolist (article *articles*)
|
(dolist (article *articles*)
|
||||||
(setf output
|
(setf output
|
||||||
(string
|
(string
|
||||||
(concatenate 'string output
|
(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
|
;; here we create a 80 width char string with title on the left
|
||||||
;; and date on the right
|
;; and date on the right
|
||||||
;; we truncate the article title if it's too large
|
;; we truncate the article title if it's too large
|
||||||
|
|
Loading…
Reference in New Issue