commit 521fa8d01f615a4424866e0a12d3711098c9ef7d
parent 2920262d3d1cf88083a26c963bf02824ee5af1f7
Author: St John Karp <contact@stjo.hn>
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:
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("&", "&", Entry, EntryAmp),
replace("<", "<", 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"