diff options
author | Case Duckworth | 2022-06-15 09:53:23 -0500 |
---|---|---|
committer | Case Duckworth | 2022-06-15 09:53:23 -0500 |
commit | 155d920801d1881525ceae872430346b27772e57 (patch) | |
tree | 4840465ff579780d1a66e36713482c6113794239 | |
download | ht-155d920801d1881525ceae872430346b27772e57.tar.gz ht-155d920801d1881525ceae872430346b27772e57.zip |
First commit
-rwxr-xr-x | ht.awk | 246 | ||||
-rw-r--r-- | test.ht | 27 | ||||
-rw-r--r-- | test.txt | 24 |
3 files changed, 297 insertions, 0 deletions
diff --git a/ht.awk b/ht.awk new file mode 100755 index 0000000..60e042b --- /dev/null +++ b/ht.awk | |||
@@ -0,0 +1,246 @@ | |||
1 | #!/usr/bin/awk -f | ||
2 | # -*- indent-tabs-mode: t; -*- | ||
3 | # HAT TRICK | ||
4 | # (C) 2022 C. Duckworth | ||
5 | |||
6 | ### Commentary: | ||
7 | |||
8 | # OLDIFS=$IFS; IFS=$'\n'; | ||
9 | # for line in `cat testfile`; do | ||
10 | # test=`echo "$line" | grep -E '[\]$'`; | ||
11 | # if [ $test ]; then | ||
12 | # newline=`echo $line | rev | cut -c 2- | rev`; | ||
13 | # echo -n "$newline"; else echo "$line"; | ||
14 | # fi; done; | ||
15 | # IFS=$OLDIFS | ||
16 | |||
17 | ### Code: | ||
18 | BEGIN { | ||
19 | width = 72 | ||
20 | default_htag = "p" | ||
21 | default_gtag = "" | ||
22 | default_ftag = "" | ||
23 | } | ||
24 | |||
25 | ### Raw formatting | ||
26 | /^>>>/ { | ||
27 | getline first_raw | ||
28 | if (raw_fmt_p("html")) { | ||
29 | raw_html = 1 | ||
30 | html[++hpar] = "<pre><code>" html_escape(first_raw) | ||
31 | } | ||
32 | if (raw_fmt_p("gemini")) { | ||
33 | raw_gemini = 1 | ||
34 | gemini[++gpar] = "```" | ||
35 | gemini[++gpar] = first_raw | ||
36 | } | ||
37 | if (raw_fmt_p("gopher")) { | ||
38 | raw_gopher = 1 | ||
39 | gopher[++fpar] = first_raw | ||
40 | } | ||
41 | raw = 1 | ||
42 | next | ||
43 | } | ||
44 | |||
45 | /^<<</ { | ||
46 | if (raw_html) { | ||
47 | html[hpar] = html[hpar] "</code></pre>" | ||
48 | } | ||
49 | if (raw_gemini) { | ||
50 | gemini[++gpar] = "```" | ||
51 | gemini[++gpar] = "" | ||
52 | } | ||
53 | if (raw_gopher) { | ||
54 | gopher[++fpar] = "" | ||
55 | } | ||
56 | raw_html = 0 | ||
57 | raw_gemini = 0 | ||
58 | raw_gopher = 0 | ||
59 | raw = 0 | ||
60 | next | ||
61 | } | ||
62 | |||
63 | raw { | ||
64 | if (raw_html) { | ||
65 | html_empty = 0 | ||
66 | html[++hpar] = html_escape($0) | ||
67 | } | ||
68 | if (raw_gemini) { | ||
69 | gemini_empty = 0 | ||
70 | gemini[++gpar] = $0 | ||
71 | } | ||
72 | if (raw_gopher) { | ||
73 | gopher_empty = 0 | ||
74 | gopher[++fpar] = $0 | ||
75 | } | ||
76 | next | ||
77 | } | ||
78 | |||
79 | # Block types | ||
80 | /^#/ { | ||
81 | match($0, /#+/) | ||
82 | htag = "h" (RLENGTH > 6 ? 6 : RLENGTH) | ||
83 | gtag = substr($0, RSTART, (RLENGTH > 3 ? 3 : RLENGTH)) " " | ||
84 | ftag = substr($0, RSTART, RLENGTH) " " | ||
85 | sub(/^#+[ \t]*/, "", $0) | ||
86 | } | ||
87 | |||
88 | # Line types | ||
89 | /^=>/ { | ||
90 | title = "" | ||
91 | for (i = 3; i <= NF; i++) { | ||
92 | title = title (title ? " " : "") $i | ||
93 | } | ||
94 | hbuf[++hline] = "<a href=\"" $2 "\">" title "</a>" | ||
95 | gbuf[++gline] = "\ngemini\t" $0 | ||
96 | # TODO: gopher | ||
97 | next | ||
98 | } | ||
99 | |||
100 | ### Everything else | ||
101 | /./ { | ||
102 | html_empty = 0 | ||
103 | gemini_empty = 0 | ||
104 | gopher_empty = 0 | ||
105 | hbuf[++hline] = $0 | ||
106 | gbuf[++gline] = $0 | ||
107 | fbuf[++fline] = $0 | ||
108 | } | ||
109 | |||
110 | /^$/ { | ||
111 | bufput() | ||
112 | } | ||
113 | |||
114 | END { | ||
115 | bufput() | ||
116 | printarr(html, "html") | ||
117 | printarr(gemini, "gemini") | ||
118 | printarr(gopher, "gopher") | ||
119 | } | ||
120 | |||
121 | |||
122 | function bufput() | ||
123 | { | ||
124 | hbufput() | ||
125 | gbufput() | ||
126 | fbufput() | ||
127 | } | ||
128 | |||
129 | function clear(arr) | ||
130 | { | ||
131 | for (x in arr) { | ||
132 | delete arr[x] | ||
133 | } | ||
134 | } | ||
135 | |||
136 | function fbufput() | ||
137 | { | ||
138 | if (! length(fbuf)) { | ||
139 | next | ||
140 | } | ||
141 | for (ln in fbuf) { # XXX: gopher line types | ||
142 | paragraph = paragraph (paragraph ? " " : "") fbuf[ln] | ||
143 | } | ||
144 | fill(paragraph) | ||
145 | for (ln in fp) { | ||
146 | gopher[++fpar] = ((ln == 1) ? ftag : "") fp[ln] | ||
147 | } | ||
148 | gopher[++fpar] = "" | ||
149 | paragraph = "" | ||
150 | ftag = default_ftag | ||
151 | clear(fp) | ||
152 | clear(fbuf) | ||
153 | } | ||
154 | |||
155 | function fill(paragraph) | ||
156 | { | ||
157 | char = 0 | ||
158 | ln = 1 | ||
159 | split(paragraph, words, FS) | ||
160 | for (word in words) { | ||
161 | char += length(words[word]) | ||
162 | if (char <= width) { | ||
163 | fp[ln] = fp[ln] (fp[ln] ? " " : "") words[word] | ||
164 | } else { | ||
165 | fp[++ln] = words[word] | ||
166 | char = length(words[word]) | ||
167 | } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | function gbufput() | ||
172 | { | ||
173 | if (! length(gbuf)) { | ||
174 | next | ||
175 | } | ||
176 | for (ln in gbuf) { | ||
177 | paragraph = paragraph (paragraph ? " " : "") gbuf[ln] | ||
178 | } | ||
179 | gemini[++gpar] = gtag paragraph | ||
180 | gemini[++gpar] = "" | ||
181 | gtag = default_gtag | ||
182 | paragraph = "" | ||
183 | clear(gbuf) | ||
184 | } | ||
185 | |||
186 | function gopher_line(type, display, selector, hostname, port) | ||
187 | { | ||
188 | return (type display "\t" selector "\t" hostname "\t" port) | ||
189 | } | ||
190 | |||
191 | function hbufput() | ||
192 | { | ||
193 | if (! length(hbuf)) { | ||
194 | next | ||
195 | } | ||
196 | for (ln in hbuf) { | ||
197 | paragraph = paragraph (paragraph ? " " : "") hbuf[ln] | ||
198 | } | ||
199 | fill(paragraph) | ||
200 | for (ln in fp) { | ||
201 | html[++hpar] = ((ln == 1) ? "<" (htag ? htag : default_htag) ">" : "") fp[ln] | ||
202 | } | ||
203 | html[hpar] = html[hpar] (htag_end ? htag_end : "</" (htag ? htag : default_htag) ">") | ||
204 | paragraph = "" | ||
205 | htag = default_htag | ||
206 | clear(fp) | ||
207 | clear(hbuf) | ||
208 | } | ||
209 | |||
210 | function html_escape(text) | ||
211 | { | ||
212 | gsub(/&/, "\\&", text) | ||
213 | gsub(/</, "\\<", text) | ||
214 | gsub(/>/, "\\>", text) | ||
215 | return text | ||
216 | } | ||
217 | |||
218 | function printarr(arr, prefix) | ||
219 | { | ||
220 | if (prefix) { | ||
221 | fmt = "%s\t%s\n" | ||
222 | } else { | ||
223 | fmt = "%s%s\n" | ||
224 | } | ||
225 | for (x in arr) { | ||
226 | printf fmt, prefix, arr[x] | ||
227 | } | ||
228 | } | ||
229 | |||
230 | function raw_fmt_p(format) | ||
231 | { | ||
232 | if (NF < 2) { | ||
233 | return 1 | ||
234 | } | ||
235 | if ($2 ~ /-/) { | ||
236 | if ($2 ~ ("-" format)) { | ||
237 | return 0 | ||
238 | } else { | ||
239 | return 1 | ||
240 | } | ||
241 | } | ||
242 | if ($2 ~ format) { | ||
243 | return 1 | ||
244 | } | ||
245 | return 0 | ||
246 | } | ||
diff --git a/test.ht b/test.ht new file mode 100644 index 0000000..0208568 --- /dev/null +++ b/test.ht | |||
@@ -0,0 +1,27 @@ | |||
1 | # a test | ||
2 | |||
3 | here's a test for ht.awk. | ||
4 | it's got paragraphs (these bad boys), long lines and such, and also raw blocks. | ||
5 | => https://example.com and links! | ||
6 | |||
7 | >>> | ||
8 | rawblock example1: all of them, & more <hi!> | ||
9 | ## fee fi fo fum | ||
10 | <<< | ||
11 | |||
12 | ## just html | ||
13 | but over two lines | ||
14 | |||
15 | >>> html | ||
16 | rawblock example2: just html | ||
17 | hey adora | ||
18 | <<< | ||
19 | |||
20 | ### not html | ||
21 | |||
22 | >>> -html | ||
23 | rawblock example3: everything /but/ html | ||
24 | # with a header inside, blah | ||
25 | <<< | ||
26 | |||
27 | and finally, the end of the file. | ||
diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..8c47543 --- /dev/null +++ b/test.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | html <p> | ||
2 | html here's a test for ht.awk. it's got paragraphs (these bad boys), long lines and such, | ||
3 | html and also raw blocks. | ||
4 | html </p> | ||
5 | html </code></pre> | ||
6 | html </code></pre> | ||
7 | html <p> | ||
8 | html and finally, the end of the file. | ||
9 | html </p> | ||
10 | gemini here's a test for ht.awk. it's got paragraphs (these bad boys), long lines and such, and also raw blocks. | ||
11 | gemini | ||
12 | gemini ``` | ||
13 | gemini rawblock example1: all of them. | ||
14 | gemini fee fi fo fum | ||
15 | gemini ``` | ||
16 | gemini | ||
17 | gemini and finally, the end of the file. | ||
18 | gemini | ||
19 | gopher here's a test for ht.awk. it's got paragraphs (these bad boys), long lines and such, | ||
20 | gopher and also raw blocks. | ||
21 | gopher | ||
22 | gopher | ||
23 | gopher and finally, the end of the file. | ||
24 | gopher | ||