diff options
-rwxr-xr-x | jimmy | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/jimmy b/jimmy new file mode 100755 index 0000000..6e7c244 --- /dev/null +++ b/jimmy | |||
@@ -0,0 +1,151 @@ | |||
1 | #!/bin/sh | ||
2 | { dummy=":" "exec" "awk" "-f" "$0" "$@"; } # -*- awk -*- | ||
3 | |||
4 | #: # h1 | ||
5 | #: ## h2 | ||
6 | #: ### h3 | ||
7 | #: => link | ||
8 | #: * list | ||
9 | #: > quote | ||
10 | #: ``` ... ``` verbatim | ||
11 | |||
12 | BEGIN { # configuration | ||
13 | if (!to) to = "html" # default: html | ||
14 | |||
15 | if (to == "html") { | ||
16 | opener["verbatim"] = "<pre><code>" | ||
17 | closer["verbatim"] = "</code></pre>\n" | ||
18 | linefmt["verbatim"] = "%s\n" | ||
19 | verbatim_esc[1] = "&" | ||
20 | verbatim_repl[1] = "&" | ||
21 | verbatim_esc[2] = "<" | ||
22 | verbatim_repl[2] = "<" | ||
23 | verbatim_esc[3] = ">" | ||
24 | verbatim_repl[3] = ">" | ||
25 | headerfmt[1] = "<h1>%s</h1>\n" | ||
26 | headerfmt[2] = "<h2>%s</h2>\n" | ||
27 | headerfmt[3] = "<h3>%s</h3>\n" | ||
28 | linkfmt = "<a href=\"%s\">%s</a>\n" | ||
29 | link_block = 0 | ||
30 | opener["quote"] = "<blockquote>" | ||
31 | closer["quote"] = "</blockquote>\n" | ||
32 | linefmt["quote"] = "%s\n" | ||
33 | opener["paragraph"] = "<p>" | ||
34 | closer["paragraph"] = "</p>\n" | ||
35 | linefmt["paragraph"] = "%s\n" | ||
36 | paragraph_collapse = 0 # turn \n to ' ' in paragraphs | ||
37 | # consider: paragraph_fold-- <w>, 0 (do nothing), -1 (collapse) | ||
38 | collapse_blanks = 1 | ||
39 | opener["list"] = "<ul>\n" | ||
40 | closer["list"] = "</ul>\n" | ||
41 | linefmt["list"] = "<li>%s</li>\n" | ||
42 | opener["linklist"] = "<ul class=\"linklist\">\n" | ||
43 | closer["linklist"] = "</ul>\n" | ||
44 | linefmt["linklist"] = "<li><a href=\"%s\">%s</a></li>\n" | ||
45 | } else if (to == "gemini") { | ||
46 | opener["verbatim"] = "```\n" | ||
47 | closer["verbatim"] = "```" | ||
48 | linefmt["verbatim"] = "%s\n" | ||
49 | headerfmt[1] = "# %s\n" | ||
50 | headerfmt[2] = "## %s\n" | ||
51 | headerfmt[3] = "### %s\n" | ||
52 | linkfmt = "=> %s %s\n" | ||
53 | link_block = 1 | ||
54 | opener["quote"] = "" | ||
55 | closer["quote"] = "" | ||
56 | linefmt["quote"] = "> %s\n" | ||
57 | opener["paragraph"] = "" | ||
58 | closer["paragraph"] = "" | ||
59 | linefmt["paragraph"] = "%s\n" | ||
60 | paragraph_collapse = 1 # turn \n to ' ' in paragraphs | ||
61 | # consider: paragraph_fold-- <w>, 0 (do nothing), -1 (collapse) | ||
62 | collapse_blanks = 0 | ||
63 | opener["list"] = "\n" | ||
64 | closer["list"] = "" | ||
65 | linefmt["list"] = "* %s\n" | ||
66 | opener["linklist"] = "\n" | ||
67 | closer["linklist"] = "" | ||
68 | linefmt["linklist"] = "=> %s %s\n" | ||
69 | } else die("Unknown `to' type: `" to "'") | ||
70 | } | ||
71 | |||
72 | /^```/ { | ||
73 | bl = BLOCK | ||
74 | close_block() | ||
75 | if (bl != "verbatim") BLOCK = "verbatim" | ||
76 | bl = "" | ||
77 | next | ||
78 | } | ||
79 | |||
80 | BLOCK == "verbatim" { | ||
81 | for (s in verbatim_esc) gsub(verbatim_esc[s], verbatim_repl[s]) | ||
82 | bufpush($0 "\n") | ||
83 | next | ||
84 | } | ||
85 | |||
86 | /^#/ { | ||
87 | close_block() | ||
88 | match($0, /^#+/) | ||
89 | bufpush(sprintf(headerfmt[RLENGTH], collect(2))) | ||
90 | BLOCK = "header" | ||
91 | next | ||
92 | } | ||
93 | |||
94 | /^=>/ { | ||
95 | if (BLOCK == "paragraph" && !link_block) | ||
96 | bufpush(sprintf(linkfmt, $2, collect(3))) | ||
97 | if (BLOCK != "linklist") close_block() | ||
98 | BLOCK = "linklist" | ||
99 | bufpush(sprintf(linefmt[BLOCK], $2, collect(3))) | ||
100 | next | ||
101 | } | ||
102 | |||
103 | /^\*/ { | ||
104 | if (BLOCK != "list") close_block() | ||
105 | BLOCK = "list" | ||
106 | bufpush(sprintf(linefmt[BLOCK], collect(2))) | ||
107 | next | ||
108 | } | ||
109 | |||
110 | /^>/ { | ||
111 | if (BLOCK != "quote") close_block() | ||
112 | BLOCK = "quote" | ||
113 | bufpush(sprintf(linefmt[BLOCK], collect(2))) | ||
114 | next | ||
115 | } | ||
116 | |||
117 | /^$/ { | ||
118 | if (BLOCK == "verbatim") bufpush("\n") | ||
119 | else close_block() | ||
120 | next | ||
121 | } | ||
122 | |||
123 | { | ||
124 | if (BLOCK != "paragraph") close_block() | ||
125 | BLOCK = "paragraph" | ||
126 | bufpush(sprintf(linefmt[BLOCK], $0)) | ||
127 | next | ||
128 | } | ||
129 | |||
130 | END { close_block(); printf "\n" } | ||
131 | |||
132 | function close_block () { | ||
133 | if (!BLOCK) { | ||
134 | if (collapse_blanks) return | ||
135 | else printf "\n" | ||
136 | } | ||
137 | if (BLOCK == "paragraph" && paragraph_collapse) | ||
138 | gsub(/\n/, " ", BUFFER) | ||
139 | printf("%s%s%s", opener[BLOCK], BUFFER, closer[BLOCK]) | ||
140 | BUFFER = BLOCK = "" | ||
141 | } | ||
142 | |||
143 | function collect (begin, end, out) { | ||
144 | for (f = (begin?begin:1); f <= (end?end:NF); f++) | ||
145 | out = out (out?" ":"") $f | ||
146 | return out | ||
147 | } | ||
148 | |||
149 | function bufpush (str) { | ||
150 | BUFFER = BUFFER str | ||
151 | } | ||