diff options
| Commit | 03a882950ead37f74ab4953dbd1199ddbc3d7f6c (patch) | |
|---|---|---|
| Author | 2025-01-01 15:50:49 +0200 | |
| Committer | 2025-01-01 15:50:49 +0200 | |
| Files | 3d47af86ba6694ae60867d308368b932d8b29596 /md-extensions | |
| csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.tar csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.tar.gz csg-03a882950ead37f74ab4953dbd1199ddbc3d7f6c.zip | ||
| Parent | 7f30e62573396b85eb9558faaf943d76ec4750ab (diff) | |
chore: Rename and reorganize files
2 files changed, 159 insertions, 0 deletions
| -rw-r--r-- | md-extensions/lib_stack.awk | 26 | ||||
| -rw-r--r-- | md-extensions/mel.awk | 133 |
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>)/, "") +} |
