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
|
# .*html
#
# == About ==
#
# MEL is the "Markdown Extensions Language"
# It's a general metalanguage (I made) for adding custom syntax to Markdown (via awk)
# The idea is it provides parsing for general constructs, and you only need to define
# the names of those constructs and with what they get replaced with
#
# Slightly based on ftags, this system allows you to easily implement the following construts:
# &(name ... &) Multiline "tag", everything inside is formatted by "name"
# &{name ... &} In practice, it just replaces "&[name" and "&]" with the appropriate HTML
# &[name ... &] All three can be used interchangeably, though it's preferrable if
# you use the matching braces and semantically, in your "language"
# square brackets are used for the largest components
# curly for structural components and normal braces for styling
# &:name Format/encapsulate everything until the end of the paragraph
# &::name Format/encapsulate everything until the end of the line
# &.name Insert standalone element as-is
#
# Though it's not decided (or implemented) yet, potentially there will also be:
# &)-( Used to simplify cases of &(name1 ... &) &(name1 ... &) &(name1 ... &)
# &}-{ into &(name1 ... &)-( ... &)-( ... &)
# &]-[ Or maybe for special cases, where rather than doing something like
# &{elementsList &(element1 ... &) &(element2 ... &) &}
# you could simply do
# &{elementsList ... &}-{ ... &}-{ ... &}
# So it will surf as a separator between direct subelements
BEGIN {
usesMEL()
newStack("mel")
}
function usesMEL() {
MELOPEN = "o"
MELCLOSE = "c"
MELLINEOPEN = "lo"
MELLINECLOSE = "lc"
MELINSERT = "i"
MELPARAGRAPH = "p"
MELLINE = "l"
}
function printErr(message, column, columnPointer) {
column = length($0) - length(lineCopy) + RSTART - 5
print "ERROR by MEL-parser.awk: " message " | Found in " FILENAME " at line " FNR " & column " column ":" > "/dev/stderr"
columnPointer = ""
for (i = 1; i < column; i++)
columnPointer = columnPointer " "
for (i = -5; i < RLENGTH; i++)
columnPointer = columnPointer "^"
print $0 "\n" columnPointer "\n" > "/dev/stderr"
}
melInsideCode && /```/ {
melInsideCode = 0
}
/```/ {
melInsideCode = 1
}
melInsideCode == 0 && /^[ \t]*(<p>|<dt>)?&[{[()\]}:.]/ {
newLine = ""
lineCopy = $0
paragraphed = 0
append = ""
while (match(lineCopy, /&(((::|[[{(:.])[^[:space:].:;[{(<>)}\]&]+)|[\]})])/)) {
RSTART += 1
RLENGTH -= 1
# Inside closing tag
if (RLENGTH == 1) {
replaceWith = MEL[topStack("mel"), MELCLOSE]
if (replaceWith == "")
printErr("Missing closing tag for \"" topStack("mel") "\"")
popStack("mel")
}
# Inside insert
else if (substr(lineCopy, RSTART, 1) == ".") {
name = substr(lineCopy, RSTART + 1, RLENGTH - 1)
replaceWith = MEL[name, MELINSERT]
if (replaceWith == "")
printErr("Unknown insertion tag \"" name "\"")
}
# Inside one line
else if (substr(lineCopy, RSTART, 2) == "::") {
name = substr(lineCopy, RSTART + 2, RLENGTH - 2)
replaceWith = MEL[name, MELLINEOPEN]
append = append MEL[name, MELLINECLOSE]
if (replaceWith == "")
printErr("Missing beginning for line tag \"" name "\"")
else if (MEL[name, MELLINECLOSE] == "")
printErr("Missing ending for line tag \"" name "\"")
else if (replaceWith == "" && MEL[name, MELLINECLOSE] == "")
printErr("Unknown single line tag \"" name "\"")
}
# Inside paragraph
else if (substr(lineCopy, RSTART, 1) == ":") {
name = substr(lineCopy, RSTART + 1, RLENGTH - 1)
replaceWith = " " MEL[name, MELPARAGRAPH]
if (replaceWith == " ")
printErr("Unknown paragraph tag \"" name "\"")
RSTART -= 1
RLENGTH += 1
paragraphed = 1
}
# Inside opening tag
else {
name = substr(lineCopy, RSTART + 1, RLENGTH - 1)
replaceWith = MEL[name, MELOPEN]
pushStack("mel", name)
if (replaceWith == "")
printErr("Unknown opening tag \"" name "\"")
}
newLine = newLine substr(lineCopy, 0, RSTART - 6) replaceWith
lineCopy = substr(lineCopy, RSTART + RLENGTH)
}
$0 = newLine lineCopy append
if (paragraphed == 0 && newLine != "")
gsub(/(<p>|<\/p>)/, "")
}
|