From 6b5631096b03f1c985bc40c4d2e244315280c686 Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Sat, 24 Dec 2016 02:47:41 +0100
Subject: [PATCH] Add HTML templating, extend tests.

---
 README.md                                   | 12 ++++----
 processor/default.html.do                   | 32 ++++++++++-----------
 processor/helpers.sh                        | 14 +++++++--
 processor/index.html.do                     | 23 +++++++--------
 processor/metadata/article.tmpl.do          | 18 ++++++++++++
 processor/metadata/default.index_snippet.do | 16 ++++++++---
 processor/metadata/index.tmpl.do            | 18 ++++++++++++
 processor/metadata/index_snippet.tmpl.do    |  7 +++++
 test/test_files/feed.xml.ignoring           |  5 ++--
 test/test_files/foo.html                    |  7 +++--
 test/test_files/foo.rst                     |  8 ++++--
 test/test_files/index.html                  |  6 ++--
 12 files changed, 116 insertions(+), 50 deletions(-)
 create mode 100644 processor/metadata/article.tmpl.do
 create mode 100644 processor/metadata/index.tmpl.do
 create mode 100644 processor/metadata/index_snippet.tmpl.do

diff --git a/README.md b/README.md
index b7f03dd..9d6a05b 100644
--- a/README.md
+++ b/README.md
@@ -25,11 +25,13 @@ 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/. (Some
-metadata files will also be generated below ./metadata/: for each article, there
-will be generated a .uuid and a .intermediate file; furthermore, files for data
-used in ./feed.xml and ./index.html will be built and can be edited to customize
-the blog: ./metadata/url, ./metadata/author, ./metadata/uuid, ./metadata/title.) 
+These files will be linked to symbolically in a directory ./public/.
+
+Some metadata files will also be generated below ./metadata/: For each article,
+there will be generated a .uuid and a .intermediate file; furthermore, files for
+data used in ./feed.xml and ./index.html will be built there and can be edited
+to customize the blog – namely the files url, author, uuid, title, index.tmpl,
+index_snippet.tmpl, article.tmpl.
 
 bugs
 ----
diff --git a/processor/default.html.do b/processor/default.html.do
index fcef3ef..99d784d 100644
--- a/processor/default.html.do
+++ b/processor/default.html.do
@@ -4,25 +4,25 @@
 . ./helpers.sh
 metadata_dir=metadata
 intermediate_file="${metadata_dir}/${1%.html}.intermediate"
+redo-ifchange "$intermediate_file"
 title_file="${metadata_dir}"/title
 redo-ifchange "$title_file" 
-redo-ifchange "$intermediate_file"
+template_file="${metadata_dir}"/article.tmpl
+redo-ifchange "$template_file"
 
 # Build entry data.
-blog_title=`read_and_escape_file "$title_file" | head -1`
-title_html=`cat "$intermediate_file" | head -1`
+blog_title=$(read_and_escape_file "$title_file" | head -1 | prep_sed)
+title_html=$(cat "$intermediate_file" | head -1)
 title_plaintext=`echo "$title_html" | html2text`
-title_plaintext_escaped=`escape_html "$title_plaintext"`
-body=`cat "$intermediate_file" | sed 1d`
-
-# Write first part of entry head.
-cat << EOF
-<!DOCTYPE html>
-<html>
-<head>
-EOF
+title_html=$(printf "%s" "$title_html" | prep_sed)
+title_plaintext=$(escape_html "$title_plaintext" | prep_sed)
+body=$(cat "$intermediate_file" | sed 1d | prep_sed)
 
-# Write remaining entry head and body. 
-printf "<title>%s – %s</title>\n</head>\n<body>\n" "$blog_title" "$title_plaintext_escaped"
-printf "<h1>%s</h1>\n" "$title_html"
-printf "<section>\n%s\n</section>\n</body>\n</html>" "$body"
+# Put data into template.
+template=$(cat "$template_file")
+printf "%s" "$template" | \
+sed 's/%BLOG_TITLE%/'"$blog_title"'/g' | \
+sed 's/%ARTICLE_TITLE_ESCAPED%/'"$title_plaintext"'/g' | \
+sed 's/%ARTICLE_TITLE_HTML%/'"$title_html"'/g' | \
+sed 's/%BODY%/'"$body"'/g' | \
+tr '\a' '%'
diff --git a/processor/helpers.sh b/processor/helpers.sh
index 20905ab..2869a29 100644
--- a/processor/helpers.sh
+++ b/processor/helpers.sh
@@ -23,7 +23,7 @@ get_basepath() {
   url_basepath=`echo $base_url | cut -d '/' -f 3-`
   url_basepath_escaped=`escape_url "$url_basepath"`
   basepath="$url_protocol""://""$url_basepath_escaped"
-  echo "$basepath"
+  printf "%s" "$basepath"
 }
 
 get_source_file() {
@@ -37,5 +37,15 @@ get_source_file() {
     exit 1
   fi
   redo-ifchange "$src_file"
-  printf "$src_file"
+  printf "%s" "$src_file"
+}
+
+prep_sed () {
+  # Escape characters that confuse sed in a replacement string. Also replace
+  # occurences of % (which the templating uses as a variable marker) with
+  # non-printable placeholder \a (clear input of it first), to be replaced by
+  # % again when the templating has finished (so that no replacement string gets
+  # interpreted by the templating).
+  sedsafe_pattern='s/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g; $!s/$/\\/g; '
+  sed "$sedsafe_pattern" | tr -d '\a' | tr '%' '\a'
 }
diff --git a/processor/index.html.do b/processor/index.html.do
index 8636969..105bc74 100644
--- a/processor/index.html.do
+++ b/processor/index.html.do
@@ -6,16 +6,11 @@ metadata_dir=metadata
 srcdir=`pwd`
 title_file="$metadata_dir"/title
 redo-ifchange "$title_file"
+template_file="${metadata_dir}"/index.tmpl
+redo-ifchange "$template_file"
 
-# Write index head.
-cat << EOF
-<!DOCTYPE html>
-<html>
-<head>
-EOF
-blog_title=`read_and_escape_file "$title_file" | head -1`
-printf "<title>%s</title>\n</head>\n<body>\n" "$blog_title"
-printf "<h1>%s</h1>\n<ul>\n" "$blog_title"
+# Build blog title.
+title=$(read_and_escape_file "$title_file" | head -1 | prep_sed)
 
 # Generate link list entries.
 tmp_snippets_dir=.tmp_index_snippets
@@ -39,9 +34,13 @@ for file in ./${tmp_snippets_dir}/*; do
   mv ./${tmp_snippets_dir}/tmp ./${tmp_snippets_dir}/list
 done
 if [ -e "./${tmp_snippets_dir}/list" ]; then
-  cat ./${tmp_snippets_dir}/list
+  list=$(cat ./${tmp_snippets_dir}/list | prep_sed)
 fi
 rm -rf "${tmp_snippets_dir}"
 
-# Write index footer.
-printf "</ul>\n</body>\n</html>"
+# Put data into template.
+template=$(cat "$template_file")
+printf "%s" "$template" | \
+sed 's/%TITLE%/'"$title"'/g' | \
+sed 's/%LIST%/'"$list"'/g' | \
+tr '\a' '%'
diff --git a/processor/metadata/article.tmpl.do b/processor/metadata/article.tmpl.do
new file mode 100644
index 0000000..7878a3e
--- /dev/null
+++ b/processor/metadata/article.tmpl.do
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+if [ ! -f "$1" ]; then
+cat << EOF
+<!DOCTYPE html>
+<html>
+<head>
+<title>%BLOG_TITLE% – %ARTICLE_TITLE_ESCAPED%</title>
+</head>
+<body>
+<h1>%ARTICLE_TITLE_HTML%</h1>
+<section>
+%BODY%
+</section>
+</body>
+</html>
+EOF
+fi
diff --git a/processor/metadata/default.index_snippet.do b/processor/metadata/default.index_snippet.do
index e332350..c65f1a6 100644
--- a/processor/metadata/default.index_snippet.do
+++ b/processor/metadata/default.index_snippet.do
@@ -7,8 +7,16 @@ intermediate_file="${1%.index_snippet}.intermediate"
 redo-ifchange "$intermediate_file"
 html_file="${src_file%.*}.html"
 redo-ifchange "$html_file"
+template_file=index_snippet.tmpl
+redo-ifchange "$template_file"
 
-# Get variables, write entry.
-title_html=$(cat "$intermediate_file" | head -1)
-html_file_escaped=$(escape_url "${1%.index_snippet}.html")
-printf "<li><a href=\"%s\" />%s</a></li>\n" "$html_file_escaped" "$title_html"
+# Build entry data.
+title=$(cat "$intermediate_file" | head -1 | prep_sed)
+link=$(escape_url "${1%.index_snippet}.html" | prep_sed)
+
+# Put data into template.
+template=$(cat "$template_file")
+printf "%s\n" "$template" | \
+sed 's/%TITLE%/'"$title"'/g' | \
+sed 's/%LINK%/'"$link"'/g' | \
+tr '\a' '%'
diff --git a/processor/metadata/index.tmpl.do b/processor/metadata/index.tmpl.do
new file mode 100644
index 0000000..c2a9c21
--- /dev/null
+++ b/processor/metadata/index.tmpl.do
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+if [ ! -f "$1" ]; then
+cat << EOF
+<!DOCTYPE html>
+<html>
+<head>
+<title>%TITLE%</title>
+</head>
+<body>
+<h1>%TITLE%</h1>
+<ul>
+%LIST%
+</ul>
+</body>
+</html>
+EOF
+fi
diff --git a/processor/metadata/index_snippet.tmpl.do b/processor/metadata/index_snippet.tmpl.do
new file mode 100644
index 0000000..8846342
--- /dev/null
+++ b/processor/metadata/index_snippet.tmpl.do
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if [ ! -f "$1" ]; then
+cat << EOF
+<li><a href="%LINK%">%TITLE%</a></li>
+EOF
+fi
diff --git a/test/test_files/feed.xml.ignoring b/test/test_files/feed.xml.ignoring
index 0d6ea0d..dde4369 100644
--- a/test/test_files/feed.xml.ignoring
+++ b/test/test_files/feed.xml.ignoring
@@ -30,14 +30,15 @@
 </entry>
 
 <entry>
-<title type="html">a title with some nasty characters: &amp;amp;&amp;lt;&amp;gt;&amp;quot;&#x27;</title>
+<title type="html">a title with some nasty characters: &amp;amp;&amp;lt;&amp;gt;&amp;quot;&#x27; %BODY%</title>
 <id>urn:uuid:IGNORE</id>
 <updated>IGNORE</updated>
 <published>IGNORE</published>
 <link href="http://example.org/foo.html" />
 <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;p&gt;this text contains some special characters: /;%&#x27;&amp;quot;&amp;gt;&amp;lt;&amp;amp;äöüß&lt;/p&gt;
 &lt;p&gt;and more than one paragraph&lt;/p&gt;
+&lt;p&gt;note that should be ignored but \ should give a backlash&lt;/p&gt;
 </content>
 </entry>
 
diff --git a/test/test_files/foo.html b/test/test_files/foo.html
index aa3575d..dd25b70 100644
--- a/test/test_files/foo.html
+++ b/test/test_files/foo.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <head>
-<title>Yet another blog – a title with some nasty characters: &amp;&lt;&gt;&quot;&#x27;</title>
+<title>Yet another blog – a title with some nasty characters: &amp;&lt;&gt;&quot;&#x27; %BODY%</title>
 </head>
 <body>
-<h1>a title with some nasty characters: &amp;&lt;&gt;&quot;'</h1>
+<h1>a title with some nasty characters: &amp;&lt;&gt;&quot;' %BODY%</h1>
 <section>
-<p>this text contains some special characters: '&quot;&gt;&lt;&amp;</p>
+<p>this text contains some special characters: /;%'&quot;&gt;&lt;&amp;äöüß</p>
 <p>and more than one paragraph</p>
+<p>note that should be ignored but \ should give a backlash</p>
 </section>
 </body>
 </html>
\ No newline at end of file
diff --git a/test/test_files/foo.rst b/test/test_files/foo.rst
index 951861b..cf4c2df 100644
--- a/test/test_files/foo.rst
+++ b/test/test_files/foo.rst
@@ -1,6 +1,8 @@
-a title with some nasty characters: &<>"'
-=========================================
+a title with some nasty characters: &<>"' %BODY%
+================================================
 
-this text contains some special characters: '"><&
+this text contains some special characters: /;%'"><&äöüß
 
 and more than one paragraph
+
+note that \ should be ignored but \\ should give a backlash
diff --git a/test/test_files/index.html b/test/test_files/index.html
index 3210fef..84fdfb3 100644
--- a/test/test_files/index.html
+++ b/test/test_files/index.html
@@ -6,9 +6,9 @@
 <body>
 <h1>Yet another blog</h1>
 <ul>
-<li><a href="foo.html" />a title with some nasty characters: &amp;&lt;&gt;&quot;'</a></li>
-<li><a href="bar%20baz.html" />foo</a></li>
-<li><a href="test.html" />foo <em>bar</em> <strong>baz</strong></a></li>
+<li><a href="foo.html">a title with some nasty characters: &amp;&lt;&gt;&quot;' %BODY%</a></li>
+<li><a href="bar%20baz.html">foo</a></li>
+<li><a href="test.html">foo <em>bar</em> <strong>baz</strong></a></li>
 </ul>
 </body>
 </html>
\ No newline at end of file
-- 
2.30.2