about summary refs log tree commit diff stats
path: root/jimmy.sh
blob: f039f4f2ac5bb2e54faaf6a33c8ecbb27692a58d (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
#!/bin/sh

BLOCK=
BUFFER=

process() {
	while read -r LINE
	do
		if test "$BLOCK" = verbatim
		then
			printf '%s\n' "$LINE"
			continue
		fi

		set -- $LINE

		case "$LINE" in
			('```')
				if test "$BLOCK" = verbatim
				then BLOCK=
				else BLOCK=verbatim
				fi
				;;
			('')
				if test "$BLOCK" = verbatim
				then bufpush $'\n'
				else bufclose
				fi
				;;
			('=>'*) link "$@" ;;
			('#'*) header "$@" ;;
			('*'*) shift; blknew list "$*" ;;
			('>'*) shift; blknew quote "$*" ;;
			(*) shift; blknew paragraph "$*" ;;
		esac
	done
	bufclose
}

blknew() {
	test "$BLOCK" = "$1" || bufclose
	bufpush "$(printf "$(eval echo "\$format_$BLOCK")" "$@")"
	BLOCK="$1"
}

bufclose() {
	if test -z "$BLOCK"
	then "$COLLAPSE_BLANKS" && return
	else newline; return
	fi

	# blockp "$BLOCK" || return
	# fillp $BLOCK && buffill "$(fillp $BLOCK)"

	# TODO: escape shit

	printf '%s%s%s\n' \
	       "$(echo eval "\$opener_$BLOCK")" \
	       "$BUFFER" \
	       "$(echo eval "\$closer_$BLOCK")"

	BLOCK=
}

buffill() { # buffill WIDTH
	if test $1 -lt 0
	then BUFFER="$(printf '%s\n' "$BUFFER" | tr '\n' ' ')"
	else
		out=
		nline=0
		printf '%s\n' "$BUFFER" | sed 's/[ \t]\+/\n/g' |
			while read -r word
			do
				if test $((nline + ${#word})) -ge "$1"
				then
					out="${out}"${out:+$'\n'}"${word}"
					nline=${#word}
				else
					out="${out}${out:+ }${word}"
					nline=$((nline + ${#word} + 1))
				fi
			done
		BUFFER="$out"
	fi
}

bufpush() { BUFFER="${BUFFER}$@"; }

fillp() {
	:
}

header() {
	bufclose
	lvl=${#1}; shift
	bufpush "$(printf "$(eval echo "\$format_h$lvl")" "$*")"
	BLOCK=header
}

link() {
	url="$2"; shift 2
	if test "$BLOCK" = paragraph #&& ! blockp link
	then bufpush "$(printf "$format_link" "$url" "$*")"
	else blknew linklist "$url" "$*"
	fi
}

newline() { printf '\n'; }

html() {
	format_link='<a href="%s">%s</a>\n'
	format_h1='<h1>%s</h1>\n'
	format_h2='<h2>%s</h2>\n'
	format_h3='<h3>%s</h3>\n'
	opener_verbatim='<pre><code>'
	closer_verbatim='</code></pre>\n'
	format_verbatim='%s\n'
	opener_paragraph='<p>'
	closer_paragraph='</p>\n'
	format_paragraph='%s\n'
	opener_quote='<blockquote>'
	closer_quote='</blockquote>\n'
	format_quote='%s\n'
	opener_list='<ul>\n'
	closer_list='</ul>\n'
	format_list='<li>%s</li>'
	opener_linklist='<ul class="linklist">'
	closer_linklist='</ul>'
	format_linklist="$(printf "$format_list" "$format_link")"
}

main() {
	html
	process "$@"
}

main "$@"