Title: New cl-yag version | |
Author: Solène | |
Date: 16 December 2017 | |
Tags: unix cl-yag | |
Description: | |
#+OPTIONS: toc:nil num:nil | |
** Introduction | |
cl-yag is a static website generator. It's a software used to publish | |
a website and/or a gopher hole from a list of articles. As the | |
developer of cl-yag I'm happy to announce that a new version has been | |
released. | |
** New features | |
The new version, with its number 0.6, bring lot of new features : | |
- supporting **different** markup language **per article** | |
- date format configurable | |
- gopher output format configurable | |
- ship with the default theme "clyma", minimalist but responsive (the | |
one used on this website) | |
- easier to use | |
- full user documentation | |
The code is available at git://bitreich.org/cl-yag, the program | |
requires sbcl or ecl to work. | |
*** Per article markup language | |
The best feature I'm proud of is allowing to use a different language | |
per article. While on my blog I choosed to use markdown, it's | |
sometimes not adapted for more elaborated articles like the one about | |
LISP containing code which was written in org-mode then converted to | |
markdown manually to fit to cl-yag. Now, the user can declare a named | |
"converter" which is a command line with pattern replacement, to | |
produce the html file. We can imagine a lot of things with this, even | |
producing a gallery with find + awk command. Now, I can use markdown | |
by default and specify if I want to use org-mode or something else. | |
This is the way to declare a converter, taking org-mode as example, | |
which is not very simple, because of emacs not being script friendly : | |
#+BEGIN_SRC lisp | |
(converter :name :org-mode :extension ".org" | |
:command (concatenate 'string | |
"emacs data/%IN --batch --eval | |
'(with-temp-buffer (org-mode) " | |
"(insert-file \"%IN\") | |
(org-html-export-as-html nil nil nil t)" | |
"(princ (buffer-string)))' --kill | | |
tee %OUT")) | |
#+END_SRC | |
And an easy way to produce a gallery with awk from a =.txt= file | |
containing a list of images path. | |
#+BEGIN_SRC lisp | |
(converter :name :gallery :extension ".txt" | |
:command (concatenate 'string | |
"awk 'BEGIN { print \"<div | |
class=\\\"gallery\\\">\"} " | |
"{ print \"<img | |
src=\\\"static/images/\"$1\"\\\" />\" } " | |
" END { print \"</div>\"} data/%IN | |
| tee %OUT")) | |
#+END_SRC | |
The concatenate function is only used to improve the presentation, to | |
split the command in multiples lines and make it easier to read. It's | |
possible to write all the command in one line. | |
The patterns **=%IN=** and **=%OUT=** are replaced by the input file | |
name and the output file name when the command is executed. | |
For an easier example, the default markdown converter looks like this, | |
calling multimarkdown command : | |
#+BEGIN_SRC lisp | |
(converter :name :markdown :extension ".md" | |
:command "multimarkdown -t html -o %OUT data/%IN") | |
#+END_SRC | |
It's really easy (I hope !) to add new converters you need with this | |
feature. | |
*** Date format configurable | |
One problem I had with cl-yag is that it's plain vanilla Common LISP | |
without libraries, so it's easier to fetch and use but it lacks some | |
elaborated libraries like one to parse date and format a date. Before | |
this release, I was writing in plain text "14 December 2017" in the | |
date field of a blog post. It was easy to use, but not really usable | |
in the RSS feed in the **=pubDate=** attribute, and if I wanted to | |
change the display of the date for some reason, I would have to | |
rewrite everything. | |
Now, the date is simply in the format "YYYYMMDD" like "20171231" for | |
the 31rd December 2017. And in the configuration variable, there is a | |
**=:date-format=** keyword to define the date display. This variable | |
is a string allowing pattern replacement of the following variables : | |
- %DayNumber :: day of the month in number, from 1 to 31 | |
- %DayName :: day of the week, from Monday to Sunday, names are | |
written in english in the source code and can be | |
translated | |
- %MonthNumber :: month in number, from 1 to 12 | |
- %MonthName :: month name, from January to December, names are | |
written in english in the source code and can be | |
translated | |
- %Year :: year | |
Currently, as the time of writing, I use the value "**=%DayNumber | |
%MonthName %Year=**" | |
A **=:gopher-format=** keyword exist in the configuration file to | |
configure the date format in the gopher export. It can be different | |
from the html one. | |
*** More Gopher configuration | |
There are cases where the gopher server use an unusual syntax compared | |
to most of the servers. I wanted to make it configurable, so the user | |
could easily use cl-yag without having to mess with the code. I | |
provide the default for **geomyidae** and in comments another syntax | |
is available. There is also a configurable value to indicates where to | |
store the gopher page menu, it's not always **gophermap**, it could be | |
**index.gph** or whatever you need. | |
*** Easier to use | |
A comparison of code will make it easier to understand. There was a | |
little change the way blog posts are declared : | |
From | |
#+BEGIN_SRC lisp | |
(defparameter *articles* | |
(list | |
(list :id "third-article" :title "My third article" :tag "me" | |
:date "20171205") | |
(list :id "second-article" :title "Another article" :tag "me" | |
:date "20171204") | |
(list :id "first-article" :title "My first article" :tag "me" | |
:date "20171201") | |
)) | |
#+END_SRC | |
to | |
#+BEGIN_SRC lisp | |
(post :id "third-article" :title "My third article" :tag "me" :date | |
"20171205") | |
(post :id "second-article" :title "Another article" :tag "me" :date | |
"20171204") | |
(post :id "first-article" :title "My first article" :tag "me" :date | |
"20171201") | |
#+END_SRC | |
Each post are independtly declared and I plan to add a "page" function | |
to create static pages, but this is going to be for the next version ! | |
** Future work | |
I am very happy to hack on cl-yag, I want to continue improving it but | |
I should really think about each feature I want to add. I want to keep | |
it really simple even if it limits the features. | |
I want to allow the creation of static pages like "About me", "Legal" | |
or "websites I liked" that integrates well in the template. The user | |
may not want all the static pages links to go at the same place in the | |
template, or use the same template. I'm thinking about this. | |
Also, I think the gopher generation could be improved, but I still | |
have no idea how. | |
Others themes may come in the default configuration, allowing the user | |
to have a choice between themes. But as for now, I don't plan to bring | |
a theme using javascript. |