squeeze

A static site generator that can put the toothpaste back in the tube.
git clone https://git.mulligrubs.me/squeeze
Log | Files | Refs | README | LICENSE

commit c78cfa3292631e2989fceb8d7e9878ab999f7f69
parent 60c888354a57a7f167cfa0dd57a20c45a440e8f3
Author: St John Karp <stjohn@mulligrubs.me>
Date:   Tue, 25 Aug 2020 17:27:47 -0500

Fix RSS date handling

Apparently RSS needs its dates in a particular format, so I've
added some date handling. Because Prolog doesn't do this natively,
I had to use dialect-specific predicates. And so long as Prolog is
already handling dates, I had it also generate the build date itself.

Diffstat:
Mdialects/gnu-prolog.pl | 21+++++++++++++++++++--
Mdialects/swi-prolog.pl | 17+++++++++++++++--
Mgenerate_rss.pl | 18++++++++++++++----
Mparse_entry.pl | 2++
Msqueeze.sh | 3+--
5 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/dialects/gnu-prolog.pl b/dialects/gnu-prolog.pl @@ -20,4 +20,22 @@ markdown_to_html(MarkdownEntryCodes, HTMLEntryCodes):- write_codes(StreamIn, MarkdownEntryCodes), close(StreamIn), read_file(StreamOut, HTMLEntryCodes), - close(StreamOut).- \ No newline at end of file + close(StreamOut). + + +% GNU-Prolog-specific handling of dates. +today(DateCodes):- + gnu_prolog, + date_time(dt(Year, Month, Day, Hour, Minute, Second)), + join([Year, '-', Month, '-', Day, ' ', Hour, ':', Minute, ':', Second], '', DateAtom), + atom_codes(DateAtom, DateCodes). + +% Format a date as RFC 822 (with a four-digit year). +format_date(FormattedDateCodes, DateCodes):- + gnu_prolog, + atom_codes(DateAtom, DateCodes), + join(['--date="', DateAtom, '"'], '', Arg), + join(['date', Arg, '--rfc-email'], ' ', Command), + exec(Command, _, StreamOut, _), + read_file(StreamOut, FormattedDateCodes), + close(StreamOut). diff --git a/dialects/swi-prolog.pl b/dialects/swi-prolog.pl @@ -16,4 +16,18 @@ markdown_to_html(MarkdownEntryCodes, HTMLEntryCodes):- write_codes(StreamIn, MarkdownEntryCodes), close(StreamIn), read_file(StreamOut, HTMLEntryCodes), - close(StreamOut).- \ No newline at end of file + close(StreamOut). + + +% SWI-Prolog-specific predicates for date handling. +today(FormattedDateCodes):- + swi_prolog, + get_time(DateStamp), + format_time(codes(FormattedDateCodes), '%a, %d %b %Y %T %z', DateStamp). + +% Format a date as RFC 822 (with a four-digit year). +format_date(FormattedDateCodes, DateCodes):- + swi_prolog, + atom_codes(DateAtom, DateCodes), + parse_time(DateAtom, DateStamp), + format_time(codes(FormattedDateCodes), '%a, %d %b %Y %T %z', DateStamp). diff --git a/generate_rss.pl b/generate_rss.pl @@ -6,16 +6,24 @@ :- include('helpers.pl'). :- include('rss.pl'). -% generate_rss(+BuildDate, +Filenames). -% BuildDate is a list of character codes representing today's date (e.g. "2109-07-14"). +% Include files for dialect-dependent predicates. +:- discontiguous(markdown_to_html/2). +:- discontiguous(format_date/2). +:- discontiguous(today/1). +:- include('dialects/gnu-prolog.pl'). +:- include('dialects/swi-prolog.pl'). + +% generate_rss(+Filenames). % Filenames is a list of atoms containing paths to all Markdown files with a date. % These files will be read, sorted by date, and used to generate an RSS of the most % recent posts. -generate_rss(BuildDate, Filenames):- +generate_rss(Filenames):- % Read in all the files so we have their dates and contents. files_to_articles(Filenames, Articles), % Sort articles by date. sort(Articles, SortedArticles), + % Get the build date. + today(BuildDate), % Convert to RSS and write to stdout. rss(BuildDate, SortedArticles, RSSCodes, []), write_codes(user_output, RSSCodes), @@ -26,7 +34,7 @@ generate_rss(BuildDate, Filenames):- % Read in each file as an article predicate. files_to_articles([], []). -files_to_articles([Filename|Filenames], [article(Date, Title, Link, Description)|Articles]):- +files_to_articles([Filename|Filenames], [article(FormattedDate, Title, Link, Description)|Articles]):- open(Filename, read, Stream), read_file(Stream, HTML), close(Stream), @@ -34,6 +42,8 @@ files_to_articles([Filename|Filenames], [article(Date, Title, Link, Description) get_link(Filename, Link), % Extract the title, entry, etc. from the HTML. page(Entry, Title, _, Date, HTML, []), + % Format the date according to RFC 822. + format_date(FormattedDate, Date), % XML escape the description. replace("&", "&amp;", Entry, EntryAmp), replace("<", "&lt;", EntryAmp, EntryLT), diff --git a/parse_entry.pl b/parse_entry.pl @@ -8,6 +8,8 @@ % Include files for dialect-dependent predicates. :- discontiguous(markdown_to_html/2). +:- discontiguous(format_date/2). +:- discontiguous(today/1). :- include('dialects/gnu-prolog.pl'). :- include('dialects/swi-prolog.pl'). diff --git a/squeeze.sh b/squeeze.sh @@ -31,7 +31,6 @@ ARTICLES=$(grep --recursive --include "*.md" "^Date: " "$SOURCE_PATH" | # Glue the file names together to be passed to Prolog. paste --serial --delimiters ',' - | sed "s|,|','|g") -BUILD_DATE=$(date +"%Y-%m-%d %T") # Parse the articles and generate the RSS. -swipl --traditional --quiet -l generate_rss.pl -g "consult('$SITE_PATH/site.pl'), generate_rss(\"$BUILD_DATE\", ['$ARTICLES'])." \ +swipl --traditional --quiet -l generate_rss.pl -g "consult('$SITE_PATH/site.pl'), generate_rss(['$ARTICLES'])." \ > "$OUTPUT_PATH/feeds/rss.xml"