Summary Files Commits Branches @commit @diff @stats
path: root / awk-edits / MEL-parser.awk
blob: ebd68bdced55f2df2b31f2726a2cf47a520365d5 (plain) (blame)
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
# .*(slides|teaching)/.*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 {
	newStack("mel")
	MELSINGLE = "s"
	MELOPEN   = "o"
	MELCLOSE  = "c"
}

/<code>/ {
	melInsideCode = 1
}

/<\/code>/ {
	melInsideCode = 0
}

melInsideCode == 0 && /^[ \t]*(<p>)?&#38;/ {
	newLine = ""
	lineCopy = $0
	while (match(lineCopy, /&#38;(((::|[[{(:.])[^[:space:].:[{(<>)}\]&]+)|[\]})])/)) {
		RSTART  = RSTART + 5
		RLENGTH = RLENGTH - 5

		# Inside closing tag
		if (RLENGTH == 1) {
			replaceWith = MEL[topStack("mel"), MELCLOSE]
			popStack("mel")
		}
		# Inside opening tag
		else if (substr(lineCopy, RSTART, 1) ~ /[[{(]/) {
			name = substr(lineCopy, RSTART + 1, RLENGTH - 1)

			replaceWith = MEL[name, MELOPEN]
			pushStack("mel", name)
		}
		# Inside paragraph/one line/insert
		# TODO: currently all work as insert
		else {
			nameStart = 1 + (substr(lineCopy, RSTART + 1, 1) == ":")
			name = substr(lineCopy, RSTART + nameStart, RLENGTH - nameStart)

			replaceWith = MEL[name, MELSINGLE]
		}
		newLine = newLine substr(lineCopy, 0, RSTART - 6) replaceWith
		lineCopy = substr(lineCopy, RSTART + RLENGTH)
	}
	$0 = newLine lineCopy
	if (length(newLine) > 0)
		gsub(/(<p>|<\/p>)/, "")
}