Summary Files Commits Branches @commit @diff @stats
path: root / awk-edits / MEL--Parser.awk
blob: 248eff2968b9e0366ec297d8e3d874471572633d (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# .*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"
	MELINSERT    = "i"
	MELPARAGRAPH = "p"
	MELLINE      = "l"
}

/<code>/ {
	melInsideCode = 1
}

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

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

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

			replaceWith = MEL[name, MELINSERT]
		}
		# Inside one line TODO
		else if (substr(lineCopy, RSTART, 2) == "::") {
			name = substr(lineCopy, RSTART + 2, RLENGTH - 2)

			# RLENGTH = length(lineCopy)
			replaceWith = MEL[name, MELLINE]
		}
		# Inside paragraph
		else if (substr(lineCopy, RSTART, 1) == ":") {
			name = substr(lineCopy, RSTART + 1, RLENGTH - 1)

			replaceWith = " " MEL[name, MELPARAGRAPH]
			RSTART  -= 1
			RLENGTH += 1
			paragraphed = 1
		}
		# Inside opening tag
		else {
			name = substr(lineCopy, RSTART + 1, RLENGTH - 1)

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