summaryrefslogtreecommitdiff
path: root/src/lib/librexgettext
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/librexgettext')
-rwxr-xr-xsrc/lib/librexgettext101
1 files changed, 78 insertions, 23 deletions
diff --git a/src/lib/librexgettext b/src/lib/librexgettext
index 22a6df2..c82b9ae 100755
--- a/src/lib/librexgettext
+++ b/src/lib/librexgettext
@@ -65,49 +65,104 @@ xgettext-sh() {
xgettext-flag() {
{
- declare -i x=0
+ # Stage 1: Generate
+ #
+ # Get all of the arguments to `flag`. Because `flag`
+ # takes an arbitrary number of arguments, just iterate
+ # through arg1, arg2, ... argN; until we've come up
+ # empty 3 times. Why 3? Because each flag takes 2
+ # arguments, and because we don't keep track of which
+ # one of those we're on, waiting for 3 empties ensures
+ # us that we've had a complete "round" with nothing.
+ #
+ # Why can't I just do i+=2, and not have to keep track
+ # of empties? Because, we also allow for arguments
+ # ending in a colon to be headings, which changes the
+ # offsets.
+ declare -i empties=0
declare -i i
- for (( i=1; x < 3; i++ )); do
+ for (( i=1; empties < 3; i++ )); do
local out
out="$(xgettext-sh --keyword="flag:$i,\"$i\"" "$@")"
if [[ -n $out ]]; then
printf -- '%s\n' "$out"
else
- x+=1
+ empties+=1
fi
done
} | whitespace-collapse | sed '/^\#, sh-format/d' | {
- declare -i i
-
- IFS=''
- local segments=()
+ # Stage 2: Parse
+ #
+ # Read in the lines, and group them into an array of
+ # (multi-line) msgs. This just makes working with
+ # them easier.
+ local msgs=()
+ declare -i i=-1
local re='^#\. ([0-9]+)$'
+ IFS=''
local line
while read -r line; do
if [[ $line =~ $re ]]; then
- i=${BASH_REMATCH[1]}
- else
- segments[$i]+="$line"$'\n'
+ i+=1
fi
+ msgs[$i]+="$line"$'\n'
done
-
- declare -i last=$(printf '%s\n' "${!segments[@]}"|sed -n '$p')
-
+ # Stage 3: Sort
+ #
+ # Now, we have the `msgs` array, and it is
+ # sorted such that it is all of the arg1's to `flag`,
+ # then all of the arg2's, then all of the arg3's, and
+ # so on. We want to re-order them such that it's all
+ # of the args for the first invocation then all of the
+ # args for the second; and so on.
+ #
+ # We do this by simply sorting them by the location
+ # that they appear in the file. Then, when we see the
+ # argument number go back down to 1, we know that a
+ # new invocation has started!
IFS=$'\n'
- local flag=true
- for (( i=1; i <= last; i++ )); do
- if $flag; then
- local lines=(${segments[$i]})
+ local locations=($(
+ local i
+ for i in "${!msgs[@]}"; do
+ declare -i arg row
+ local lines=(${msgs[$i]})
+ arg=${lines[0]#'#. '}
+ row=${lines[1]##*:}
+ printf '%d.%d %d\n' "$row" "$arg" "$i"
+ done | sort -n
+ ))
+ # Stage 4: Output
+ #
+ # Now, we prune out the arguments that aren't
+ # localizable. Also, remove the "#." comment lines.
+ # As explained above (in stage 3), when we see $arg go
+ # to 1, that's the beginning of a new invocation.
+ local expectflag=true
+ local location
+ for location in "${locations[@]}"; do
+ IFS=' .'
+ local row arg i
+ read -r row arg i <<<"$location"
+ local msg="${msgs[$i]#*$'\n'}"
+ # Now we operate based on $row, $arg, and $msg
+ if [[ $arg == 1 ]]; then
+ expectflag=true
+ fi
+ if $expectflag; then
+ IFS=$'\n'
+ local lines=(${msg})
if [[ ${lines[1]} == *':"' ]]; then
- printf -- '%s\n' "${segments[$i]}"
+ # We expected a flag, but got
+ # a heading
+ printf -- '%s\n' "$msg"
else
- flag=false
+ # We expected a flag, and got
+ # one!
+ expectflag=false
fi
else
- if [[ -n ${segments[$i]} ]]; then
- printf -- '%s\n' "${segments[$i]}"
- fi
- flag=true
+ printf -- '%s\n' "$msg"
+ expectflag=true
fi
done
}