From 0759afe3db42ac3ca2c708a7f08fd37d5401bf7a Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Wed, 18 Jan 2017 23:41:12 +0100
Subject: [PATCH] Add interpretation of article-specific linkback URL list
 files.

---
 README.md                                  |  8 +++++---
 processor/default.html.do                  | 20 +++++++++++++++++---
 processor/metadata/article.tmpl.do         |  5 +++++
 processor/metadata/default.feed_snippet.do | 15 +++++++++++++--
 processor/metadata/linkback.tmpl.do        |  5 +++++
 test.sh                                    |  1 +
 test/test_files/bar baz.html.ignoring      |  5 +++++
 test/test_files/feed.xml.ignoring          |  2 ++
 test/test_files/foo.html.ignoring          |  7 +++++++
 test/test_files/foo.links                  |  2 ++
 test/test_files/test.html.ignoring         |  5 +++++
 11 files changed, 67 insertions(+), 8 deletions(-)
 create mode 100644 processor/metadata/linkback.tmpl.do
 create mode 100644 test/test_files/foo.links

diff --git a/README.md b/README.md
index aa70d01..0165c11 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,9 @@ run ./add_dir.sh DIRECTORY.
 
 You can then enter the directory and run redo there. This will generate article
 .html files from all .md and .rst files, plus a ./index.html, and a ./feed.xml.
-These files will be linked to symbolically in a directory ./public/.
+These files will be linked to symbolically in a directory ./public/. If you
+provide a file suffixed .links to basename of an article file, these links will
+be added as article-specific linkbacks to the .html file and the feed entry.
 
 Some metadata files will also be generated below ./metadata/: For each article,
 there will be generated a .automatic_metadata (to contain an article's UUID,
@@ -34,8 +36,8 @@ checksum, and creation/modification dates) and a .intermediate file (to contain
 pandoc-formatted article content like title and body); furthermore, files for
 data used in ./feed.xml and ./index.html will, if non-existant, be built there
 and can be edited to customize the blog – namely the files url, author, title,
-index.tmpl, index_snippet.tmpl, article.tmpl. A blog-specific UUID and creation
-date is stored in ./metadata/automatic_metadata
+index.tmpl, index_snippet.tmpl, article.tmpl, linkback.tmpl. A blog-specific
+UUID and creation date is stored in ./metadata/automatic_metadata
 
 recipe to remotely manage a redo blog with git
 ----------------------------------------------
diff --git a/processor/default.html.do b/processor/default.html.do
index 7adf89b..8937ce8 100644
--- a/processor/default.html.do
+++ b/processor/default.html.do
@@ -1,5 +1,12 @@
 #!/bin/sh
 
+# Handle URL from .links file.
+prep_url() {
+  url=$(printf "%s" "$(escape_html "$1")" | prep_sed)
+  template=$(cat "$linkback_tmpl_file")
+  printf "%s" "$template" | sed 's/%URL%/'"$url"'/g' | tr '\a' '%' | prep_sed
+}
+
 # Pull in global dependencies.
 . ./helpers.sh
 metadata_dir=metadata
@@ -9,8 +16,11 @@ intermediate_file="${metadata_dir}/${1%.html}.intermediate"
 redo-ifchange "$intermediate_file"
 title_file="${metadata_dir}"/title
 redo-ifchange "$title_file" 
-template_file="${metadata_dir}"/article.tmpl
-redo-ifchange "$template_file"
+article_tmpl_file="${metadata_dir}"/article.tmpl
+redo-ifchange "$article_tmpl_file"
+linkback_tmpl_file="${metadata_dir}"/linkback.tmpl
+redo-ifchange "$linkback_tmpl_file"
+replies_file="${1%.html}.links"
 
 # Build entry data.
 blog_title=$(read_and_escape_file "$title_file" | head -1 | prep_sed)
@@ -23,9 +33,12 @@ datetime_created_unix=$(get_creation_date_from_meta_file_seconds "$meta_file")
 date_created=$(date -u "+%Y-%m-%d" -d "@${datetime_created_unix}")
 datetime_lastmod_unix=$(get_lastmod_date_from_meta_file "$meta_file")
 date_updated=$(date -u "+%Y-%m-%d" -d "@${datetime_lastmod_unix}")
+if test -f "$replies_file"; then
+  replies=$(while read line; do prep_url "$line"; done < "$replies_file")
+fi
 
 # Put data into template.
-template=$(cat "$template_file")
+template=$(cat "$article_tmpl_file")
 printf "%s" "$template" | \
 sed 's/%BLOG_TITLE%/'"$blog_title"'/g' | \
 sed 's/%ARTICLE_TITLE_ESCAPED%/'"$title_plaintext"'/g' | \
@@ -33,4 +46,5 @@ sed 's/%ARTICLE_TITLE_HTML%/'"$title_html"'/g' | \
 sed 's/%DATE_CREATED%/'"$date_created"'/g' | \
 sed 's/%DATE_UPDATED%/'"$date_updated"'/g' | \
 sed 's/%BODY%/'"$body"'/g' | \
+sed 's/%LINKBACKS%/'"$replies"'/g' | \
 tr '\a' '%'
diff --git a/processor/metadata/article.tmpl.do b/processor/metadata/article.tmpl.do
index 8b7e0dc..f24106a 100644
--- a/processor/metadata/article.tmpl.do
+++ b/processor/metadata/article.tmpl.do
@@ -22,6 +22,11 @@ header p { margin: 0; }
 <p>created: <time>%DATE_CREATED%</time> / last update: <time>%DATE_UPDATED%</time></p>
 </header>
 %BODY%
+<footer>
+Links back:
+<ul>%LINKBACKS%
+</ul>
+</footer>
 </article>
 EOF
 fi
diff --git a/processor/metadata/default.feed_snippet.do b/processor/metadata/default.feed_snippet.do
index 872eacf..73a2d56 100644
--- a/processor/metadata/default.feed_snippet.do
+++ b/processor/metadata/default.feed_snippet.do
@@ -1,5 +1,11 @@
 #!/bin/sh
 
+# Handle URL from .links file.
+prep_url() {
+  url=$(escape_html "$1")
+  printf "\n<link href=\"%s\" rel=\"replies\">%s</link>" "$url" "$url"
+}
+
 # Pull in dependencies. 
 . ../helpers.sh
 src_file=$(get_source_file "$1")
@@ -7,6 +13,7 @@ meta_file="${1%.feed_snippet}.automatic_metadata"
 redo-ifchange "$meta_file"
 intermediate_file="${1%.feed_snippet}.intermediate"
 redo-ifchange "$intermediate_file"
+replies_file="${src_file%.*}.links"
 
 # Get variables, write entry.
 html_file=$(escape_url "${1%.feed_snippet}.html")
@@ -17,11 +24,15 @@ uuid=$(get_uuid_from_meta_file "$meta_file")
 published_unix=$(get_creation_date_from_meta_file_seconds "$meta_file")
 published_rfc3339=$(date -u "+%Y-%m-%dT%TZ" -d "@${published_unix}")
 body=$(read_and_escape_file "$intermediate_file" | sed 1d)
+if test -f "$replies_file"; then
+  replies=$(while read line; do prep_url "$line"; done < "$replies_file")
+fi
 printf "<entry>\n"
 printf "<title type=\"html\">%s</title>\n" "$title"
 printf "<id>urn:uuid:%s</id>\n" "$uuid"
 printf "<updated>%s</updated>\n" "$lastmod_rfc3339"
 printf "<published>%s</published>\n" "$published_rfc3339"
-printf "<link href=\"%s%s\" rel=\"alternate\" type=\"text/html\" />\n" "$(get_basepath)" "${html_file}"
-printf "<content type=\"html\">\n%s\n</content>\n" "$body"
+printf "<link href=\"%s%s\" rel=\"alternate\" type=\"text/html\" />" "$(get_basepath)" "${html_file}"
+printf "%s" "$replies"
+printf "\n<content type=\"html\">\n%s\n</content>\n" "$body"
 printf "</entry>\n"
diff --git a/processor/metadata/linkback.tmpl.do b/processor/metadata/linkback.tmpl.do
new file mode 100644
index 0000000..64c21a6
--- /dev/null
+++ b/processor/metadata/linkback.tmpl.do
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+if [ ! -f "$1" ]; then
+  printf "\n%s" "<li><a href=\"%URL%\">%URL%</a></li>"
+fi
diff --git a/test.sh b/test.sh
index da87a2b..c6e9c8f 100755
--- a/test.sh
+++ b/test.sh
@@ -54,6 +54,7 @@ redo
 cp "$working_dir/$expected_files_dir"/bar\ baz.md .
 redo
 cp "$working_dir/$expected_files_dir"/foo.rst .
+cp "$working_dir/$expected_files_dir"/foo.links .
 redo
 
 # Test file modification tracking.
diff --git a/test/test_files/bar baz.html.ignoring b/test/test_files/bar baz.html.ignoring
index 59c5996..1c29f06 100644
--- a/test/test_files/bar baz.html.ignoring	
+++ b/test/test_files/bar baz.html.ignoring	
@@ -21,4 +21,9 @@ header p { margin: 0; }
 <p>bar</p>
 <h3 id="bar-1">bar</h3>
 <p>bar</p>
+<footer>
+Links back:
+<ul>
+</ul>
+</footer>
 </article>
\ No newline at end of file
diff --git a/test/test_files/feed.xml.ignoring b/test/test_files/feed.xml.ignoring
index 7289ec6..c6b6b9d 100644
--- a/test/test_files/feed.xml.ignoring
+++ b/test/test_files/feed.xml.ignoring
@@ -40,6 +40,8 @@
 <updated>IGNORE</updated>
 <published>IGNORE</published>
 <link href="http://example.org/foo.html" rel="alternate" type="text/html" />
+<link href="http://example.org/" rel="replies">http://example.org/</link>
+<link href="http://example.com/some&quot;what&#x27;danger&lt;&gt;us%URL" rel="replies">http://example.com/some&quot;what&#x27;danger&lt;&gt;us%URL</link>
 <content type="html">
 &lt;p&gt;this text contains some special characters: /;%&#x27;&amp;quot;&amp;gt;&amp;lt;&amp;amp;äöüß&lt;/p&gt;
 &lt;h2 id=&quot;some-sub-heading&quot;&gt;some sub-heading&lt;/h2&gt;
diff --git a/test/test_files/foo.html.ignoring b/test/test_files/foo.html.ignoring
index de2d406..a20fc1e 100644
--- a/test/test_files/foo.html.ignoring
+++ b/test/test_files/foo.html.ignoring
@@ -22,4 +22,11 @@ header p { margin: 0; }
 <p>and more than one paragraph</p>
 <h2 id="another-sub-heading">another sub-heading</h2>
 <p>note that should be ignored but \ should give a backlash</p>
+<footer>
+Links back:
+<ul>
+<li><a href="http://example.org/">http://example.org/</a></li>
+<li><a href="http://example.com/some&quot;what&#x27;danger&lt;&gt;us%URL">http://example.com/some&quot;what&#x27;danger&lt;&gt;us%URL</a></li>
+</ul>
+</footer>
 </article>
\ No newline at end of file
diff --git a/test/test_files/foo.links b/test/test_files/foo.links
new file mode 100644
index 0000000..f6d6e4d
--- /dev/null
+++ b/test/test_files/foo.links
@@ -0,0 +1,2 @@
+http://example.org/
+http://example.com/some"what'danger<>us%URL
diff --git a/test/test_files/test.html.ignoring b/test/test_files/test.html.ignoring
index fbdf75e..d751b3b 100644
--- a/test/test_files/test.html.ignoring
+++ b/test/test_files/test.html.ignoring
@@ -20,4 +20,9 @@ header p { margin: 0; }
 <p>foo</p>
 <h2 id="bar">bar</h2>
 <p>baz</p>
+<footer>
+Links back:
+<ul>
+</ul>
+</footer>
 </article>
\ No newline at end of file
-- 
2.30.2