# .*(blog|slides|teaching|tutorials|misc)/.*/.*html # # == About == # # This script wraps certain code block patterns in spans, enabling code syntax highlighting. # The styling classes are defined in the bottom of styles.css # You'll need to specify the language in markdown, like this # # ```cpp # code here # ``` # # where cpp should be your language of choice. BEGIN { # This variable specifies what language is currently being highlighted. # 0 is none, and >0 is the index/id of the language. syntaxhighlighting=0; } function hi(pat, class) { gsub(pat, "&"); } function hie(pat, epat, class) { return gesub(pat, epat, "&"); } function hil(lbpat, pat, lrpat, class) { return glsub(lbpat, pat, lrpat, "&"); } function hib(lbrace, rbrace, class) { return gbsub(lbrace, rbrace, "&"); } # # -- Global -- # syntaxhighlighting > 0 || /class="language-/ { $0 = gesub(@/=/, "<[^>]*>", "\\="); } # # -- Grammars -- # # Code in the form # name -> expression | expression | ... # # Supports "grammar" and "grammar+", the difference being that the first resets # what grammer names have been found in predvious grammar code blocks, # while the second doesn't. # The idea is that you could want to define a grammar in one code block, # do some explanations and then continue the definition with other rules. # syntaxhighlighting == 0 && /class="language-grammar"/ { grammarNamesI = 0; syntaxhighlighting = 1; } syntaxhighlighting == 0 && /class="language-grammar\+"/ { syntaxhighlighting = 1; } syntaxhighlighting == 1 { # Extract the name of the current grammar in the array grammarNames # Since a grammar name could appear in multiple different rule expressions grammarDef = match($0, /[[:alnum:]]+[[:blank:]]*->/); grammarNames[++grammarNamesI] = substr($0, grammarDef, match($0, /[[:blank:]]+->[[:blank:]]+/) - grammarDef); # If we couldn't find a name in the current line, or the rule name already exists, # make sure not to "add" it. grammarNamesI acts as an array size, so decrementing it # effectively "removes" the current string. if (grammarDef == 0 || grammarNames[grammarNamesI] == "") grammarNamesI--; else { for (i = 1; i < grammarNamesI; i++) { if (grammarNames[i] == grammarNames[grammarNamesI]) { grammarNamesI--; break; } } } for (i = 1; i <= grammarNamesI; i++) { $0 = hie(grammarNames[i], @/]*>[^<]*<\/[^>]*>/, "function"); } hi(@/->/, "statement"); hi(@/\|/, "statement"); } # # -- Regexes -- # # Supports "regex" syntaxhighlighting == 0 && /class="language-regex"/ { syntaxhighlighting = 2; } syntaxhighlighting == 2 { syntaxhighlighting = 2; hi(@/\*/, "repeat"); hi(@/[\(\)\|]/, "statement"); } # # -- Bash # # Supports "bash" /class="language-bash"/ { syntaxhighlighting = 3; # The first code block line could look something like #
class="langage-bash"
	# So, if we want to do something with the word class or strings,
	# we'll need to skip the tags from the beginning.
	tagend = match($0, /class="language-bash"/) + 21;
	prestart = substr($0, 0, tagend);
	$0 = substr($0, tagend + 1);
}

syntaxhighlighting == 3 {
	$0 = hie(@/"[^"]*"/, "<[^>]*>", "string");
	$0 = hil(@/(^|[^>&])/,
	         @/#.*$/,
	         "",
	         "comment");
	$0 = hib("\\$\\{", "\\}", "structure");
	$0 = hib("\\$\\(\\(", "\\)\\)", "structure");
	$0 = hib("\\$\\(", "\\)", "structure");
	hi(@/\$[[:alnum:]]+/, "structure");
	$0 = hil(@/[^[:alnum:]#\$]/,
	         @/[[:digit:]]+/,
	         @/([^[:alnum:]]|$)/,
	         "number");
	$0 = hil(@/[[:blank:]]+/, @/-[-_[:alnum:]]+/, "", "operator");
	$0 = hil(@/(^|[^[:alnum:]])/,
	         @/(if|fi|then|case|esac|==|!=|-eq|-ne|-gt|-ge|-lt|-le|;;|;|\|\||&&)/,
	         @/([^[:alnum:]]|$)/,
	         "conditional");
	$0 = hil(@/(^|[^[:alnum:]])/,
	         @/(for|while|until|in|do|done)/,
	         @/([^[:alnum:]]|$)/,
	         "repeat");
	$0 = hil(@/(^|[[:blank:]]+)/,
	         @/[[:alnum:]]+/,
	         @/(|\+|-)=/,
	         "identifier");
	$0 = hil("",
	         @/[-_[:alnum:]]+[[:blank:]]*/,
	         @/\([^\)]*\)/,
	         "function");
	hi(@/^[[:blank:]]*[-_[:alnum:]]+/, "statement");
}


#
# -- C-like programming languages --
#

#
# -- C++ --
#
# Supports "cpp"

/class="language-cpp"/ {
	syntaxhighlighting = 101;
}

syntaxhighlighting == 101 {
	$0 = hil(@/(^|[^[:alnum:]])/,
	         @/(string)/,
	         @/([^[:alnum:]]|$)/,
	         "type");
}

#
# -- C# --
#
# Supports "csharp"

/class="language-csharp"/ {
	syntaxhighlighting = 102;
}

syntaxhighlighting == 102 {
	$0 = hil(@/(^|[^[:alnum:]])/,
	         @/(new|public|protected|private|override)/,
	         @/([^[:alnum:]]|$)/,
	         "keyword");
	hi(@/<[-_[:alpha:]]+>/, "typedef");
	$0 = hie(@/[_[:upper:]][_[:upper:]][_[:upper:]][_[:upper:]]+/, @/<[^>]*>/, "const");
}

#
# -- lex --
#
# Supports "lex"

/class="language-lex"/ {
	syntaxhighlighting = 103;
}

syntaxhighlighting == 103 {
	hi(@/%[^[:blank:]]+/, "storageclass");
}

#
# -- yacc --
#
# Supports "yacc"

/class="language-yacc"/ {
	syntaxhighlighting = 104;
}

syntaxhighlighting == 104 {
	hi(@/%[^[:blank:]]+/, "storageclass");
}

#
# -- C --
#
# Supports "c" and is used in C-like programming languages

/class="language-c"/ {
	syntaxhighlighting = 100;
}

syntaxhighlighting >= 100 {
	$0 = hie(@/"[^"]*"/, "<[^>]*>", "string");
	hi(@/(//.*$|/\*.*$|^[^\*]*\*/)/, "comment");
	$0 = hil(@/[^[:alnum:]#\$]/,
	         @/[[:digit:]]+/,
	         @/[^[:alnum:]]/,
	         "number");
	$0 = hil(@/[^[:alnum:]#\$]/,
	         @/[[:digit:]]+\.[[:digit:]]+/,
	         @/[^[:alnum:]]/,
	         "float");
	$0 = hil("",
	         @/[-_[:alnum:]]+/,
	         @/[[:blank:]]*(|\+|-|\*|/|%|<<|>>|&|\^|\|)=/,
	         "identifier");
	$0 = hil("",
	         @/[-_[:alnum:]]+[[:blank:]]*/,
	         @/\(/,
	         "function");
	hi(@/(==|!=|<=|>=|&&|\|\||!)/, "conditional");
	$0 = hil(@/(^|[^-[:alnum:]])/,
	         @/(break|continue|do|for|goto|while)/,
	         @/([^[:alnum:]]|$)/,
	         "repeat");
	$0 = hil(@/(^|[^-[:alnum:]])/,
	         @/(case|const|default|else|extern|if|return|sizeof|switch|typedef)/,
	         @/([^[:alnum:]]|$)/,
	         "keyword");
	$0 = hil(@/(^|<.*>)[[:blank:]]*/,
	         @/#[[:alpha:]]+/,
	         "",
	         "preproc");
	$0 = hil(@/(^|[^-[:alnum:]])/,
	         @/(auto|char|double|float|int|long|short|signed|unsigned|bool|void)/,
	         @/([^[:alnum:]]|$)/,
	         "type");
	hi(@/'[\\]?[ -~]'/, "char");
	hi(@/(true|false)/, "bool");
	$0 = hil(@/(^|[^[:alnum:]])/,
	         @/(enum|struct|union)/,
	         @/([^[:alnum:]]|$)/,
	         "storageclass");
}

tagend != 0 {
	$0 = prestart $0;
	tagend = 0;
}

syntaxhighlighting > 0 && /<\/code>/ {
	syntaxhighlighting = 0;
}