diff options
1 files changed, 134 insertions, 0 deletions
| -rw-r--r-- | awk-edits/MEL-parser.awk | 134 |
diff --git a/awk-edits/MEL-parser.awk b/awk-edits/MEL-parser.awk new file mode 100644 index 0000000..f0a8f84 --- /dev/null +++ b/awk-edits/MEL-parser.awk @@ -0,0 +1,134 @@ +# .*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" +} + +/<code>/ { + melInsideCode = 1 +} + +/<\/code>/ { + melInsideCode = 0 +} + +melInsideCode == 0 && /^[ \t]*(<p>|<dt>)?&[{[()\]}:.]/ { + newLine = "" + lineCopy = $0 + paragraphed = 0 + append = "" + while (match(lineCopy, /&(((::|[[{(:.])[^[:space:].:;[{(<>)}\]&]+)|[\]})])/)) { + RSTART += 5 + RLENGTH -= 5 + + # 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 == "" && append == "") + printErr("Unknown single line tag \"" name "\"") + else if (replaceWith == "") + printErr("Missing beginning for line tag \"" name "\"") + else + printErr("Missing ending for 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>)/, "") +} |