History

Initial commit

yiyus committed 17 years ago

Commit 21e56b0No parent (first commit)1 file · +176 −0Browse files

Unified · Split

md2html.awk+176−0
@@ -0,0 +1,176 @@
1+#!/bin/awk -f
2+
3+# md2html.awk
4+# by: Jesus Galan (yiyus) <yiyu.jgl@gmail>, May 2009
5+# Usage:
6+# md2html file.md > file.html
7+# Options: -v esc=false to not escape html
8+
9+function newblock(nblock){
10+ if(text)
11+ print "<" block ">" text "</" block ">";
12+ text = "";
13+ block = nblock ? nblock : "p";
14+}
15+
16+function subinline(tgl, inl){
17+ while(match($0, tgl)){
18+ if (inline[ni] == inl)
19+ ni -= sub(tgl, "</" inl ">");
20+ else if (sub(tgl, "<" inl ">"))
21+ inline[++ni] = inl;
22+ }
23+}
24+
25+function dolink(href, lnk){
26+ # Undo escaped html in uris
27+ gsub(/&amp;/, "\\&", href);
28+ gsub(/&lt;/, "<", href);
29+ gsub(/&gt;/, ">", href);
30+ # & can be tricky, and not standard:
31+ gsub(/&/, "\\\\\\&", href);
32+ gsub(/&/, "\\\\\\&", lnk);
33+ return "<a href=\"" href "\">" lnk "</a>";
34+}
35+
36+BEGIN {
37+ ni = 0; # inlines
38+ nl = 0; # nested lists
39+ text = "";
40+ block = "p";
41+}
42+
43+# Escape html
44+esc != "false" {
45+ gsub("&", "\\&amp;")
46+ gsub("<", "\\&lt;")
47+ gsub(">", "\\&gt;")
48+}
49+
50+# Horizontal rules (_ is not in markdown)
51+/^[ ]*([-*_] ?)+[ ]*$/ && text == "" {
52+ print "<hr>";
53+ next;
54+}
55+
56+# Tables (not in markdown)
57+# Syntax:
58+# Right Align| Center Align |Left Align
59+/([ ]\|)|(\|[ ])/ {
60+ if(block != "table")
61+ newblock("table");
62+ nc = split($0, cells, "|");
63+ $0 = "<tr>\n";
64+ for(i = 1; i <= nc; i++){
65+ align = "left";
66+ if(sub(/^[ ]+/, "", cells[i])){
67+ if(sub(/[ ]+$/, "", cells[i]))
68+ align = "center";
69+ else
70+ align = "right";
71+ }
72+ sub(/[ ]+$/,"", cells[i]);
73+ $0 = $0 "<td align=\"" align "\">" cells[i] "</td>\n";
74+ }
75+ $0 = $0 "</tr>";
76+}
77+
78+# Ordered and unordered (possibly nested) lists
79+/^[ ]*([*+-]|(([0-9]+[\.-]?)+))[ ]/ {
80+ newblock("li");
81+ nnl = 1;
82+ while(match($0, /^[ ]/)){
83+ sub(/^[ ]/,"");
84+ nnl++;
85+ }
86+ while(nl > nnl)
87+ print "</" list[nl--] ">";
88+ while(nl < nnl){
89+ list[++nl] = "ol";
90+ if(match($0, /^[*+-]/))
91+ list[nl] = "ul";
92+ print "<" list[nl] ">";
93+ }
94+ sub(/^([*+-]|(([0-9]+[\.-]?)+))[ ]/,"");
95+}
96+
97+# Multi line list items
98+block == "li" {
99+ sub(/^( *)|( *)/,"");
100+}
101+
102+# Code blocks
103+/^( | )/ {
104+ if(block != "pre")
105+ newblock("pre");
106+ sub(/^( | )/, "");
107+ text = text $0 "\n";
108+ next;
109+}
110+
111+# Paragraph
112+/^$/ {
113+ newblock();
114+ while(nl > 0)
115+ print "</" list[nl--] ">";
116+}
117+
118+# Setex-style Headers
119+# (Plus h3 with underscores.)
120+/^=+$/ {
121+ block = "h" 1;
122+ next;
123+}
124+
125+/^-+$/ {
126+ block = "h" 2;
127+ next;
128+}
129+
130+/^_+$/ {
131+ block = "h" 3;
132+ next;
133+}
134+
135+# Atx-style headers
136+/^#/ {
137+ newblock();
138+ match($0, /#+/);
139+ n = RLENGTH;
140+ if(n > 6)
141+ n = 6;
142+ text = substr($0, RLENGTH + 1);
143+ block = "h" n;
144+ next;
145+}
146+
147+// {
148+ # Images
149+ while(match($0, /!\[[^\]]+\]\([^\)]+\)/)){
150+ split(substr($0, RSTART + 2, RLENGTH - 3), a, /\]\(/);
151+ sub(/!\[[^\]]+\]\([^\)]+\)/, "<img src=\"" a[2] "\" alt=\"" a[1] "\">");
152+ }
153+ # Links
154+ while(match($0, /\[[^\]]+\]\([^\)]+\)/)){
155+ split(substr($0, RSTART + 1, RLENGTH - 2), a, /\]\(/);
156+ sub(/\[[^\]]+\]\([^\)]+\)/, dolink(a[2], a[1]));
157+ }
158+ # Auto links (uri matching is poor)
159+ na = split($0, a, /(^\()|[ ]|([,\.\)]([ ]|$))/);
160+ for(i = 1; i <= na; i++)
161+ if(match(a[i], /^(((https?|ftp|file|news|irc):\/\/)|(mailto:)).+$/))
162+ sub(a[i], dolink(a[i], a[i]));
163+ # Inline
164+ subinline("(\\*\\*)|(__)", "strong");
165+ subinline("\\*", "em");
166+ subinline("`", "code");
167+ text = text (text ? " " : "") $0;
168+}
169+
170+END {
171+ while(ni > 0)
172+ text = text "</" inline[ni--] ">";
173+ newblock();
174+ while(nl > 0)
175+ print "</" list[nl--] ">";
176+}