summaryrefslogtreecommitdiffhomepage
path: root/www
diff options
context:
space:
mode:
authorHsieh Chin Fan <typebrook@gmail.com>2022-02-02 13:34:47 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-11-30 21:09:29 +0800
commit9934dd538b0ce116e3b1600272cb46369b082246 (patch)
tree2f28c6c362201151eaf8218e566479ed7eb72070 /www
init commit
Diffstat (limited to 'www')
-rw-r--r--www/.gitignore1
-rw-r--r--www/Makefile14
-rw-r--r--www/assets/favicon.icobin0 -> 549 bytes
-rw-r--r--www/assets/gpg.asc84
-rw-r--r--www/assets/robots.txt4
-rw-r--r--www/assets/style.css213
-rw-r--r--www/assets/wp-admin.php1
-rwxr-xr-xwww/scripts/add-graph.py35
-rwxr-xr-xwww/scripts/build.sh188
-rw-r--r--www/templates/footer.html4
-rw-r--r--www/templates/head.html10
-rw-r--r--www/templates/header.html17
-rw-r--r--www/templates/index.md1
13 files changed, 572 insertions, 0 deletions
diff --git a/www/.gitignore b/www/.gitignore
new file mode 100644
index 0000000..364fdec
--- /dev/null
+++ b/www/.gitignore
@@ -0,0 +1 @@
public/
diff --git a/www/Makefile b/www/Makefile
new file mode 100644
index 0000000..80b9d47
--- /dev/null
+++ b/www/Makefile
@@ -0,0 +1,14 @@
1.ONESHELL:
2ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST))))
3
4# build html files for public/
5build:
6 @input_dir=~/log/posts \
7 output_dir=/srv/http \
8 assets_dir=$(ROOT_DIR)assets \
9 template_dir=$(ROOT_DIR)templates \
10 $(ROOT_DIR)scripts/build.sh
11
12# Migrage frontmatter from '---' to HTML comment '<!-- -->'
13frontmatter:
14 find content -type f -name '*.md' | xargs sed -i ':frontmatter { 1s/^---/<!--/; 1!s/^---/-->/; 1!b}; /^---/ {1b frontmatter}'
diff --git a/www/assets/favicon.ico b/www/assets/favicon.ico
new file mode 100644
index 0000000..5af1857
--- /dev/null
+++ b/www/assets/favicon.ico
Binary files differ
diff --git a/www/assets/gpg.asc b/www/assets/gpg.asc
new file mode 100644
index 0000000..f33181e
--- /dev/null
+++ b/www/assets/gpg.asc
@@ -0,0 +1,84 @@
1-----BEGIN PGP PUBLIC KEY BLOCK-----
2
3mQGNBGAzCdIBDACvt2iu+FTg+p3Q5p/J8Q7643g61n3kgIgDt9a5JU06nwAGDmX+
4hIrVy5OxsTntJzRkvV+nr0cR9Suvkci9RfJ9TixjMca+Eld3pPLhdPGmtPofjCaj
5LpKMkPdHg+VU4B7BANwsd/on7VYLq5Ko6dj1HKrp3KJappP5njK1u39DQHjLPEjK
6976nyErOdKNVjswIWdLFJgWhC46mH3zW4aOtkw8UIn32fbCmpZyuVU8ooJTbIl6+
7YvU9BsYRgEhSjQbi+RXQZAyUqsQlZnS8/81pwanKs6NFqBSTFaryHVfbC1McXHNY
8V3+Y/rGEmUIn2FXhHWWHb8b5oBroZQLbHVpjWV3DZgkTN0c8g+K3hQ1iLFAdWuQg
9wxBuzkq/5AMiqJ/0gUjkT4uW12fIEQR30wvveVDq/BMWdhC4tgy+ft5QcBjA3xj2
10xC813/r3cvgfWaJvB5/mUH4QPv1gESG9QdjAVOBMt/TTnKJFes5iuq1q0+ZdnG0S
11KZ1aFlfbGgZWcW8AEQEAAbQvdHlwZWJyb29rIDx0eXBlYnJvb2tAZ21haWwuY29t
12PiAoR21haWwgQWNjb3VudCmJAdQEEwEIAD4WIQQSgUZMDGWhjNgJ9OxmRzq+mhjP
13LQUCYEnKDgIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRBmRzq+
14mhjPLe7zC/9/6O4+icJc74Y/d/VhJv4k/Zc3b2ZlMrdGq/FDQTYSISPPo2k6hgcS
15IQw2SPNb0hRkoaj7Dj3tMFzumSrGMyfGNXHThYWh3UABSTkTnYIXMNhd+on7VpfZ
16FqkBrIfgv+Im7Gops66L7x9b3BT16yxb373uG9bhe+w/Kzk8Mix6f57M9f21f/MI
17trOKbA50HG6scpmytJ5YHiu7qZVihhVewJDX32e9W9fpMu3Kos+SCDOzxIrLl8An
18/8WrSTqAMh/RGYKaxL6A+JjZyhDMXjWMZfvCPfzFrfF60D3ppcDtatqYvMk76i+c
19QW8Oiyv8CRWEK9CzSXptz/MsDwzVKn4UV4QFyoCmB4EGLB7+lbSbnNdtZeluoElG
20+HKIwayJ9s09m3AItTIoyaejjLp7+NgivoUWueW8c2z4KHSY9uJYij0+3k9VASfx
21Njs7DdiWcgezi4BIHS0dC7sRLmJ2U5Bt0oHyRzoDa67trumCLKc/b8xAEaZZCO8z
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
82RWr5Ni7wyLHOaHhoDLK9i+Fz
83=DNGE
84-----END PGP PUBLIC KEY BLOCK-----
diff --git a/www/assets/robots.txt b/www/assets/robots.txt
new file mode 100644
index 0000000..41f82c4
--- /dev/null
+++ b/www/assets/robots.txt
@@ -0,0 +1,4 @@
1User-agent: *
2Allow: /
3
4Sitemap: https://topo.tw/sitemap.xml
diff --git a/www/assets/style.css b/www/assets/style.css
new file mode 100644
index 0000000..2752323
--- /dev/null
+++ b/www/assets/style.css
@@ -0,0 +1,213 @@
1header {
2 display: flex;
3 justify-content: space-between;
4 margin-top: 1rem;
5}
6
7footer * {
8 display: inline;
9}
10
11blockquote {
12 color: gray;
13 font-size: 1.2rem;
14 font-style: italic;
15
16 text-align: center;
17}
18
19p code {
20 margin-inline: 0.2rem;
21 padding-inline: 6px;
22}
23
24/* Neat CSS: https://neat.joeldare.com */
25* {
26 box-sizing: border-box;
27}
28
29:root {
30 color-scheme: light dark;
31 --light: #fff;
32 /* --light: #f7f7f7; */
33 --lesslight: #efefef;
34 --dark: #404040;
35 --moredark: #000;
36 /*--link: royalblue; */
37 --link: #850000;
38 --link-highlight-color: #ffdcda;
39 /* border-top: 5px solid var(--dark); */
40 line-height: 1.5em;
41 font-family: system-ui, sans-serif;
42 font-size: 16px;
43 color: var(--dark);
44}
45
46h1 {
47 line-height: 1em;
48}
49
50button, input {
51 font-size: 1em; /* Override browser default font shrinking*/
52}
53
54input {
55 border: 1px solid var(--dark);
56 background-color: var(--lesslight);
57 border-radius: .25em;
58 padding: .5em;
59}
60
61pre {
62 background-color: var(--lesslight);
63 margin: 0.5em 0 0.5em 0;
64 padding: 0.5em;
65 overflow: auto;
66}
67
68code {
69 background-color: var(--lesslight);
70}
71
72body {
73 background-color: var(--light);
74 margin: 0;
75 max-width: 800px;
76 padding: 0 20px 20px 20px;
77 margin-left: auto;
78 margin-right: auto;
79}
80
81a {
82 outline: none;
83 text-decoration: underline 2px var(--link-highlight-color);
84 color: var(--link);
85}
86
87a:hover {
88 background: var(--link-highlight-color);
89}
90
91img {
92 max-width: 100%;
93 height: auto;
94}
95
96button, .button, input[type=submit] {
97 display: inline-block;
98 background-color: var(--dark);
99 color: var(--light);
100 text-align: center;
101 padding: .5em;
102 border-radius: .25em;
103 text-decoration: none;
104 border: none;
105 cursor: pointer;
106}
107
108button:hover, .button:hover, input[type=submit]:hover {
109 color: var(--lesslight);
110 background-color: var(--moredark);
111}
112
113/* Add a margin between side-by-side buttons */
114button + button, .button + .button, input[type=submit] + input[type=submit] {
115 margin-left: 1em;
116}
117
118.center {
119 display: block;
120 margin-left: auto;
121 margin-right: auto;
122 text-align: center;
123}
124
125.bordered {
126 border: 3px solid;
127}
128
129.home {
130 display: inline-block;
131 background-color: var(--dark);
132 color: var(--light);
133 margin-top: 20px;
134 padding: 5px 10px 5px 10px;
135 text-decoration: none;
136 font-weight: bold;
137}
138
139
140/* Desktop sizes */
141@media (min-width: 600px) {
142 ol.twocol {
143 column-count: 2;
144 }
145
146 .row {
147 display: flex;
148 flex-direction: row;
149 padding: 0;
150 width: 100%;
151 }
152
153 /* Make everything in a row a column */
154 .row > * {
155 display: block;
156 flex: 1 1 auto;
157 max-width: 100%;
158 width: 100%;
159 }
160
161 .row > *:not(:last-child) {
162 margin-right: 10px;
163 }
164}
165
166/* Dark mode overrides (confusingly inverse) */
167@media (prefers-color-scheme: dark) {
168 :root {
169 --light: #222;
170 --lesslight: #333;
171 --dark: #eee;
172 --moredark: #fefefe;
173 }
174 /* This fixes an odd blue then white shadow on FF in dark mode */
175 *:focus {
176 outline: var(--light);
177 box-shadow: 0 0 0 .25em var(--link);
178 }
179}
180
181/* Printing */
182@media print {
183 .home {
184 display: none;
185 }
186}
187
188[data-tooltip]{
189 display: inline-block;
190 position: relative;
191
192 &::after {
193 display: block;
194 position: absolute;
195 content: attr(data-tooltip);
196 background: var(--dark);
197 color: var(--lesslight);
198 padding: .25em;
199 cursor: default;
200 user-select: text;
201
202 transition:
203 visibility .3s ease-out,
204 opacity .3s ease-out;
205 visibility: hidden;
206 opacity: 0;
207 }
208
209 &:hover::after {
210 opacity: 1;
211 visibility: visible;
212 }
213}
diff --git a/www/assets/wp-admin.php b/www/assets/wp-admin.php
new file mode 100644
index 0000000..b774c98
--- /dev/null
+++ b/www/assets/wp-admin.php
@@ -0,0 +1 @@
Got you!
diff --git a/www/scripts/add-graph.py b/www/scripts/add-graph.py
new file mode 100755
index 0000000..455b45a
--- /dev/null
+++ b/www/scripts/add-graph.py
@@ -0,0 +1,35 @@
1#! /bin/python3
2
3import sys, subprocess
4from datetime import date
5from bs4 import BeautifulSoup
6
7def handle(html):
8 soup = BeautifulSoup(html, 'html.parser')
9 for graph in soup.select('pre.language-graph'):
10 print()
11 print(date.today().strftime("%H:%M:%S"))
12 print('before:')
13 print(graph.string)
14
15 process = subprocess.Popen(
16 ["/usr/bin/vendor_perl/graph-easy", "--boxart"],
17 stdin=subprocess.PIPE,
18 stdout=subprocess.PIPE,
19 stderr=subprocess.PIPE
20 )
21 output, error = process.communicate(input=graph.get_text().encode())
22 graph.string = output.decode()
23
24 print('After:')
25 print(graph.string)
26 print('Error:')
27 print(error.decode())
28 return str(soup)
29
30for line in sys.stdin:
31 file = line.rstrip("\n")
32 with open(file, 'r') as html:
33 new_content = handle(html)
34 with open(file, 'w') as html:
35 html.write(new_content)
diff --git a/www/scripts/build.sh b/www/scripts/build.sh
new file mode 100755
index 0000000..9b95c99
--- /dev/null
+++ b/www/scripts/build.sh
@@ -0,0 +1,188 @@
1#! /bin/bash
2
3set -e
4
5# Executable command for markdown
6markdown_bin="markdown -f fencedcode,autolink,alphalist,autolink,footnote"
7
8# Directory for input/output
9input_dir=${input_dir:?ENV \"input_dir\" is not set}
10output_dir=${output_dir:?ENV \"output_dir\" is not set}
11assets_dir=${assets_dir:?ENV \"assets_dir\" is not set}
12template_dir=${template_dir:?ENV \"template_dir\" is not set}
13
14# functions {{{
15
16# add indent for each line except <pre>
17indent() {
18 indent="$(printf "%${1}s")"
19 sed "s/^/${indent}/; /<pre>/!b; :pre; N; /<\/pre>/!b pre"
20}
21
22# use heredoc to generate html from .md file and templates
23html() {
24 <<-END_OF_HTML sed '1d;$d'
25
26 <!DOCTYPE html>
27 <html lang="en">
28 ${head}
29 <body>
30 ${header}
31 <hr><br>
32 <main>
33 $(${markdown_bin} | indent 4)
34 </main>
35 <br><hr>
36 ${footer}
37 </body>
38 </html>
39
40 END_OF_HTML
41}
42
43# list of latest posts in markdown format
44latest_posts() {
45 (IFS=$'\n'; echo "${index_list[*]}") | sort -r | head -20 | while read date path title; do
46 echo "- <time datetime="$date">$date</time> [$title](/$path)"
47 done
48}
49
50# print frontmatter from markdown file with format: "<key> <value>"
51get_frontmatter() {
52 sed -n '1 {/<!--/ !q; n}; /-->/q; s/"//g; s/://p'
53}
54
55# process frontmatter
56add_index() {
57 unset title public index date draft
58
59 # define local variables for frontmatter
60 while read key value; do
61 local -r $key="$value"
62 done <<<"$(get_frontmatter)"
63
64 # don't process draft after function call
65 test "$draft" != "" && return 1
66
67 # skip making index in some cases
68 test "$public" = false && return 0
69 test "$index" = false && return 0
70 test "$type" = demo && return 0
71 test "$title" = "" && return 0
72 iso8601=$(date --iso --date "${date:-NULL}" 2>/dev/null)
73 test "$iso8601" = "" && return 0
74
75 # put frontmatter info into variable "index" if title and date are valid
76 index_list+=("$iso8601 $path $title")
77}
78
79# remove SGML comments but keep the top one as frontmatter
80ignore_comment() {
81 sed '1 !{ /^<!--$/,/^-->$/ d }'
82}
83
84# Generate the feed file
85make_rss() {
86 echo -n "Making RSS "
87
88 rssfile=$blog_feed.$RANDOM
89 while [[ -f $rssfile ]]; do rssfile=$blog_feed.$RANDOM; done
90
91 {
92 pubdate=$(LC_ALL=C date +"$date_format_full")
93 cat <<-EOF
94 <?xml version="1.0" encoding="UTF-8" ?>'
95 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">'
96 <channel><title>Dummy Website</title><link>https://topo.tw/index.xml</link>"
97 <description>$global_description</description><language>en</language>"
98 <lastBuildDate>$pubdate</lastBuildDate>"
99 <pubDate>$pubdate</pubDate>"
100 <atom:link href="$global_url/$blog_feed" rel="self" type="application/rss+xml" />"
101 EOF
102
103 n=0
104 while IFS='' read -r i; do
105 is_boilerplate_file "$i" && continue
106 ((n >= number_of_feed_articles)) && break # max 10 items
107 echo -n "." 1>&3
108 echo '<item><title>'
109 get_post_title "$i"
110 echo '</title><description><![CDATA['
111 get_html_file_content 'text' 'entry' $cut_do <"$i"
112 echo "]]></description><link>$global_url/${i#./}</link>"
113 echo "<guid>$global_url/$i</guid>"
114 echo "<dc:creator>$(get_post_author "$i")</dc:creator>"
115 echo "<pubDate>$(LC_ALL=C date -r "$i" +"$date_format_full")</pubDate></item>"
116
117 n=$(( n + 1 ))
118 done < <(ls -t ./*.html)
119
120 echo '</channel></rss>'
121 } 3>&1 >"$rssfile"
122 echo ""
123
124 mv "$rssfile" "$blog_feed"
125 chmod 644 "$blog_feed"
126}
127
128# }}}
129# prepare directory for outputs {{{
130
131mkdir -p $output_dir/
132rm -rf $output_dir/**
133ln -s $assets_dir/* $output_dir/
134
135# }}}
136# content of templates {{{
137
138head="$(cat $template_dir/head.html)"
139header="$(cat $template_dir/header.html | indent 2)"
140footer="$(cat $template_dir/footer.html | indent 2)"
141index_list=()
142index_template="$(cat $template_dir/index.md)"
143
144# }}}
145# for each markdown file {{{
146
147files="$(find "$input_dir" -type f -name '*md')"
148total=$(wc -l <<<"$files")
149declare -i counter
150for file in $files; do
151 # set variables
152 path=$(<<<"$file" sed "s#^${input_dir}/##; s/\.md$//").html; mkdir -p $(dirname $output_dir/$path)
153 content="$(cat ${file} | ignore_comment)"
154
155 # use frontmatter to decide making html file or not
156 <<<"$content" add_index || continue
157
158 # log
159 echo -e "\033[1K\r$((counter+=1))/$total \t\t processing $path"
160
161 # make html file for draft
162 h1="$(<<<"$content" get_frontmatter | sed -n 's/^title *//p')"
163 echo "$content" \
164 | tee $output_dir/${file#${input_dir}/} \
165 | { [ -n "$h1" ] && echo "# $h1"; cat; } \
166 | html >$output_dir/$path
167done
168echo
169
170# }}}
171# make index.html {{{
172
173{
174 echo "${index_template}"
175 echo -e '<br><br>\n\n'
176 latest_posts
177} \
178| tee $output_dir/index.md \
179| html >$output_dir/index.html
180
181echo -e index.html "\t" generated
182
183# }}}
184# make index.xml {{{
185
186
187
188# }}}
diff --git a/www/templates/footer.html b/www/templates/footer.html
new file mode 100644
index 0000000..9e87e02
--- /dev/null
+++ b/www/templates/footer.html
@@ -0,0 +1,4 @@
1<footer>
2 <address><a href="mailto:info@topo.tw">info@topo.tw</a></address> |
3 <a href="http://creativecommons.org/publicdomain/zero/1.0" rel="license noopener noreferrer">CC0 1.0</a>
4</footer>
diff --git a/www/templates/head.html b/www/templates/head.html
new file mode 100644
index 0000000..ede99c9
--- /dev/null
+++ b/www/templates/head.html
@@ -0,0 +1,10 @@
1<head>
2 <meta charset="UTF-8">
3 <meta name="viewport" content="width=device-width, initial-scale=1.0">
4 <meta http-equiv="X-UA-Compatible" content="ie=edge">
5
6 <title>Dummy Site</title>
7
8 <link rel="stylesheet" href="/style.css">
9 <link rel="icon" href="/favicon.ico" type="image/x-icon">
10</head>
diff --git a/www/templates/header.html b/www/templates/header.html
new file mode 100644
index 0000000..a77079a
--- /dev/null
+++ b/www/templates/header.html
@@ -0,0 +1,17 @@
1<header>
2 <nav class="left">
3 <a href="/">Home</a> |
4 <a href="/about.html" data-tooltip="About this site">About</a> |
5 <a href="/posts/">Posts</a> |
6 <a href="/projects.html" data-tooltip="Not valid now...">Projects</a> |
7 <!--
8 <a href="/links.html" data-tooltip="Cool sites you might be interested">Links</a>
9 -->
10 <a href="/links.html" data-tooltip="Not valid now...">Links</a>
11 </nav>
12 <nav class="right">
13 <a href="/rss.xml" data-tooltip="Not valid now...">RSS</a> |
14 <a href="https://git.topo.tw" data-tooltip="Public Git Repos">Code</a> |
15 <a href="/gpg.asc">GPG</a>
16 </nav>
17</header>
diff --git a/www/templates/index.md b/www/templates/index.md
new file mode 100644
index 0000000..5743a19
--- /dev/null
+++ b/www/templates/index.md
@@ -0,0 +1 @@
> There should be a intro for this site, but I cannot came up with any idea about this...