From efa4e784bafeb146dd35ea09f2f481aaedc7e69f Mon Sep 17 00:00:00 2001 From: Syndamia Date: Fri, 23 Feb 2024 21:29:18 +0200 Subject: (awk-edits) Added initial MEL parser --- awk-edits/#stack.awk | 26 ++++++++++++++++ awk-edits/MEL-parser.awk | 78 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 awk-edits/#stack.awk create mode 100644 awk-edits/MEL-parser.awk diff --git a/awk-edits/#stack.awk b/awk-edits/#stack.awk new file mode 100644 index 0000000..a8b0b2a --- /dev/null +++ b/awk-edits/#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/awk-edits/MEL-parser.awk b/awk-edits/MEL-parser.awk new file mode 100644 index 0000000..ebd68bd --- /dev/null +++ b/awk-edits/MEL-parser.awk @@ -0,0 +1,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" +} + +// { + melInsideCode = 1 +} + +/<\/code>/ { + melInsideCode = 0 +} + +melInsideCode == 0 && /^[ \t]*(

)?&/ { + newLine = "" + lineCopy = $0 + while (match(lineCopy, /&(((::|[[{(:.])[^[: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>)/, "") +} -- cgit v1.3.1-23-gd82d