summaryrefslogtreecommitdiffhomepage
path: root/www
diff options
context:
space:
mode:
authorHsieh Chin Fan <pham@topo.tw>2024-12-15 00:41:50 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-12-15 00:41:50 +0800
commit465c4ba5b4f0b4f69fd3773fc4f9f9650b7fffa0 (patch)
tree769146b9e30a5ce77cee7535a9c807eeecc8a35e /www
parentb604d49cfac78f0061ffee2373dede6206db6667 (diff)
add rss
Diffstat (limited to 'www')
-rw-r--r--www/Makefile5
-rwxr-xr-xwww/scripts/build.sh172
2 files changed, 91 insertions, 86 deletions
diff --git a/www/Makefile b/www/Makefile
index ab6a39e..cf45b29 100644
--- a/www/Makefile
+++ b/www/Makefile
@@ -4,8 +4,9 @@ ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
4# build html files for public/ 4# build html files for public/
5build: 5build:
6 cd $(ROOT_DIR) 6 cd $(ROOT_DIR)
7 export input_dir=~/log/public 7 export INPUT_DIR=~/log/public
8 export output_dir=/srv/http 8 export OUTPUT_DIR=/srv/http
9 export HOST=topo.tw
9 @scripts/build.sh 10 @scripts/build.sh
10 11
11# Migrage frontmatter from '---' to HTML comment '<!-- -->' 12# Migrage frontmatter from '---' to HTML comment '<!-- -->'
diff --git a/www/scripts/build.sh b/www/scripts/build.sh
index e3757ac..23c4a70 100755
--- a/www/scripts/build.sh
+++ b/www/scripts/build.sh
@@ -3,13 +3,15 @@
3set -e 3set -e
4 4
5# Executable command for markdown 5# Executable command for markdown
6markdown_bin="markdown -f fencedcode,autolink,alphalist,autolink,footnote,definitionlist" 6declare -r MARKDOWN_BIN="markdown -f fencedcode,autolink,alphalist,autolink,footnote,definitionlist"
7 7
8# Directory for input/output 8# Directory for input/output
9input_dir=${input_dir:?ENV \"input_dir\" is not set} 9declare -r INPUT_DIR=${INPUT_DIR:?ENV \"INPUT_DIR\" is not set}
10output_dir=${output_dir:?ENV \"output_dir\" is not set} 10declare -r OUTPUT_DIR=${OUTPUT_DIR:?ENV \"OUTPUT_DIR\" is not set}
11assets_dir=${assets_dir:-`pwd`/assets} 11declare -r ASSET_DIR=${ASSET_DIR:-`pwd`/assets}
12template_dir=${template_dir:-`pwd`/templates} 12declare -r TEMPLATE_DIR=${TEMPLATE_DIR:-`pwd`/templates}
13declare -r RSSFILE=feed.rss
14declare -r HOST=${HOST:?}
13 15
14# functions {{{ 16# functions {{{
15 17
@@ -41,22 +43,22 @@ comment_block() {
41} 43}
42 44
43# }}} 45# }}}
44# use heredoc to generate html from .md file and templates {{{ 46# generate html by heredoc from .md file and templates {{{
45html() { 47html() {
46 <<-END_OF_HTML sed '1d;$d' 48 <<-END_OF_HTML sed '1d;$d'
47 49
48 <!DOCTYPE html> 50 <!DOCTYPE html>
49 <html lang="en"> 51 <html lang="en">
50 ${head} 52 $(echo "$HEAD" | { [ -z "${title}" ] && cat || sed "/^ *<title>/c \ \ <title>${title}</title>"; } )
51 <body> 53 <body>
52 ${header} 54 ${HEADER}
53 <hr><br> 55 <hr><br>
54 <main> 56 <main>
55 $(${markdown_bin} | indent 4) 57 $(${MARKDOWN_BIN} | indent 4)
56 </main> 58 </main>
57 $(comment_block | indent 2) 59 $(comment_block | indent 2)
58 <br><hr> 60 <br><hr>
59 ${footer} 61 ${FOOTER}
60 </body> 62 </body>
61 </html> 63 </html>
62 64
@@ -73,31 +75,28 @@ latest_posts() {
73} 75}
74 76
75# }}} 77# }}}
76# print frontmatter from markdown file with format: "<key> <value>" {{{ 78# process frontmatter {{{
77 79
78get_frontmatter() { 80get_frontmatter() {
79 sed -n '1 {/<!--/ !q; n}; /-->/q; s/"//g; s/://p' 81 sed -n '1 {/<!--/ !q; n}; /-->/q; s/"//g; s/://p'
80} 82}
81 83
82# }}} 84check_frontmatter() {
83# process frontmatter {{{ 85 unset title public index type date draft
84
85add_index() {
86 unset title public index date draft
87 86
88 # define local variables for frontmatter 87 # define local variables for frontmatter
89 while read key value; do 88 while read key value; do
90 local -r $key="$value" 89 export ${key,,}="$value"
91 done <<<"$(get_frontmatter)" 90 done <<<"$(get_frontmatter)"
92 91
93 # don't process draft after function call 92 # don't process draft after function call
94 test "$draft" != "" && return 1 93 test "$draft" != "" && return 1
95 94
96 # skip making index in some cases 95 # skip making index in some cases
96 test "$title" = "" && return 0
97 test "$public" = false && return 0 97 test "$public" = false && return 0
98 test "$index" = false && return 0 98 test "$index" = false && return 0
99 test "$type" = demo && return 0 99 test "$type" = demo && return 0
100 test "$title" = "" && return 0
101 iso8601=$(date --iso --date "${date:-NULL}" 2>/dev/null) 100 iso8601=$(date --iso --date "${date:-NULL}" 2>/dev/null)
102 test "$iso8601" = "" && return 0 101 test "$iso8601" = "" && return 0
103 102
@@ -109,99 +108,97 @@ add_index() {
109# remove SGML comments but keep the top one as frontmatter {{{ 108# remove SGML comments but keep the top one as frontmatter {{{
110 109
111ignore_comment() { 110ignore_comment() {
112 sed '1 !{ /^<!--$/,/^-->$/ d }' 111 sed '1! { /^<!--$/,/^-->$/ d }'
113} 112}
114 113
115# }}} 114# }}}
116# Generate the feed file {{{ 115# RSS Feed {{{
116
117get_channel_item() {
118 path=${1#${OUTPUT_DIR}}
119 <<-ITEM cat
120 <item>
121 $(grep -Po '<title>.+</title>' ${1} | head -1)
122 <link>https://${HOST}${path}</link>
123 <guid isPermaLink="false">$(md5sum ${1} | cut -d' ' -f1)</guid>
124 <pubDate>$(date --rfc-email -r ${1})</pubDate>
125 </item>
126 ITEM
127}
117 128
118make_rss() { 129make_rss() {
119 echo -n "Making RSS " 130 # Use modified time to get latest html files
120 131 items="$(
121 rssfile=$blog_feed.$RANDOM 132 ls -1t $OUTPUT_DIR/**/**html \
122 while [[ -f $rssfile ]]; do rssfile=$blog_feed.$RANDOM; done 133 | head -10 \
123 134 | while read html_file; do
124 { 135 get_channel_item $html_file
125 pubdate=$(LC_ALL=C date +"$date_format_full") 136 done \
126 cat <<-EOF 137 | indent 2 \
127 <?xml version="1.0" encoding="UTF-8" ?>' 138 )"
128 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">' 139
129 <channel><title>Dummy Website</title><link>https://topo.tw/index.xml</link>" 140 <<-RSS cat
130 <description>$global_description</description><language>en</language>" 141 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" >
131 <lastBuildDate>$pubdate</lastBuildDate>" 142 <channel>
132 <pubDate>$pubdate</pubDate>" 143 <title>Dummy Website</title>
133 <atom:link href="$global_url/$blog_feed" rel="self" type="application/rss+xml" />" 144 <link>https://${HOST}</link>
134 EOF 145 <atom:link href="http://${HOST}/${RSSFILE}" rel="self" type="application/rss+xml" />
135 146 <description>$global_description</description>
136 n=0 147 <language>zh-tw</language>
137 while IFS='' read -r i; do 148 <pubDate>$(date --rfc-email)</pubDate>
138 is_boilerplate_file "$i" && continue 149 <docs>https://www.rssboard.org/rss-specification</docs>
139 ((n >= number_of_feed_articles)) && break # max 10 items 150 ${items}
140 echo -n "." 1>&3 151 </channel>
141 echo '<item><title>' 152 </rss>
142 get_post_title "$i" 153 RSS
143 echo '</title><description><![CDATA['
144 get_html_file_content 'text' 'entry' $cut_do <"$i"
145 echo "]]></description><link>$global_url/${i#./}</link>"
146 echo "<guid>$global_url/$i</guid>"
147 echo "<dc:creator>$(get_post_author "$i")</dc:creator>"
148 echo "<pubDate>$(LC_ALL=C date -r "$i" +"$date_format_full")</pubDate></item>"
149
150 n=$(( n + 1 ))
151 done < <(ls -t ./*.html)
152
153 echo '</channel></rss>'
154 } 3>&1 >"$rssfile"
155 echo ""
156
157 mv "$rssfile" "$blog_feed"
158 chmod 644 "$blog_feed"
159} 154}
160 155
161# }}} 156# }}}
157
162# }}} 158# }}}
163# prepare directory for outputs {{{ 159# prepare directory for outputs {{{
164 160
165mkdir -p $output_dir/ 161mkdir -p $OUTPUT_DIR/
166rm -rf $output_dir/** 162rm -rf $OUTPUT_DIR/**
167ln -s $assets_dir/* $output_dir/ 163ln -s $ASSET_DIR/* $OUTPUT_DIR/
168 164
169# }}} 165# }}}
170# content of templates {{{ 166# content of templates {{{
171 167
172head="$(cat $template_dir/head.html)" 168declare -r HEAD="$(cat $TEMPLATE_DIR/head.html)"
173header="$(cat $template_dir/header.html | indent 2)" 169declare -r HEADER="$(<$TEMPLATE_DIR/header.html indent 2)"
174footer="$(cat $template_dir/footer.html | indent 2)" 170declare -r FOOTER="$(<$TEMPLATE_DIR/footer.html indent 2)"
171declare -r INDEX_TEMPLATE="$(cat $TEMPLATE_DIR/index.md)"
175index_list=() 172index_list=()
176index_template="$(cat $template_dir/index.md)"
177 173
178# }}} 174# }}}
179# for each markdown file {{{ 175# for each markdown file {{{
180 176
181files="$(find "$input_dir" -type f -name '*md')" 177files="$(find "$INPUT_DIR" -type f -name '*md')"
182total=$(wc -l <<<"$files") 178total=$(wc -l <<<"$files")
183declare -i counter 179declare -i counter
184for file in $files; do 180for file in $files; do
185 # set variables 181 # set variables
186 path=$(<<<"$file" sed "s#^${input_dir}/##; s/\.md$//").html; mkdir -p $(dirname $output_dir/$path) 182 path=$(<<<"$file" sed "s#^${INPUT_DIR}/##; s/\.md$//").html; mkdir -p $(dirname $OUTPUT_DIR/$path)
187 content="$(<${file} ignore_comment)" 183 content="$(<${file} ignore_comment)"
188 184
189 # use frontmatter to decide making html file or not 185 # use frontmatter to decide making html file or not
190 <<<"$content" add_index || continue 186 <<<"$content" check_frontmatter || continue
191 187
192 # log 188 # log
193 echo -e "\033[1K\r$((counter+=1))/$total \t\t processing $path" 189 echo -e "\033[1K\r$((counter+=1))/$total \t\t processing $path"
194 190
195 # make html file for draft 191 # add original content to $OUTPUT_DIR
196 h1="$(<<<"$content" get_frontmatter | sed -n 's/^title *//p')"
197 comment="$(<<<"$content" get_frontmatter | sed -n 's/^comment *//p')"
198
199 # add original content to $output_dir
200 # and generate html file with <h1> 192 # and generate html file with <h1>
201 echo "$content" \ 193 echo "$content" \
202 | tee $output_dir/${file#${input_dir}/} \ 194 | tee $OUTPUT_DIR/${file#${INPUT_DIR}/} \
203 | { [ -n "$h1" ] && echo "# $h1"; cat; } \ 195 | { [ -n "$title" ] && echo "# $title"; cat; } \
204 | html >$output_dir/$path 196 | html >$OUTPUT_DIR/$path
197
198 # Set modified time for index/RSS
199 mtime='@0'
200 [ ! "$public" = false ] && [ -n "$iso8601" ] && mtime="$iso8601"
201 touch -m -d "$mtime" $OUTPUT_DIR/$path
205 202
206 unset h1 comment 203 unset h1 comment
207done 204done
@@ -210,19 +207,26 @@ echo
210# }}} 207# }}}
211# make index.html {{{ 208# make index.html {{{
212 209
210echo -en "Making\t\tindex.html"
211export title=""
213{ 212{
214 echo "${index_template}" 213 echo "${INDEX_TEMPLATE}"
215 echo -e '<br><br>\n\n' 214 echo -e '<br><br>\n\n'
216 latest_posts 215 latest_posts
217} \ 216} \
218| tee $output_dir/index.md \ 217| tee $OUTPUT_DIR/index.md \
219| html >$output_dir/index.html 218| html >$OUTPUT_DIR/index.html
220 219
221echo -e index.html "\t" generated 220touch -m -d @0 $OUTPUT_DIR/index.html
221echo -e "\tgenerated"
222 222
223# }}} 223# }}}
224# make index.xml {{{ 224# make RSS file {{{
225
226 225
226echo -en "Making\t\tRSS"
227make_rss >$OUTPUT_DIR/$RSSFILE
228echo -e "\t\tgenerated"
227 229
228# }}} 230# }}}
231
232# vim: fdm=marker fdl=0