# .*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]*(

|

)?&[{[()\]}:.]/ { 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>)/, "") }