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 |