Rev 16 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 15 | PointedEar | 1 | #!/bin/bash |
| 2 | |||
| 288 | PointedEar | 3 | appname="EazyTranslator" |
| 4 | appver="0.97a" |
||
| 5 | appfilename=$(readlink $(basename "$0")) |
||
| 6 | [ -n "$appfilename" ] && appfiledir=$(echo "$0" | sed "s/$appfilename\$//") |
||
| 15 | PointedEar | 7 | |
| 8 | # dictionary file |
||
| 288 | PointedEar | 9 | dict="$TRANSLATE_DIR" |
| 10 | [ -z "$dict" ] && dict=$appfiledir |
||
| 15 | PointedEar | 11 | |
| 12 | # delimiter name (for help page only) and character (string) for separating original expression |
||
| 13 | # and translation in dictionary file |
||
| 288 | PointedEar | 14 | delimiter_name="colon" |
| 15 | delimiter=":" |
||
| 15 | PointedEar | 16 | |
| 17 | # all help on a single page |
||
| 288 | PointedEar | 18 | single_page=0 |
| 15 | PointedEar | 19 | |
| 20 | # bell character |
||
| 288 | PointedEar | 21 | ch_sound="" |
| 22 | ch_sound_on=$'\a' |
||
| 15 | PointedEar | 23 | |
| 288 | PointedEar | 24 | result="" |
| 15 | PointedEar | 25 | |
| 288 | PointedEar | 26 | title() { |
| 27 | #[ $single_page -eq 0 ] && clear |
||
| 28 | echo " |
||
| 29 | $appname $appver - Stream editor to use and to manage dictionary files |
||
| 30 | Requires 'basename', 'grep' and 'sed', optionally 'sort' and 'mktemp' in PATH |
||
| 31 | " |
||
| 15 | PointedEar | 32 | } |
| 33 | |||
| 288 | PointedEar | 34 | copyright() { |
| 35 | echo "Copyright (C) 2001 Thomas Lahn (webmaster@PointedEars.de) |
||
| 36 | Be sure to have 'easyTrans' or similar in mail subject line for fast response. |
||
| 37 | " |
||
| 15 | PointedEar | 38 | } |
| 39 | |||
| 288 | PointedEar | 40 | pause() { |
| 15 | PointedEar | 41 | if [ "$1" == "c" ]; then |
| 42 | echo "Hit RETURN to continue..." |
||
| 43 | else |
||
| 44 | echo "Hit RETURN for the next page" |
||
| 45 | fi |
||
| 46 | read |
||
| 47 | } |
||
| 48 | |||
| 288 | PointedEar | 49 | copying() { |
| 15 | PointedEar | 50 | title |
| 51 | copyright |
||
| 288 | PointedEar | 52 | echo "This program is free software; you can redistribute it and/or modify |
| 53 | it under the terms of the GNU General Public License as published by |
||
| 54 | the Free Software Foundation; either version 2 of the License, or |
||
| 55 | (at your option) any later version. |
||
| 56 | |||
| 57 | This program is distributed in the hope that it will be useful, |
||
| 58 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 59 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
| 60 | GNU General Public License for more details. |
||
| 61 | |||
| 62 | You should have received a copy of the GNU General Public License |
||
| 63 | along with this program (COPYING file); if not, write to the |
||
| 64 | Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
||
| 65 | " |
||
| 15 | PointedEar | 66 | } |
| 67 | |||
| 288 | PointedEar | 68 | cmdHelp() { |
| 15 | PointedEar | 69 | title |
| 288 | PointedEar | 70 | echo "$appfilename EXPRESSION DICTIONARY [OPTIONS] |
| 71 | |||
| 72 | Tries to translate EXPRESSION looking up DICTIONARY and writes the result |
||
| 73 | |||
| 74 | Environment: |
||
| 75 | |||
| 76 | TRANSLATE_DIR Dictionary folder root (absolute path '/')" |
||
| 77 | if [ -n "$TRANSLATE_DIR" ]; then |
||
| 78 | local INVALID_PATH=" -- INVALID PATH!" |
||
| 79 | local INVALID_FORMAT=" -- INVALID FORMAT!" |
||
| 80 | # : AutoCorrect performed! |
||
| 81 | local INVALID_MSG="" |
||
| 82 | if [ ! -e $TRANSLATE_DIR ]; then |
||
| 83 | INVALID_MSG=$INVALID_PATH |
||
| 84 | else |
||
| 85 | local GREPRES=$(echo $TRANSLATE_DIR | grep -e "\/$") |
||
| 86 | [ -z "$GREPRES" ] && INVALID_MSG=$INVALID_FORMAT |
||
| 87 | fi |
||
| 88 | echo " (currently '"$TRANSLATE_DIR"'"$INVALID_MSG")" |
||
| 89 | #if [ "$INVALID_MSG" == "$INVALID_FORMAT" ]; then |
||
| 90 | #export TRANSLATE_DIR=$TRANSLATE_DIR"/" |
||
| 91 | #set -a |
||
| 92 | #fi |
||
| 15 | PointedEar | 93 | fi |
| 288 | PointedEar | 94 | echo "\ |
| 95 | If undefined, this is the program directory |
||
| 96 | (currently '$appfiledir'). |
||
| 97 | TRANSLATE_OPTIONS Default options to overwrite command-line options" |
||
| 15 | PointedEar | 98 | if [ -n "$TRANSLATE_OPTIONS" ]; then |
| 99 | echo " (currently '"$TRANSLATE_OPTIONS"')" |
||
| 100 | fi |
||
| 288 | PointedEar | 101 | echo " |
| 102 | Arguments: |
||
| 103 | |||
| 104 | EXPRESSION Word or (double-quoted) phrase to be translated |
||
| 105 | DICTIONARY Path of dictionary file relative to TRANSLATE_DIR |
||
| 106 | " |
||
| 107 | [ $single_page -eq 0 ] && pause "c" |
||
| 108 | echo "\ |
||
| 109 | Translation OPTIONS: |
||
| 110 | -b, --brackets If not in DICTIONARY, writes given WORD or EXPRESSION |
||
| 111 | as [WORD] or [EXPRESSION]. |
||
| 112 | -m, --messages Return error messages instead of null-strings. |
||
| 113 | -p, --phrase Translate EXPRESSION as entire phrase. If not given, |
||
| 114 | each WORD of EXPRESSION is translated seperately. |
||
| 115 | -r, --reverse Perform reverse translation. Recommended only if |
||
| 116 | no appropriate dictionary file for vice-versa translation is |
||
| 117 | available and -p is also used. |
||
| 118 | -s, --sound Beep on fatal errors. |
||
| 119 | -v, --verbose Display flow of operation. Includes -m behavior. |
||
| 120 | -z, --zero Return not translatable tokens as null-strings. |
||
| 121 | Overwrites -b. |
||
| 122 | " |
||
| 123 | [ $single_page -eq 0 ] && pause "c" |
||
| 124 | echo "\ |
||
| 125 | $appfilename EXPRESSION DICTIONARY COMMAND TRANSLATION [INFO] [OPTIONS] |
||
| 126 | $appfilename COMMAND DICTIONARY [INFO] [OPTIONS] |
||
| 127 | |||
| 128 | Dictionary file COMMANDs: |
||
| 129 | -a, --add If not in DICTIONARY, add EXPRESSION with TRANSLATION |
||
| 130 | to DICTIONARY and write TRANSLATION. |
||
| 131 | If DICTIONARY not exists, create the file with INFO |
||
| 132 | and add the entry; if INFO is a null-string, |
||
| 133 | default INFO is added, containing program version, |
||
| 134 | user name and timestamp. Requires 'sort'. |
||
| 135 | -ai, --addinfo Add information data INFO to DICTIONARY. |
||
| 136 | Must be used as first argument. |
||
| 137 | -c, --create Create new DICTIONARY with INFO (see -a). |
||
| 138 | Existing files are replaced. Must be used as first argument. |
||
| 139 | |||
| 140 | -d, --delete If used with EXPRESSION and DICTIONARY, remove EXPRESSION |
||
| 141 | from DICTIONARY instead of translating. |
||
| 142 | If used as first argument, delete DICTIONARY. |
||
| 143 | -i, --info Display information about DICTIONARY. |
||
| 144 | Must be used as first argument. |
||
| 145 | " |
||
| 146 | [ $single_page -eq 0 ] && pause "c" |
||
| 147 | echo "\ |
||
| 148 | -o, --overwrite Like -a but overwrite a contained translation of |
||
| 149 | EXPRESSION with TRANSLATION without question. |
||
| 150 | Additionally requires 'mktemp'. |
||
| 151 | -R, --repair Repair DICTIONARY instead of translating. Requires 'mktemp'. |
||
| 152 | Info data is be kept but invalid entries are removed. |
||
| 153 | USE WITH CAUTION! |
||
| 154 | -s, --sort Sort DICTIONARY instead of translating. Requires 'sort'. |
||
| 155 | Includes --sound when used with -v. |
||
| 156 | Must be used as first argument. |
||
| 157 | " |
||
| 158 | [ $single_page -eq 0 ] && pause "c" |
||
| 159 | echo "\ |
||
| 160 | $appfilename OPTION [OPTION] |
||
| 161 | |||
| 162 | Help page OPTIONs: |
||
| 163 | --1 Display help on one page (without 'clear' and user input). |
||
| 164 | Useful with redirection |
||
| 165 | (try '"$appfilename" --1 --? > translate.doc.txt'). |
||
| 166 | Must be given before all other help page options. |
||
| 167 | --a, --about Display information about the program. |
||
| 168 | --c, --cmd Display this help page. |
||
| 169 | --d, --dict Display help about dictionary files. |
||
| 170 | --dev, --emp Display special information for developers and employers. |
||
| 171 | --x, --example Display example. |
||
| 172 | --?, --help Display all help pages. |
||
| 173 | " |
||
| 15 | PointedEar | 174 | } |
| 175 | |||
| 288 | PointedEar | 176 | example() { |
| 15 | PointedEar | 177 | title |
| 288 | PointedEar | 178 | echo "EXAMPLE: If you would like to translate the English words 'a few' into German, |
| 179 | |||
| 180 | $appfilename 'a few' en-de |
||
| 181 | |||
| 182 | should write the German words |
||
| 183 | |||
| 184 | ein(e) wenig(e)\n |
||
| 185 | |||
| 186 | (without indent) to stdout if the echo dictionary file 'en-de' contains |
||
| 187 | a correct entry for it (see next page). You may also translate it as |
||
| 188 | entire phrase (which seems to make more sense here): |
||
| 189 | |||
| 190 | $appfilename 'a few' en-de -p |
||
| 191 | |||
| 192 | should instead write the German word 'einige\n' |
||
| 193 | (replace '' in input with the double-quote character). |
||
| 194 | |||
| 195 | " |
||
| 15 | PointedEar | 196 | } |
| 197 | |||
| 288 | PointedEar | 198 | dictHelp() { |
| 15 | PointedEar | 199 | title |
| 288 | PointedEar | 200 | echo "\ |
| 201 | DICTIONARY FILES: |
||
| 202 | You may create/improve dictionary files to be used with $appname |
||
| 203 | of your own. Translation data must match the following expression: |
||
| 204 | |||
| 205 | #${delimiter}File description displayed when option -i is used\\n[#${delimiter}File description\\n] |
||
| 206 | [Expression"$delimiter"translation\\n[Next expression"$delimiter"next translation\\n]] |
||
| 207 | Last expression"$delimiter"last translation\z |
||
| 208 | |||
| 209 | Parts enclosed in rectangle brackets are optional. The $delimiter_name ($delimiter) is to be used |
||
| 210 | as delimiter character between original and translated expression only. |
||
| 211 | Dictionary file names should contain common language identifiers separated |
||
| 212 | by a dash (such as 'en-de.dic' for an English-German dictionary file). |
||
| 213 | |||
| 214 | Program updates and dictionaries can be obtained from |
||
| 215 | 'http://pointedears.de/tools/eazytrans/'. |
||
| 216 | Thank you for using a program by PointedEars. |
||
| 217 | " |
||
| 15 | PointedEar | 218 | } |
| 219 | |||
| 288 | PointedEar | 220 | devInfo() { |
| 15 | PointedEar | 221 | title |
| 222 | copyright |
||
| 288 | PointedEar | 223 | echo "\ |
| 224 | KNOWN ISSUES |
||
| 225 | |||
| 226 | - Sorting the dictionary unfortunately also sorts its info data by now. |
||
| 227 | " |
||
| 15 | PointedEar | 228 | } |
| 229 | |||
| 288 | PointedEar | 230 | help() { |
| 15 | PointedEar | 231 | copying |
| 288 | PointedEar | 232 | [ $single_page -eq 0 ] && pause |
| 15 | PointedEar | 233 | cmdHelp |
| 288 | PointedEar | 234 | [ $single_page -eq 0 ] && pause |
| 15 | PointedEar | 235 | example |
| 288 | PointedEar | 236 | [ $single_page -eq 0 ] && pause |
| 15 | PointedEar | 237 | dictHelp |
| 288 | PointedEar | 238 | [ $single_page -eq 0 ] && pause |
| 15 | PointedEar | 239 | devInfo |
| 240 | } |
||
| 241 | |||
| 288 | PointedEar | 242 | check_dictionary() { |
| 243 | # check if dictionary file (contains at least '#$delimiter') |
||
| 244 | [ $verbose -eq 1 ] && echo "Executing: grep -e '."$delimiter".' '"$dict"'" |
||
| 245 | result=$(grep -e "#$delimiter." "$dict") |
||
| 246 | if [ -z "$result" ]; then |
||
| 247 | [ $verbose -eq 1 ] && echo "grep returned: ''" |
||
| 248 | echo $dict": Not a (valid) dictionary file (type '"$appfilename" --d' for details)." |
||
| 249 | [ $verbose -eq 1 ] && echo |
||
| 250 | exit $EDICT_WRONG_FORMAT |
||
| 251 | else |
||
| 252 | if [ $verbose -eq 1 ]; then |
||
| 253 | echo "grep returned not a null-string: '$dict' seems to be a dictionary file" |
||
| 254 | fi |
||
| 255 | fi |
||
| 256 | result="" |
||
| 257 | } |
||
| 258 | |||
| 259 | create() { |
||
| 260 | [ $verbose -eq 1 ] && echo $dict": Creating dictionary" |
||
| 261 | if [ -z "$3" ]; then |
||
| 262 | [ $verbose -eq 1 ] && echo $dict": Adding information: '"$DEFAULT_INFO |
||
| 263 | echo "#"$delimiter$DEFAULT_INFO &>$dict |
||
| 264 | else |
||
| 265 | [ $verbose -eq 1 ] && echo $dict": Adding information: '"$3"'" |
||
| 266 | echo "#"$delimiter$3 &>$dict |
||
| 267 | fi |
||
| 268 | [ $verbose -eq 1 ] && echo |
||
| 269 | exit $? |
||
| 270 | } |
||
| 271 | |||
| 272 | add_info() { |
||
| 273 | if [ -z "$3" ]; then |
||
| 274 | [ $verbose -eq 1 ] && echo $dict": Adding information: '"$DEFAULT_INFO"'" |
||
| 275 | echo "#"$delimiter$DEFAULT_INFO >>$dict |
||
| 276 | else |
||
| 277 | [ $verbose -eq 1 ] && echo $dict": Adding information: '"$3"'" |
||
| 278 | echo "#"$delimiter$3 >>$dict |
||
| 279 | fi |
||
| 280 | [ $verbose -eq 1 ] && echo |
||
| 281 | exit $? |
||
| 282 | } |
||
| 283 | |||
| 284 | info() { |
||
| 285 | if [ $verbose -eq 1 ]; then |
||
| 286 | echo "Obtaining information..." |
||
| 287 | echo |
||
| 288 | fi |
||
| 289 | grep "^#$delimiter" "$dict" | sed 's/^#'$delimiter'//' |
||
| 290 | result=$(grep -e "^#$delimiter" "$dict") |
||
| 291 | [ -z "$result" ] && echo $ch_sound$dict": No information available" |
||
| 292 | [ $verbose -eq 1 ] && echo |
||
| 293 | exit $ESUCCESS |
||
| 294 | } |
||
| 295 | |||
| 296 | add_translation() { |
||
| 297 | [ $verbose -eq 1 ] && echo |
||
| 298 | result=$(grep -i -e "^$1$delimiter" "$dict") |
||
| 299 | if [ -z "$result" ]; then |
||
| 300 | echo $dict": Adding expression: '"$1"'" |
||
| 301 | echo $dict": Adding translation: '"$4"'" |
||
| 302 | if [ -n "$4" ]; then |
||
| 303 | echo $1$delimiter$4 >>$dict |
||
| 304 | else |
||
| 305 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $ch_sound$appfilename": No translation given for '"$1"'" |
||
| 306 | fi |
||
| 307 | sort=1 |
||
| 308 | else |
||
| 309 | translate "$1" |
||
| 310 | echo $ch_sound$dict": Expression already contained: '"$1"':"$result |
||
| 311 | [ $verbose -eq 1 ] && echo |
||
| 312 | exit $EDICT_EXPR_CONTAINED |
||
| 313 | fi |
||
| 314 | } |
||
| 315 | |||
| 316 | replace_translation() { |
||
| 317 | [ $verbose -eq 1 ] && echo |
||
| 318 | echo $dict": Replacing expression: '"$1"'" |
||
| 319 | echo $dict": Replacing translation: '"$4"'" |
||
| 320 | TMPFILE=$(mktemp -q /tmp/$appfilename.XXXXXX) |
||
| 321 | if [ $? -ne 0 ]; then |
||
| 322 | [ $verbose -eq 1 ] && echo $appfilename": Can't create temp file, exiting..." |
||
| 323 | exit EDICT_TEMP_ERROR |
||
| 324 | else |
||
| 325 | if [ -n "$4" ]; then |
||
| 326 | grep -iv -e "^$1$delimiter" "$dict" &>$TMPFILE |
||
| 327 | [ $? -eq 0 ] && echo $1$delimiter$4 >>$TMPFILE |
||
| 328 | [ $? -eq 0 ] && mv $TMPFILE $dict &>/dev/null |
||
| 329 | if [ $? -ne 0 ]; then |
||
| 330 | [ $verbose -eq 1 ] && echo $appfilename": Unable to replace dictionary file: '"$dict"'" |
||
| 331 | exit EDICT_REPLACE_ERROR |
||
| 332 | else |
||
| 333 | sort=1 |
||
| 334 | fi |
||
| 335 | else |
||
| 336 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $ch_sound$appfilename": No translation given for '"$1"'" |
||
| 337 | fi |
||
| 338 | fi |
||
| 339 | } |
||
| 340 | |||
| 341 | delete() { |
||
| 342 | if [ $dictionary -eq 0 ]; then |
||
| 343 | # delete entry |
||
| 344 | [ $verbose -eq 1 ] && echo $dict": Removing expression: "$1 |
||
| 345 | result=$(grep -i -e "^$1$delimiter" "$dict") |
||
| 346 | if [ -z "$result" ]; then |
||
| 347 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $dict": Expression not contained in dictionary: '"$1"'" |
||
| 348 | exit $EDICT_DELETE_EXPR_NOT_FOUND |
||
| 349 | fi |
||
| 350 | TMPFILE=$(mktemp -q /tmp/$appfilename.XXXXXX) |
||
| 351 | if [ $? -ne 0 ]; then |
||
| 352 | [ $verbose -eq 1 ] && echo $appfilename": Can't create temp file, exiting..." |
||
| 353 | exit EDICT_TEMP_ERROR |
||
| 354 | else |
||
| 355 | grep -iv -e "$1$delimiter" "$dict" &>$TMPFILE |
||
| 356 | [ $? -eq 0 ] && mv $TMPFILE $dict &>/dev/null |
||
| 357 | if [ $? -ne 0 ]; then |
||
| 358 | [ $verbose -eq 1 ] && echo $dict": Unable to modify dictionary (cannot replace file)" |
||
| 359 | exit EDICT_REPLACE_ERROR |
||
| 360 | else |
||
| 361 | [ $verbose -eq 1 ] && echo $dict": Modification successful" |
||
| 362 | exit $ESUCCESS |
||
| 363 | fi |
||
| 364 | fi |
||
| 365 | else |
||
| 366 | # delete dictionary |
||
| 367 | if [ $verbose -eq 1 ]; then |
||
| 368 | echo $appfilename": Deleting dictionary: '"$dict"'" |
||
| 369 | echo $appfilename": Executing: rm '"$dict"' &>/dev/null" |
||
| 370 | fi |
||
| 371 | rm $dict &>/dev/null |
||
| 372 | if [ $? -ne 0 ]; then |
||
| 373 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $dict": Unable to remove dictionary" |
||
| 374 | exit $EDICT_REMOVE |
||
| 375 | else |
||
| 376 | if [ $verbose -eq 1 ]; then |
||
| 377 | echo $dict": Dictionary successfully removed" |
||
| 378 | echo |
||
| 379 | fi |
||
| 380 | exit $ESUCCESS |
||
| 381 | fi |
||
| 382 | fi |
||
| 383 | } |
||
| 384 | |||
| 385 | sort_dictionary() { |
||
| 386 | if [ $verbose -eq 1 ]; then |
||
| 387 | echo "Sorting dictionary: '"$dict"'" |
||
| 388 | echo "Executing: sort -d -f -o "$dict" -t "$delimiter" "$dict |
||
| 389 | fi |
||
| 390 | result=$(sort -d -f -o "$dict" -t $delimiter "$dict") |
||
| 391 | SORT_EXIT=$? |
||
| 392 | if [ $verbose -eq 1 ]; then |
||
| 393 | echo "sort returned exit code "$SORT_EXIT |
||
| 394 | if [ $SORT_EXIT -eq 0 ]; then |
||
| 395 | echo "Sorting successful: '"$dict"'" |
||
| 396 | else |
||
| 397 | echo "Sorting failed: '"$dict"'" |
||
| 398 | fi |
||
| 399 | echo |
||
| 400 | fi |
||
| 401 | exit $SORT_EXIT |
||
| 402 | } |
||
| 403 | |||
| 404 | repair() { |
||
| 405 | [ $verbose -eq 1 ] && echo $dict": Repairing dictionary" |
||
| 406 | TMPFILE=$(mktemp -q /tmp/$appfilename.XXXXXX) |
||
| 407 | if [ $? -ne 0 ]; then |
||
| 408 | [ $verbose -eq 1 ] && echo $appfilename": Can't create temp file, exiting..." |
||
| 409 | exit EDICT_TEMP_ERROR |
||
| 410 | else |
||
| 411 | grep -e "^#$delimiter" "$dict" &>$TMPFILE |
||
| 412 | grep -e ".$delimiter." "$dict" >>$TMPFILE |
||
| 413 | [ $? -eq 0 ] && mv $TMPFILE $dict &>/dev/null |
||
| 414 | if [ $? -ne 0 ]; then |
||
| 415 | [ $verbose -eq 1 ] && echo $dict": Unable to repair dictionary (cannot replace file)" |
||
| 416 | exit EDICT_REPLACE_ERROR |
||
| 417 | else |
||
| 418 | $dict": Repair successful" |
||
| 419 | fi |
||
| 420 | fi |
||
| 421 | } |
||
| 422 | |||
| 423 | translateReverse() { |
||
| 15 | PointedEar | 424 | local EXPR="$1" |
| 288 | PointedEar | 425 | [ $verbose -eq 1 ] && echo >&2 "Executing: grep -i -e '"$delimiter$EXPR"$' '"$dict"'" |
| 426 | result=$(egrep -i -e "$delimiter(\([^\)]+\))?.*\<$EXPR\>.*(\([^\)]+\))?$" "$dict") |
||
| 427 | [ $verbose -eq 1 ] && echo >&2 "grep returned: '"$result"'" |
||
| 428 | if [ -n "$result" ]; then |
||
| 429 | if [ $verbose -eq 1 ]; then |
||
| 430 | echo >&2 "Reading expression from recordset (with sed requires only 1 step! :o) |
||
| 431 | Executing: echo $result | sed 's/$delimiter[ ]*[^$delimiter]*//'" |
||
| 15 | PointedEar | 432 | fi |
| 288 | PointedEar | 433 | # result=$(echo $result | sed 's/'$delimiter'[ ]*[^'$delimiter']*//') |
| 434 | result=$(echo $result | sed 's/'$delimiter'.*$//') |
||
| 435 | [ $verbose -eq 1 ] && echo >&2 "sed returned: '"$result"'" |
||
| 15 | PointedEar | 436 | fi |
| 437 | |||
| 438 | # Should return only characters before the delimiter until BOL (expression) |
||
| 439 | } |
||
| 440 | |||
| 288 | PointedEar | 441 | translate() { |
| 15 | PointedEar | 442 | local EXPR="$1" |
| 288 | PointedEar | 443 | if [ $reverse -eq 1 ]; then |
| 444 | translateReverse "$1" |
||
| 445 | return |
||
| 446 | fi |
||
| 447 | [ $verbose -eq 1 ] && echo >&2 "Executing: grep -i -e '^"$EXPR$delimiter"' '"$dict"'" |
||
| 448 | result=$(grep -i -e "^$EXPR$delimiter" "$dict") |
||
| 449 | [ $verbose -eq 1 ] && echo >&2 "grep returned: '"$result"'" |
||
| 450 | if [ -n "$result" ]; then |
||
| 451 | if [ $verbose -eq 1 ]; then |
||
| 452 | echo >&2 "Reading translation from recordset (with sed requires only 1 step! :o) |
||
| 453 | Executing: echo $result | sed 's/[^$delimiter]*$delimiter[ ]*//'" |
||
| 15 | PointedEar | 454 | fi |
| 288 | PointedEar | 455 | result=$(echo $result | sed 's/[^'$delimiter']*'$delimiter'[ ]*//') |
| 456 | [ $verbose -eq 1 ] && echo >&2 "sed returned: '"$result"'" |
||
| 15 | PointedEar | 457 | fi |
| 458 | |||
| 459 | # Should return only characters after the separation character until EOL |
||
| 460 | # (translation) |
||
| 461 | } |
||
| 462 | |||
| 288 | PointedEar | 463 | translate_all() { |
| 464 | local second_pass=0 |
||
| 465 | [ "$1" = "-2" ] && { |
||
| 466 | shift |
||
| 467 | second_pass=1 |
||
| 468 | } |
||
| 469 | TRANSL="" |
||
| 470 | REVERSE_TRANSL="" |
||
| 471 | REVERSE_TRANSL_CAPT="T" |
||
| 472 | REVERSE_TRANSL_on=" (reverse)" |
||
| 473 | REVERSE_TRANSL_CAPT_on="Reverse t" |
||
| 474 | if [ $reverse -eq 1 ]; then |
||
| 475 | REVERSE_TRANSL=$REVERSE_TRANSL_on |
||
| 476 | REVERSE_TRANSL_CAPT=$REVERSE_TRANSL_CAPT_on |
||
| 477 | fi |
||
| 478 | if [ $phrase -eq 1 ] ; then |
||
| 479 | [ $verbose -eq 1 ] && echo "Looking up phrase"$REVERSE_TRANSL": '"$1"'" |
||
| 480 | if [ $zero -eq 0 ]; then |
||
| 481 | TRANSL="$1" |
||
| 482 | [ $brackets -eq 1 ] && TRANSL="["$TRANSL"]" |
||
| 483 | fi |
||
| 484 | translate "$1" |
||
| 485 | if [ -n "$result" ]; then |
||
| 486 | TRANSL=$result |
||
| 487 | [ $verbose -eq 1 ] && echo $REVERSE_TRANSL_CAPT"ranslation: '"$TRANSL"'" |
||
| 488 | else |
||
| 489 | if [ $verbose -eq 1 ]; then |
||
| 490 | if [ $zero -eq 1 ]; then |
||
| 491 | echo $REVERSE_TRANSL_CAPT"ranslation failed (return not translatable tokens as null-string): '"$1"'" |
||
| 492 | else |
||
| 493 | if [ $brackets -eq 1 ]; then |
||
| 494 | echo $ch_sound$REVERSE_TRANSL_CAPT"ranslation failed (enclosing phrase in brackets): '"$1"'" |
||
| 495 | else |
||
| 496 | echo $ch_sound$REVERSE_TRANSL_CAPT"ranslation failed (leave 'as is'): '"$1"'" |
||
| 497 | fi |
||
| 498 | fi |
||
| 499 | fi |
||
| 500 | fi |
||
| 501 | else |
||
| 502 | for word in $@; do |
||
| 503 | if [ $zero -eq 0 ]; then |
||
| 504 | TRANSLWORD="$word" |
||
| 505 | else |
||
| 506 | TRANSLWORD="" |
||
| 507 | fi |
||
| 508 | [ $verbose -eq 1 ] && echo "Looking up word"$REVERSE_TRANSL": "$word |
||
| 509 | translate "$word" |
||
| 510 | if [ -n "$result" ]; then |
||
| 511 | TRANSLWORD=$result |
||
| 512 | elif [ -n "$wsep" ] && [ $second_pass -eq 0 ]; then |
||
| 513 | word=${word//$wsep/ } |
||
| 514 | translate_all -2 $word |
||
| 515 | if [ -n "$result" ]; then |
||
| 516 | TRANSLWORD=$result |
||
| 517 | fi |
||
| 518 | fi |
||
| 519 | [ -n "$result" ] && [ $verbose -eq 1 ] && echo $REVERSE_TRANSL_CAPT"ranslation: '"$TRANSLWORD"'" |
||
| 520 | |||
| 521 | if [ -z "$result" ]; then |
||
| 522 | [ $zero -eq 0 ] && [ $brackets -eq 1 ] && TRANSLWORD="["$TRANSLWORD"]" |
||
| 523 | if [ $verbose -eq 1 ]; then |
||
| 524 | if [ $zero -eq 1 ]; then |
||
| 525 | echo $REVERSE_TRANSL_CAPT"ranslation failed (return not translatable tokens as null-string): "$word |
||
| 526 | else |
||
| 527 | if [ $brackets -eq 1 ]; then |
||
| 528 | echo $REVERSE_TRANSL_CAPT"ranslation failed (enclosing word in brackets): "$word |
||
| 529 | else |
||
| 530 | echo $REVERSE_TRANSL_CAPT"ranslation failed (leave 'as is'): "$word |
||
| 531 | fi |
||
| 532 | fi |
||
| 533 | fi |
||
| 534 | fi |
||
| 535 | TRANSL=$TRANSL" "$TRANSLWORD |
||
| 536 | done |
||
| 537 | fi |
||
| 538 | } |
||
| 539 | |||
| 15 | PointedEar | 540 | # exit codes |
| 541 | ESUCCESS=0 |
||
| 542 | ENO_DICT=1 |
||
| 543 | EDICT_DIR_NOT_FOUND=2 |
||
| 544 | EDICT_NOT_FOUND=3 |
||
| 545 | EDICT_WRONG_FORMAT=4 |
||
| 546 | EDICT_EXPR_CONTAINED=5 |
||
| 547 | EDICT_TEMP_ERROR=6 |
||
| 548 | EDICT_CREATE_ERROR=7 |
||
| 549 | EDICT_DELETE_EXPR_NOT_FOUND=8 |
||
| 550 | EDICT_REMOVE=9 |
||
| 551 | |||
| 552 | # argument flags |
||
| 288 | PointedEar | 553 | dictionary=0 # if 1, -d refers to the dictionary file instead of an entry |
| 15 | PointedEar | 554 | |
| 555 | # option flags - may be replaced by declare -i FLAG |
||
| 288 | PointedEar | 556 | add=0 |
| 557 | addinfo=0 |
||
| 558 | brackets=0 |
||
| 559 | create=0 |
||
| 560 | delete=0 |
||
| 561 | info=0 |
||
| 562 | messages=0 |
||
| 563 | overwrite=0 |
||
| 564 | phrase=0 |
||
| 565 | repair=0 |
||
| 566 | reverse=0 |
||
| 567 | show_version=0 |
||
| 568 | sort=0 |
||
| 569 | sound=0 |
||
| 570 | verbose=0 |
||
| 571 | zero=0 |
||
| 15 | PointedEar | 572 | |
| 288 | PointedEar | 573 | if $(getopt -T >/dev/null 2>&1); [ $? = 4 ]; then |
| 574 | getopt_type=long |
||
| 575 | # echo "getopt(1) type: enhanced" >&2 |
||
| 576 | tmp=$(getopt -o hVbmpoRrSsvzA:a:c:D:d:E:e:i:t: \ |
||
| 577 | -l help,version\ |
||
| 578 | ,brackets,messages,phrase,overwrite,repair,reverse,sort,sound,verbose,zero\ |
||
| 579 | ,add:,addinfo:,dictionary:,delete:word-separator:\ |
||
| 580 | ,about,cmd,dictionary-help,dev,emp,1,x,example \ |
||
| 581 | -n "$appname" \ |
||
| 582 | -- "$@") |
||
| 583 | else |
||
| 584 | getopt_type=short |
||
| 585 | # echo "getopt(1) type: old" >&2 |
||
| 586 | tmp=$(getopt bdhVmpoRrSsvzA:a:c:D:E:e:i: "$@") |
||
| 587 | fi |
||
| 588 | |||
| 589 | getopt_exit_code=$? |
||
| 590 | |||
| 591 | if [ $getopt_exit_code -eq 0 ]; then |
||
| 592 | ## getopt returns error code 0 for successful parsing, 1 if |
||
| 593 | ## getopt(3) returns errors, 2 if it does not understand its |
||
| 594 | ## own parameters, 3 if an internal error occurs like out-of- |
||
| 595 | ## memory, and 4 if it is called with -T. |
||
| 596 | # |
||
| 597 | # Note the quotes around '$tmp': they are essential! |
||
| 598 | # echo $tmp |
||
| 599 | # remove "--" |
||
| 600 | # for i in $tmp; do if [ "$i" != "--" ]; then tmp2="${tmp2} $i"; fi; done |
||
| 601 | eval set -- "$tmp" |
||
| 602 | echo "${extd}New arguments: $*$norm" >&2 |
||
| 603 | |||
| 604 | # First pass to make sure that only help is displayed if wanted |
||
| 605 | for arg in $* |
||
| 606 | do |
||
| 607 | case "$arg" in |
||
| 608 | -h | --help) help; exit $ESUCCESS;; |
||
| 609 | # -V | --version) show_version=1;; |
||
| 610 | --) break;; |
||
| 15 | PointedEar | 611 | esac |
| 612 | done |
||
| 288 | PointedEar | 613 | |
| 614 | # Second pass to deal with the other options |
||
| 615 | while true |
||
| 616 | do |
||
| 15 | PointedEar | 617 | case "$1" in |
| 288 | PointedEar | 618 | # switches |
| 619 | -b | --brackets) brackets=1;; |
||
| 620 | -r | --reverse) reverse=1;; |
||
| 621 | -v | --verbose) verbose=1; title; copyright;; |
||
| 622 | # options |
||
| 623 | -D | --dictionary) shift; dict="$1";; |
||
| 624 | -t | --word-separator) shift; wsep="$1";; |
||
| 625 | --) shift; break;; |
||
| 15 | PointedEar | 626 | esac |
| 288 | PointedEar | 627 | shift |
| 628 | done |
||
| 629 | [ -n "$*" ] && args=$args" $*" |
||
| 630 | [ -z "$args" -a $show_version -eq 0 -a -z "$dict" ] && echo help |
||
| 631 | set -- $args |
||
| 632 | else |
||
| 633 | # echo "getopt exited: $getopt_exit_code |
||
| 634 | # " >&2 |
||
| 635 | if [ $getopt_exit_code -eq 1 ] || [ $getopt_exit_code -eq 2 ]; then |
||
| 636 | echo |
||
| 637 | echo help |
||
| 638 | else |
||
| 639 | exit $getopt_exit_code |
||
| 640 | fi |
||
| 641 | fi |
||
| 15 | PointedEar | 642 | |
| 288 | PointedEar | 643 | if [ -n "$1" ]; then |
| 644 | # retrieve arguments and use default settings from environment variable |
||
| 645 | arguments=$* |
||
| 646 | [ -n "$TRANSLATE_OPTIONS" ] && arguments=$arguments" "$TRANSLATE_OPTIONS |
||
| 647 | |||
| 648 | # check options |
||
| 649 | # for argument in $arguments |
||
| 650 | # do |
||
| 651 | # case "$argument" in |
||
| 652 | # "-m" | "--messages") messages=1;; |
||
| 653 | # "-p" | "--phrase") phrase=1;; |
||
| 654 | # "-r" | "--reverse") reverse=1;; |
||
| 655 | # "-s" | "--sound") sound=1;; |
||
| 656 | # "-z" | "--zero") zero=1;; |
||
| 657 | # "--a" | "--about") copying; exit $ESUCCESS;; |
||
| 658 | # "--c" | "--cmd") cmdHelp; exit $ESUCCESS;; |
||
| 659 | # "--d" | "--dictionary-help") dictHelp; exit $ESUCCESS;; |
||
| 660 | # "--dev" | "--emp") devInfo; exit $ESUCCESS;; |
||
| 661 | # "--1") single_page=1;; |
||
| 662 | # "--x" | "--example") example; exit $ESUCCESS;; |
||
| 663 | # "-h" | "--help") help; exit $ESUCCESS;; |
||
| 664 | # esac |
||
| 665 | # done |
||
| 666 | |||
| 667 | [ $sound -eq 1 ] && ch_sound=$ch_sound_on |
||
| 668 | |||
| 669 | if [ -n "$dict" ]; then |
||
| 670 | # # concatenate dictionary root and given dictionary file |
||
| 671 | # dict="$dict$2" |
||
| 672 | # # check for dictionary commands |
||
| 673 | # case "$1" in |
||
| 674 | # "-d" | "--delete") delete=1 ; dictionary=1 ;; |
||
| 675 | # "-c" | "--create") create1;; |
||
| 676 | # "-i" | "--info") info=1;; |
||
| 677 | # "-S" | "--sort") sort=1;; |
||
| 678 | # "-R" | "--repair") repair=1;; |
||
| 679 | # esac |
||
| 680 | # |
||
| 681 | # case "$3" in |
||
| 682 | # "-a" | "--add") add=1;; |
||
| 683 | # "-A" | "--addinfo") addinfo=1;; |
||
| 684 | # "-d" | "--delete") delete=1;; |
||
| 685 | # "-o" | "--overwrite") overwrite=1;; |
||
| 686 | # esac |
||
| 687 | # |
||
| 688 | # if [ $verbose -eq 1 ]; then |
||
| 689 | # if [ -z "$TRANSLATE_DIR" ]; then |
||
| 690 | # echo "Dictionary root (program directory): '"$appfiledir"'" |
||
| 691 | # else |
||
| 692 | # echo "Dictionary root (TRANSLATE_DIR): '"$TRANSLATE_DIR"'" |
||
| 693 | # fi |
||
| 694 | # echo "Dictionary file: '$2'" |
||
| 695 | # echo "Dictionary file path: '$dict'" |
||
| 696 | # fi |
||
| 697 | # |
||
| 698 | # DEFAULT_INFO="$appname $appver dictionary file created by '$(whoami)' on $(date)" |
||
| 699 | # |
||
| 700 | # [ $create -eq 1 ] && create |
||
| 701 | # |
||
| 702 | if [ -e "$dict" ]; then # if dictionary file exists |
||
| 703 | check_dictionary |
||
| 15 | PointedEar | 704 | |
| 288 | PointedEar | 705 | # [ $addinfo -eq 1 ] && add_info |
| 706 | # [ $info -eq 1 ] && info |
||
| 707 | # [ $add -eq 1 ] && add_translation |
||
| 708 | # [ $overwrite -eq 1 ] && replace_translation |
||
| 709 | # [ $delete -eq 1 ] && delete |
||
| 710 | # [ $sort -eq 1 ] && sort_dictionary |
||
| 711 | # [ $repair -eq 1 ] && repair |
||
| 712 | |||
| 713 | translate_all "$@" |
||
| 714 | |||
| 715 | [ $verbose -eq 1 ] && echo "Overall translation:" |
||
| 716 | [ -n "$TRANSL" ] && echo $TRANSL |
||
| 717 | [ $verbose -eq 1 ] && echo |
||
| 15 | PointedEar | 718 | else |
| 719 | # send errmsg to stderr |
||
| 720 | if [ -n "$TRANSLATE_DIR" ] && [ ! -e "$TRANSLATE_DIR" ]; then |
||
| 288 | PointedEar | 721 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $ch_sound"$appfilename: Unable to locate dictionary root: '"$TRANSLATE_DIR"'" 1>&2 |
| 15 | PointedEar | 722 | else |
| 288 | PointedEar | 723 | if [ $info -eq 0 ] && [ $add -eq 1 ] || [ $overwrite -eq 1 ]; then |
| 724 | if [ $verbose -eq 1 ]; then |
||
| 15 | PointedEar | 725 | echo |
| 288 | PointedEar | 726 | echo $dict": Creating dictionary" |
| 15 | PointedEar | 727 | fi |
| 728 | if [ -n "$4" ]; then |
||
| 729 | if [ -z "$5" ]; then |
||
| 288 | PointedEar | 730 | [ $verbose -eq 1 ] && echo $dict": Adding information: '"$appname" "$appver" dictionary file created by '"$(whoami)"' on "$(date)"'" |
| 731 | echo "#"$delimiter$appname" "$appver" dictionary file created by '"$(whoami)"' on "$(date) &>$dict |
||
| 15 | PointedEar | 732 | else |
| 288 | PointedEar | 733 | [ $verbose -eq 1 ] && echo $dict": Adding information: '"$5"'" |
| 734 | echo "#"$delimiter$5 &>$dict |
||
| 15 | PointedEar | 735 | fi |
| 736 | if [ $? -eq 0 ]; then |
||
| 288 | PointedEar | 737 | if [ $verbose -eq 1 ]; then |
| 738 | echo $dict": Adding expression: '"$1"'" |
||
| 739 | echo $dict": Adding translation: '"$4"'" |
||
| 15 | PointedEar | 740 | fi |
| 288 | PointedEar | 741 | echo $1$delimiter$4 >>$dict |
| 15 | PointedEar | 742 | else |
| 288 | PointedEar | 743 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $ch_sound$appfilename": Unable to create dictionary file: '"$dict"'" |
| 15 | PointedEar | 744 | exit EDICT_CREATE_ERROR |
| 745 | fi |
||
| 746 | else |
||
| 288 | PointedEar | 747 | [ $messages -eq 1 ] || [ $verbose -eq 1 ] && echo $ch_sound$appfilename": No translation given for '"$1"'" |
| 15 | PointedEar | 748 | fi |
| 749 | else |
||
| 288 | PointedEar | 750 | if [ $messages -eq 1 ] || [ $verbose -eq 1 ]; then |
| 751 | echo >&2 "$ch_sound$appfilename: Unable to locate dictionary file: '$dict'" |
||
| 752 | fi |
||
| 15 | PointedEar | 753 | fi |
| 754 | fi |
||
| 288 | PointedEar | 755 | [ $verbose -eq 1 ] && echo |
| 15 | PointedEar | 756 | if [ -n "$TRANSLATE_DIR" ] && [ ! -e "$TRANSLATE_DIR" ]; then |
| 757 | exit $EDICT_DIR_NOT_FOUND |
||
| 758 | else |
||
| 759 | exit $EDICT_NOT_FOUND |
||
| 760 | fi |
||
| 761 | fi |
||
| 762 | else |
||
| 288 | PointedEar | 763 | if [ $messages -eq 1 ] || [ $verbose -eq 1 ]; then |
| 15 | PointedEar | 764 | # send errmsg to stderr |
| 288 | PointedEar | 765 | echo >&2 $ch_sound$appfilename": No dictionary file given" |
| 15 | PointedEar | 766 | fi |
| 288 | PointedEar | 767 | [ $verbose -eq 1 ] && echo |
| 15 | PointedEar | 768 | exit $ENO_DICT |
| 769 | fi |
||
| 770 | else |
||
| 771 | help |
||
| 772 | fi |