# match(text, pattern): return true if pattern found in text define match { text = $1 pattern = $2 return (search_string(text, pattern, 0, "regex") >= 0) } # match_between(text, beg, end, pattern): define match_between { text = $1 beg = $2 end = $3 pattern = $4 if (beg < 0 || end < beg || length(text) < beg) return 0 pos = search_string(text, pattern, beg, "regex") return (pos >= beg && $search_end <= end) } # match_line(text, line_no, pattern): define match_line { text = $1 line_no = $2 pattern = $3 beg = str_line_col_to_pos(text, line_no) if (beg < 0) return 0 end = end_of_line_pos(beg, text) return match_between(text, beg, end, pattern) } # toTable(text): return text as a table define toTable { text = $1 result = "" nrec = 0; ncol = 0; sepChar = " " hdrs = $empty_array lens = $empty_array cols = $empty_array ints = $empty_array decs = $empty_array data = $empty_array # main loop x__beg = 0; x__end = -1; x__lim = length(text); x__NR = 0 while (x__end < x__lim) { # start main loop ---------------------------------------------------------- x__beg = x__end + 1 x__end = end_of_line_pos(x__beg, text) x__NR++ if (match_between(text, x__beg, x__end, "^\\s*$")) { nrec++; continue } pos = search_string(text, ":", x__beg) if (pos < x__beg || $search_end > x__end) continue hdr = substring(text, x__beg, pos) # make sure header is registered if (!(hdr in hdrs)) { lens[hdr] = length(hdr) hdrs[hdr] = ncol ints[hdr] = 0 decs[hdr] = 0 cols[ncol] = hdr ncol++ } val = substring(text, pos + 1, x__end) val = replace_in_string(val, "^\\s*((?:(?!\\s*$).)*)\\s*$", "\\1", "regex") if (match(val, "^[-+]?(?:\\d+\\.?\\d*|\\.\\d+)$")) { # remove trailing decimal zeros (and point) val = replace_in_string(val, "\\.0+$", "", "regex", "copy") val = replace_in_string(val, "(\\.\\d*[1-9])0+$", "\\1", "regex", "copy") # measure intpart length and decpart length decpos = search_string(val, ".", 0) vlen = length(val) if (decpos >= 0) intlen = decpos; else intlen = vlen declen = vlen - intlen ints[hdr] = max(ints[hdr], intlen) decs[hdr] = max(decs[hdr], declen) # evaluate current value max width vlen = ints[hdr] + decs[hdr] lens[hdr] = max(lens[hdr], vlen) } data[nrec, hdr] = val lens[hdr] = max(lens[hdr], length(val)) # end main loop ------------------------------------------------------------ } # print headings sep = "" for (col = 0; col < ncol; col++) { hdr = cols[col] len = lens[hdr] result = result sep ljust(hdr, len) sep = sepChar } result = result "\n" # print bars sep = "" for (col = 0; col < ncol; col++) { hdr = cols[col] len = lens[hdr] bar = replace_in_string(ljust(" ", len), " ", "-") result = result sep bar sep = sepChar } result = result "\n" # print data for (rec = 0; rec < nrec; rec++) { sep = "" for (col = 0; col < ncol; col++) { hdr = cols[col] len = lens[hdr] val = "" if ((rec $sub_sep hdr) in data) val = data[rec, hdr] # check whether it is numeric to determine justification if (match(val, "^[-+]?(?:\\d+\\.?\\d*|\\.\\d+)$")) { # measure intpart length and decpart length decpos = search_string(val, ".", 0) vlen = length(val) if (decpos >= 0) intlen = decpos; else intlen = vlen declen = vlen - intlen decl = decs[hdr] - declen # add trailing spaces to line up decimals if (decl > 0) val = val ljust(" ", decl) result = result sep rjust(val, len) } else { result = result sep ljust(val, len) } sep = sepChar } result = result "\n" } # print bars for (col = 0; col < ncol; col++) { hdr = cols[col] DEBUG(col" - "hdr": len="lens[hdr]" int="ints[hdr]" dec="decs[hdr]"\n") } result = result "\n" return result }