|
3 | 3 | # Text formatting utilities |
4 | 4 | # |
5 | 5 | # Exports: |
| 6 | +# @go.array_printf |
| 7 | +# Assigns `printf` transformations of its arguments to an array |
6 | 8 | # |
7 | 9 | # @go.pad_items |
8 | | -# Pads each string in an array to match the length of the longest element |
| 10 | +# Right-pads each string with spaces to match the length of the longest |
9 | 11 | # |
10 | 12 | # @go.zip_items |
11 | 13 | # Concatenates parallel elements from each input array |
12 | 14 | # |
13 | 15 | # @go.strip_formatting_codes |
14 | 16 | # Strips ANSI escape codes of the form `\e[...(;...)m` from a string |
15 | 17 |
|
16 | | -# Pads each string in an array to match the length of the longest element |
| 18 | +. "$_GO_USE_MODULES" 'strings' 'validation' |
| 19 | + |
| 20 | +# Assigns `printf` transformations of its arguments to an array |
| 21 | +# |
| 22 | +# Since `printf -v` can't print to an array subscript prior to Bash 4.1, this |
| 23 | +# provides a portable means of printing to an array variable while avoiding the |
| 24 | +# use of `eval`. |
| 25 | +# |
| 26 | +# NOTE: By default, this function relies on the ASCII Record Separator character |
| 27 | +# ($'\x1f') to delimit generated strings before splitting them into the result |
| 28 | +# array. If you have strings containing this character, you can set a new |
| 29 | +# delimiter via `_GO_ARRAY_PRINTF_DELIMITER`. |
| 30 | +# |
| 31 | +# Globals: |
| 32 | +# _GO_ARRAY_PRINTF_DELIMITER: |
| 33 | +# If set, used to separate generated strings prior to array assignment |
| 34 | +# |
| 35 | +# Arguments: |
| 36 | +# result: Name of the caller-declared output array |
| 37 | +# format: `printf`-style format specification |
| 38 | +# ...: Items to pass to `printf` and store in `result` |
| 39 | +@go.array_printf() { |
| 40 | + @go.validate_identifier_or_die 'Result array name' "$1" |
| 41 | + local __go_array_printf_delim="${_GO_ARRAY_PRINTF_DELIMITER:-$'\x1f'}" |
| 42 | + local __tmp_go_array_printf |
| 43 | + printf -v __tmp_go_array_printf -- "${2}${__go_array_printf_delim}" "${@:3}" |
| 44 | + @go.split "$__go_array_printf_delim" "$__tmp_go_array_printf" "$1" |
| 45 | +} |
| 46 | + |
| 47 | +# Right-pads each string with spaces to match the length of the longest |
| 48 | +# |
| 49 | +# Globals: |
| 50 | +# _GO_ARRAY_PRINTF_DELIMITER: See the comments for `@go.array_printf` |
17 | 51 | # |
18 | 52 | # Arguments: |
19 | | -# $1: Name of the input array in the caller's scope |
20 | | -# Outputs: |
21 | | -# __go_padded_result: The caller-declared array to which results are assigned |
| 53 | +# result: Name of the caller-declared output array |
| 54 | +# ...: Items to right-pad with spaces to match the longest one |
22 | 55 | @go.pad_items() { |
23 | | - local items_reference=("${1}[@]") |
24 | | - local item |
25 | | - local padding='' |
26 | | - local padding_len=0 |
| 56 | + @go.validate_identifier_or_die 'Result array name' "$1" |
| 57 | + local __go_pad_items_items=("${@:2}") |
| 58 | + local __item |
| 59 | + local padding_size=0 |
27 | 60 |
|
28 | | - for item in "${!items_reference}"; do |
29 | | - while [[ "${#padding}" -lt "${#item}" ]]; do |
30 | | - padding+=' ' |
| 61 | + for __item in "${__go_pad_items_items[@]}"; do |
| 62 | + while [[ "$padding_size" -lt "${#__item}" ]]; do |
| 63 | + padding_size="${#__item}" |
31 | 64 | done |
32 | 65 | done |
33 | | - |
34 | | - for item in "${!items_reference}"; do |
35 | | - padding_len="$((${#padding} - ${#item}))" |
36 | | - __go_padded_result+=("${item}${padding:0:padding_len}") |
37 | | - done |
| 66 | + @go.array_printf "$1" "%-${padding_size}s" "${__go_pad_items_items[@]}" |
38 | 67 | } |
39 | 68 |
|
40 | 69 | # Concatenates parallel elements from each input array |
41 | 70 | # |
42 | 71 | # Will produce a number of results matching that of the left-hand input array. |
43 | 72 | # |
| 73 | +# Globals: |
| 74 | +# _GO_ARRAY_PRINTF_DELIMITER: See the comments for `@go.array_printf` |
| 75 | +# |
44 | 76 | # Arguments: |
45 | | -# $1: Name of the left-hand input array in the caller's scope |
46 | | -# $2: Name of the right-hand input array in the caller's scope |
47 | | -# $3: The string used as a delimiter between elements (defaults to two spaces) |
48 | | -# Outputs: |
49 | | -# __go_zipped_result: The caller-declared array to which results are assigned |
| 77 | +# lhs: Name of the left-hand input array in the caller's scope |
| 78 | +# rhs: Name of the right-hand input array in the caller's scope |
| 79 | +# delim: String used as a delimiter between elements (default: two spaces) |
| 80 | +# result: Name of the caller-declared output array |
50 | 81 | @go.zip_items() { |
| 82 | + @go.validate_identifier_or_die 'Result array name' "$4" |
51 | 83 | local lhs_array_reference="${1}[@]" |
52 | | - local rhs_reference="$2" |
53 | | - local delimiter="${3:- }" |
54 | 84 | local rhs_item_ref |
55 | 85 | local item |
56 | | - local i=-1 |
| 86 | + local i=0 |
| 87 | + local __tmp_go_zip_items_result=() |
57 | 88 |
|
58 | 89 | for item in "${!lhs_array_reference}"; do |
59 | | - rhs_item_ref="${rhs_reference}[$((++i))]" |
60 | | - __go_zipped_result+=("${item}${delimiter}${!rhs_item_ref}") |
| 90 | + rhs_item_ref="${2}[$((i++))]" |
| 91 | + __tmp_go_zip_items_result+=("${item}${3}${!rhs_item_ref}") |
61 | 92 | done |
| 93 | + @go.array_printf "$4" '%s' "${__tmp_go_zip_items_result[@]}" |
62 | 94 | } |
63 | 95 |
|
64 | | -# Strips ANSI escape codes of the form `\e[...(;...)m` from a string |
| 96 | +# Strips ANSI escape codes from a string |
65 | 97 | # |
66 | 98 | # Used primarily by `@go.log`. |
67 | 99 | # |
68 | 100 | # Arguments: |
69 | | -# $1: The string to strip |
70 | | -# Outputs: |
71 | | -# __go_stripped_value: The caller-declared variable for the stripped result |
| 101 | +# original: The string to strip |
| 102 | +# result: Name of the caller-declared output variable |
72 | 103 | @go.strip_formatting_codes() { |
73 | | - __go_stripped_value="$1" |
74 | | - local format_pattern='\\e\[[0-9]{1,3}(;[0-9]{1,3})*m' |
| 104 | + @go.validate_identifier_or_die 'Result variable name' "$2" |
| 105 | + printf -v "$2" -- '%b' "$1" |
| 106 | + |
| 107 | + if [[ -z "$__GO_STRIP_FORMATTING_PATTERN" ]]; then |
| 108 | + printf -v __GO_STRIP_FORMATTING_PATTERN '%b' '\e[[0-9]{1,3}(;[0-9]{1,3})*m' |
| 109 | + readonly __GO_STRIP_FORMATTING_PATTERN |
| 110 | + fi |
75 | 111 |
|
76 | | - while [[ "$__go_stripped_value" =~ $format_pattern ]]; do |
77 | | - __go_stripped_value="${__go_stripped_value/"${BASH_REMATCH[0]}"}" |
| 112 | + while [[ "${!2}" =~ $__GO_STRIP_FORMATTING_PATTERN ]]; do |
| 113 | + printf -v "$2" -- '%s' "${!2/"${BASH_REMATCH[0]}"}" |
78 | 114 | done |
79 | 115 | } |
0 commit comments