Last active
March 30, 2021 21:33
-
-
Save Miciah/8a2d5245ba8150a626acb16a16926021 to your computer and use it in GitHub Desktop.
AWK script to indent Go template actions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/awk | |
# This AWK script indents actions in Go templates. The script only modifies | |
# indentation for lines that begin with any amount of indentation followed by | |
# "{{". The script also normalizes blanks within the action, so that "{{if | |
# foo}}" or "{{ if foo }}" becomes "{{ if foo }}". Minus signs (as in "{{- | |
# if foo}}") are skipped over and preserved. Comment-only actions are formatted | |
# as "{{/* comment */}}" or "{{- /* command */ -}}". | |
# | |
# Shortcomings: | |
# | |
# - This script only recognizes a single "if", "with", "else", or "range" | |
# statement per line. | |
# | |
# - This script only recognizes a single "else" or "end" statement per line. | |
# | |
# - The normalization of blanks is rudimentary; if a line mixes "{{"/"}}" | |
# markers and "{{-"/"-}}" markers, the normalization may produce bad results. | |
# | |
# For example, the script indents the following: | |
# | |
# {{if .Foo}} | |
# {{if .Bar}} | |
# {{ .Baz }} | |
# {{end}} | |
# {{end}} | |
# | |
# as the following: | |
# | |
# {{if .Foo}} | |
# {{if .Bar}} | |
# {{ .Baz }} | |
# {{end}} | |
# {{end}} | |
# | |
# However, the script incorrectly indents the following: | |
# | |
# {{if .Foo}}{{if .Bar}} | |
# {{ .Baz }} | |
# {{end}} | |
# {{end}} | |
# | |
# as the following: | |
# | |
# {{if .Foo}}{{if .Bar}} | |
# {{ .Baz }} | |
# {{end}} | |
# {{end}} | |
# | |
# Also, the script incorrectly normalizes the following: | |
# | |
# {{if .Foo}} {{-if .Bar}} | |
# {{ .Baz }} | |
# {{end}} {{-end}} | |
# | |
# as the following: | |
# | |
# {{if .Foo }} {{- if .Bar }} | |
# {{ .Baz }} | |
# {{end }} {{- end }} | |
# Decrease the indentation level if the line has an "end" stanzza. Do this | |
# before printing indentation so that an "end" is indented at the same level as | |
# the matching "if"/"with"/"range" stanza. Similarly, decrease the indentation | |
# level for "else" stanzas (although we increase indentation again after | |
# printing the line with the "else"). | |
/{{[-[:space:]]*(end|else)/ { | |
if (indentation > 0) { | |
indentation-=2 | |
} | |
} | |
# Re-indent based on the current indentation level. | |
/^[[:space:]]*{{/ { | |
spaces = sprintf("%*.*s", indentation, indentation, " "); | |
sub(/^[[:space:]]*/, spaces) | |
} | |
# Normalize blanks within the action delimiters and print the line. | |
{ | |
# Compact blanks after "{{" or "{{-" or before "}}" or "-}}". | |
if ($0 ~ /{{-/) { | |
gsub(/{{-[[:space:]]*/, "{{- ") | |
} else { | |
gsub(/{{[[:space:]]*/, "{{ "); | |
} | |
if ($0 ~ /-}}/) { | |
gsub(/[[:space:]]*-}}/, " -}}"); | |
} else { | |
gsub(/[[:space:]]*}}/, " }}"); | |
} | |
# Delete any space between "{{" and "/*" and between "*/" and "}}". | |
gsub(/{{ \/\*/, "{{/*") | |
gsub(/\*\/ }}/, "*/}}") | |
# Printing with the indentation level is useful when hacking on this script. | |
#print indentation " " $0 | |
} | |
# Increase the indentation level if the line has an "if", "with", or "range" | |
# stanza. Do this after re-indenting the line so that the "if"/"with"/"range" | |
# stanza doesn't increase its own indentation. If the line has an "else" | |
# stanza, increase the indentation, which we decreased so that the line wouldn't | |
# be indented. | |
/{{[-[:space:]]*(if|with|range|else)/ { | |
indentation+=2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment