Skip to content

Instantly share code, notes, and snippets.

@OnkelTem
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OnkelTem/21753cf82d8868f0c33e to your computer and use it in GitHub Desktop.
Save OnkelTem/21753cf82d8868f0c33e to your computer and use it in GitHub Desktop.
BEGIN {
FS="[[:blank:]]*"
OFS = " "
CSYM = csym
PAD = " "
if (CSYM == "") CSYM = "#"
s_starts_len = 0
}
# Reset section when new file is read
FNR == 1 {
s = ""
delete s_starts
}
# Skip comments and blank lines
$0 ~ "^[[:blank:]]*(" CSYM "|$)" { next }
# Trim line
/^[[:blank:]]*/ { $0 = trim($0) }
# End current section
$0 ~ "^[[:blank:]]*</" {
delete s_starts[s_starts_len--]
s = join(":", s_starts)
next
}
# Section start
$0 ~ "^[[:blank:]]*<" {
if (s != "")
s = s ":" trim($0)
else
s = trim($0)
s_starts[++s_starts_len] = $0
next
}
# Collect data from the first file
NR == FNR {
key = $1
$1 = ""
v[s, key] = $0
s_lines[s, key] = FNR
next
}
# Override data with values from the second file
{
key = $1
$1 = ""
v[s, key] = $0
d_lines[s, key] = FNR
next
}
# Build the output
END {
ns = ""
#sects_old_len = 0;
depth = 0
split("", sects)
split("", sects_old)
PROCINFO["sorted_in"] = "cnf_sort"
for (k in v) {
#print k ":" v[k]
split(k, k_a, SUBSEP)
split(k_a[1], sects, ":")
if (ns != k_a[1]) {
# closing tags
num = calc_diff(sects_old, sects)
max = length(sects_old)
for (i = 0; i < num; i++)
print str_repeat(PAD, max - i - 1) end(sects_old[max - i])
# opening tags
num = calc_diff(sects, sects_old)
max = length(sects)
for (i = 0; i < num; i++)
print "\n" str_repeat(PAD, max - i - 1) sects[max - num + i + 1]
ns = k_a[1]
for (i = 1; i <= length(sects); i++)
sects_old[i] = sects[i]
for (i = length(sects) + 1; i <= length(sects_old); i++)
delete sects_old[i]
}
print_line(str_repeat(PAD, length(sects)) k_a[2], v[k])
}
num = length(sects)
max = length(sects)
for (i = 0; i < num; i++)
print str_repeat(PAD, max - i - 1) end(sects_old[max - i])
print ""
}
# Sort array by sections and then by original lines order if possible
function cnf_sort(i1, v1, i2, v2) {
split(i1, i1_a, SUBSEP)
split(i2, i2_a, SUBSEP)
if (i1_a[1] < i2_a[1])
return -1
if (i1_a[1] == i2_a[1])
if (i1 in s_lines && i2 in s_lines)
return (s_lines[i1] - s_lines[i2])
else if (i1 in d_lines && i2 in d_lines)
return (d_lines[i1] - d_lines[i2])
else if (i1 in sl)
return -1
else
return 1
else
return 1
}
function calc_diff(ar1, ar2) {
#print print_r(ar1)
#print print_r(ar2)
res = 0
for(i = 1; i <= length(ar1); i++) {
if (ar1[i] != ar2[i]) {
#print "BREAK" length(ar1)
break;
}
res++
}
res = length(ar1) - res
#print "result is " res
return res
}
# Output line
function print_line(key, value) {
if (value != "")
print key, value
else
print key
}
function str_repeat(str, n, rep, i ) {
for(i = 1; i <= n; i++)
rep = rep str
return rep
}
function trim(str) {
gsub(/^[[:blank:]]*/, "", str)
gsub(/[[:blank:]]*$/, "", str)
return str
}
function print_r(ar) {
out = "[\n"
for (x in ar) {
out = out x " => " ar[x] "," "\n"
}
out = out "]"
return out
}
function join(sep, ar) {
i = 1
out = ""
for (x in ar) {
out = out ar[x]
if (i < length(ar))
out = out sep
i = i + 1
}
#print "JOINING ARRAY: " out
return out
}
function end(sect) {
return gensub(/^<([^[:blank:]]*)[[:blank:]].*/, "</\\1>", "g", sect)
}
@OnkelTem
Copy link
Author

OnkelTem commented Oct 5, 2014

Moved FNR == 1 to the top and replaced empty array stuff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment