Summary Files Commits Branches @commit @diff @stats
path: root / md-extensions
diff options
context:
space:
mode:
Commit03a882950ead37f74ab4953dbd1199ddbc3d7f6c (patch)
Author
 Syndamia <kamen@syndamia.com>
2025-01-01 15:50:49 +0200
Committer
 Syndamia <kamen@syndamia.com>
2025-01-01 15:50:49 +0200
Files3d47af86ba6694ae60867d308368b932d8b29596 /md-extensions
csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.tar
csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.tar.gz
csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.zip
Parent7f30e62573396b85eb9558faaf943d76ec4750ab (diff)
chore: Rename and reorganize files
2 files changed, 159 insertions, 0 deletions
-rw-r--r--md-extensions/lib_stack.awk26
-rw-r--r--md-extensions/mel.awk133
diff --git a/md-extensions/lib_stack.awk b/md-extensions/lib_stack.awk
new file mode 100644
index 0000000..a8b0b2a
--- /dev/null
+++ b/md-extensions/lib_stack.awk
@@ -0,0 +1,26 @@
+function newStack(name) {
+ __stacks[name, "length"] = 0
+}
+
+function topStack(name) {
+ return __stacks[name, __stacks[name, "length"] - 1]
+}
+
+function lengthStack(name) {
+ return __stacks[name, "length"]
+}
+
+function pushStack(name, value) {
+ __stacks[name, __stacks[name, "length"]++] = value
+}
+
+function popStack(name, value) {
+ delete __stacks[name, --__stacks[name, "length"]]
+}
+
+function deleteStack(name) {
+ for (i = 0; i < __stacks[name, "length"]; i++) {
+ delete __stacks[name, i]
+ }
+ delete __stacks[name, "length"]
+}
diff --git a/md-extensions/mel.awk b/md-extensions/mel.awk
new file mode 100644
index 0000000..3359cf9
--- /dev/null
+++ b/md-extensions/mel.awk
@@ -0,0 +1,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>)/, "")
+}