diff --git a/Makefile b/Makefile index 25805ce..75ba5cb 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,6 @@ LISP= sbcl -MD= multimarkdown -t html -o HTMLDIR= temp/data -ARTICLES!= ls data/*.md -HTML= $(ARTICLES:.md=.html) all: clean dirs html @@ -16,9 +13,6 @@ dirs: mkdir -p "output/html/static" mkdir -p "output/gopher" -.SUFFIXES: .md .html -.md.html: - $(MD) "$(HTMLDIR)/$(@F)" "$<" clean: rm -fr output/html/* output/gopher/* "temp" diff --git a/data/articles.lisp b/data/articles.lisp index d5a4f4b..6d32a55 100644 --- a/data/articles.lisp +++ b/data/articles.lisp @@ -11,6 +11,7 @@ :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 :date-format "%DayNumber %MonthName %Year" ;; format for date %DayNumber %DayName %MonthNumber %MonthName %Year + :default-converter :markdown2 :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 @@ -23,8 +24,13 @@ )) -(converter :name :markdown :extension ".md" :command "peg-markdown -o %IN") -(converter :name :markdown2 :extension ".md" :command "multimarkdown -o %IN") +(converter :name :markdown :extension ".md" :command "peg-markdown -t html -o %OUT data/%IN") +(converter :name :markdown2 :extension ".md" :command "multimarkdown -t html -o %OUT data/%IN") +(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")) ;; 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. @@ -40,6 +46,8 @@ ;; :tiny can be omitted. If so, the article's full text gets displayed on the all-articles view. (most people don't want this.) +(post :title "test" + :id "t" :date "20171214" :tag "f" :converter :org-mode) ;; CSS (post :title "CSS For cl-yag" :id "css" :date "20171202" :tag "cl-yag" diff --git a/generator.lisp b/generator.lisp index 84f7960..d000f7d 100644 --- a/generator.lisp +++ b/generator.lisp @@ -9,11 +9,13 @@ "October" "November" "December")) ;; structure to store links -(defstruct article title tag date id tiny author rawdate) +(defstruct article title tag date id tiny author rawdate converter) (defstruct converter name command extension) ;;;; FUNCTIONS +(require 'asdf) + ;; return the day of the week (defun get-day-of-week(day month year) (multiple-value-bind @@ -39,22 +41,26 @@ :year year)) nil)) -(defun post(&optional &key title tag date id (tiny nil) (author nil)) +(defun post(&optional &key title tag date id (tiny nil) (author nil) (converter nil)) (push (make-article :title title :tag tag :date (date-parse date) :rawdate date :tiny tiny :author author - :id id) + :id id + :converter converter) *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*)) + (setf *converters* + (append + (list name + (make-converter :name name + :command command + :extension extension)) + *converters*))) ;; load data from metadata and load config (load "data/articles.lisp") @@ -117,6 +123,23 @@ `(progn (setf output (replace-all output ,before ,@after)))) +;; get the converter object of "article" +(defmacro with-converter(&body code) + `(progn + (let ((converter-name (if (article-converter article) + (article-converter article) + (getf *config* :default-converter)))) + (let ((converter-object (getf *converters* converter-name))) + ,@code)))) + +(defun use-converter-to-html(article) + (with-converter + (let ((output (converter-command converter-object))) + (ensure-directories-exist "temp/data/") + (template "%IN" (concatenate 'string (article-id article) (converter-extension converter-object))) + (template "%OUT" (concatenate 'string "temp/data/" (article-id article) ".html")) + (uiop:run-program output)))) + ;; format the date (defun date-format(format date) (let ((output format)) @@ -240,21 +263,25 @@ ;; We do all the website (defun create-html-site() - ;; produce index.html - (generate "output/html/index.html" (generate-semi-mainpage)) - - ;; produce index-titles.html where there are only articles titles - (generate "output/html/index-titles.html" (generate-semi-mainpage :no-text t)) ;; produce each article file (loop for article in *articles* do + ;; use the article's converter to get html code of it + (use-converter-to-html article) + (generate (format nil "output/html/~d-~d.html" (date-format "%Year-%MonthNumber-%DayNumber" (article-date article)) (article-id article)) (create-article article :tiny nil) :title (concatenate 'string (getf *config* :title) " : " (article-title article)))) + + ;; produce index.html + (generate "output/html/index.html" (generate-semi-mainpage)) + + ;; produce index-titles.html where there are only articles titles + (generate "output/html/index-titles.html" (generate-semi-mainpage :no-text t)) ;; produce index file for each tag (loop for tag in (articles-by-tag) do @@ -293,10 +320,12 @@ output)) ;; produce each article file (only a copy/paste in fact) - (dolist (article *articles*) - (let ((id (article-id article))) - (save-file (format nil "output/gopher/article-~d.txt" id) - (load-file (format nil "data/~d.md" id))))) + (loop for article in *articles* + do + (with-converter + (let ((id (article-id article))) + (save-file (format nil "output/gopher/article-~d.txt" id) + (load-file (format nil "data/~d~d" id (converter-extension converter-object))))))) ) @@ -313,4 +342,5 @@ (generate-site) + (quit)