summaryrefslogtreecommitdiff
path: root/bin/update_html
blob: 587ed6179e1007fbfe063ef33bd6a1d607b31bd5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/bin/bash

# Generate HTML from txt2tags (.t2t) and Markdown (.md)
# Usage:
# - update_html
#   Look for all .t2t and .md files in the current directory and below,
#   generating the output HTML when the source is newer than the HTML.
# - update_html path/to/file.t2t path/to/another.md
#   Generate HTML for the specified file(s), ignoring modification time.
#
# Requires:
# - txt2tags for .t2t files. Tested with 2.6.
# - pandoc for both .t2t and .md files. Tested with 1.16.0.2 and 2.3.1.
# - the template file `template.html` in the same directory as this script.
#
# Tested with Ubuntu 16.04 and macOS Mojave.
#
# See also clean_html for removing the files generated by this script.

# Path to directory where this script is
# https://stackoverflow.com/a/246128/98600
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"

# HTML template
template="$DIR/template.html"

# Render txt2tags into html file
# Arguments:
# 1. txt2tags source file, e.g. download/index.t2t
# 2. html target file, e.g. download/index.html
function render_t2t_html {
  t2t="$1"
  html="$2"
  tmp="$2.tmp"
  relroot="$( dirname $t2t | sed -E 's/^.\///' | sed -E 's/[^/]+/../g' )"

  # First render with txt2tags to handle pre/post processing
  txt2tags \
    --target=html \
    --no-headers \
    --quiet \
    --outfile="$tmp" \
    --infile="$t2t"

  # Replace <A NAME="toc3"></A> with <div id="toc3"></div> so that Pandoc retains it
  # Do this for both cases since BSD sed doesn't support /i
  sed -i.bak "s/<a name=\"\(.*\)\"><\/a>/<div id=\"\1\"><\/div>/" "$tmp"
  sed -i.bak "s/<A NAME=\"\(.*\)\"><\/A>/<div id=\"\1\"><\/div>/" "$tmp"
  rm -f "$tmp.bak"

  # Capture first 3 lines of t2t file: title, author, date
  # Documentation here: https://txt2tags.org/userguide/headerarea
  l1=$(head -n 1 "$t2t")
  l2=$(tail -n+2 "$t2t" | head -n 1)
  l3=$(tail -n+3 "$t2t" | head -n 1)
  title=
  author=
  date=
  if [ -n "$l1" ] ; then
    title="$l1"
    if [ -n "$l2" ] ; then author="$l2" ; fi
    if [ -n "$l3" ] ; then date="$l3" ; fi
  fi

  # Run txt2tag's HTML through Pandoc for cleanup
  pandoc \
    --from=html \
    --to=html5 \
    --standalone \
    --template="$template" \
    --variable="lang:en" \
    --variable="rel-root:$relroot" \
    --metadata="title:$title" \
    --metadata="author:$author" \
    --metadata="date:$date" \
    "$tmp" \
    --output="$html"
  rm -f "$tmp"

  # Final post-processing
  if [ -f "$html" ] ; then
    sed -i.bak "s/<table/<table class=\"table\"/" "$html" && rm "$html.bak"
    echo "$html"
  fi
}

# Render markdown into html file
# Arguments:
# 1. markdown source file, e.g. download/index.md
# 2. html target filen, e.g. download/index.html
function render_md_html {
  md="$1"
  html="$2"
  relroot="$( dirname $md | sed -E 's/^.\///' | sed -E 's/[^/]+/../g' )"

  # Look for `show-toc: true` in metadata (first ten lines of file)
  if head -n 10 "$md" | grep --quiet 'show-toc: true' ; then
    tocflag='--table-of-contents'
  else
    tocflag=''
  fi

  pandoc \
    --from=markdown \
    --to=html5 \
    --standalone \
    $tocflag \
    --template="$template" \
    --variable="lang:en" \
    --variable="rel-root:$relroot" \
    "$md" \
    --output="$html"

  # Final post-processing
  if [ -f "$html" ] ; then
    sed -i.bak "s/<table/<table class=\"table\"/" "$html" && rm "$html.bak"
    echo "$html"
  fi
}

if [ $# -gt 0 ] ; then
  # Render specific file(s) from args, ignoring dates
  for file in "$@" ; do
    ext="${file##*.}"
    html="${file%.$ext}.html"
    case $ext in
      "md")
        render_md_html "$file" "$html"
        ;;
      "t2t")
        render_t2t_html "$file" "$html"
        ;;
    esac
  done
else
  # Render all files found in cwd and deeper if source is newer
  find . -name '*.t2t' | while read file ; do
    html="${file%.t2t}.html"
    if [ "$file" -nt "$html" ] || [ "$template" -nt "$html" ] ; then
      render_t2t_html "$file" "$html"
    fi
  done
  find . -name '*.md' | while read file ; do
    if [[ "$file" == *"README.md" ]] ; then continue ; fi
    html="${file%.md}.html"
    if [ "$file" -nt "$html" ] || [ "$template" -nt "$html" ] ; then
      render_md_html "$file" "$html"
    fi
  done
fi