محلی‌سازی

پیوست ‎K‎- محلی‌سازی

محلی سازی یک جنبه غیر مستند Bash است.

یک اسکریپت پوسته محلی‌شده متن خروجی‌اش را به زبان تعیین شده به عنوان منطقه سیستم نمایش می‌دهد. یک کاربر لینوکس در برلین، آلمان، خروجی اسکریپت را به آلمانی دریافت می‌کند، در حالیکه عموزاده‌اش در برلین، مریلند، خروجی همان اسکریپت را به انگلیسی دریافت خواهد نمود.

برای ایجاد اسکریپت محلی‌سازی شده، از الگوی پایین جهت نوشتن پیغام‌ها به کاربر (پیغام‌های خطا، اعلان‌ها، و غیره) استفاده کنید.

#!/bin/bash
# 
#                     اسکریپت توسط ‎Stéphane Chazelas‎ نوشته شده، و به وسیله
#+ ‎Bruno Haible‎ ویرایش گردیده و توسط ‎Alfredo Pironti‎ باگ‌هایش برطرف گردیده.

. gettext.sh

E_CDERROR=65

error()
{
  printf "$@" >&2
  exit $E_CDERROR
}

cd $var || error "`eval_gettext \"Can\'t cd to \\\$var.\"`"
#   backslashهای سه‌تایی (escapeها) در جلوی ‎$var‎ لازم بود
#+ «زیرا ‎eval_gettext‎  جاییکه هنوز مقادیر متغیر جایگزین
#+ نگردیده‌اند، منتظر یک رشته است.» -- توسط ‎Bruno Haible
read -p "`gettext \"Enter the value: \"`" var
# 


#  ------------------------------------------------------------------
#                           ‎Alfredo Pironti‎ توضیح می‌دهد:

#  این اسکریپت برای استفاده نکردن از گرامر ‎$"..."‎ به نفع
#+          گرامر ‎"`gettext \"...\"`"‎ ویرایش گردیده است.
# این خوب است، اما با برنامه ‎localized.sh‎ جدید، فرمان‌های
#+ ‎bash -D filename‎ و ‎bash --dump-po-string filename‎ هیچ
#+  خروجی تولید نخواهند کرد (زیرا آن فرمان‌ها فقط رشته‌های
#+                              ‎$"..."‎ را جستجو می‌کنند)!
# تنها راه استخراج رشته‌ها از فایل جدید استفاده از برنامه
#       ‎xgettext‎ است. اما برنامه xgettext دارای باگ است.

#  توجه کنید که xgettext یک باگ دیگر دارد.
#
#                 
#   به طور صحیح استخراج خواهد شد، اما. . .
#  ‎xgettext -s "I like Bash"‎ ناموفق می‌شود!
#xgettext فقط ‎‎-s‎ را استخراج خواهد نمود چون
#+  فرمان، اولین شناسه بعد از کلمه gettext
#+                      را استخراج می کند.


# کاراکترهای ‎Escape‎:
#
# برای محلی‌سازی جمله‌ای مانند ‎echo -e "Hello\tworld!"‎
#  شما باید از ‎echo -e "`gettext \"Hello\\tworld\"`"‎‎
#+                                     استفاده کنید.
# «کاراکتر escape دوتایی» قبل از t لازم است برای آنکه
#+  gettext رشته‌ای مانند ‎Hello\tworld‎ را جستجو میکند
# به این دلیل است که gettext یک \ لفظی خواهد خواند و
#+یک رشته مانند ‎Bonjour\tmonde‎ بیرون می‌دهد، بنابراین
#+  فرمان echo پیغام را به طور صحیح نمایش خواهد داد.
#
#به سبب باگ xgettext ذکر شده در بالا شما نمی‌توانید از
#+‎echo "`xgettext -e \"Hello\tworld\"`"‎ استفاده کنید



#                  بیایید قطعه زیر را محلی‌سازی کنیم:
#                 
#
#           ابتدا شخص ممکن است این کار را انجام دهد:
#     
#     به این طریق xgettext خوب کار می‌کند، اما برنامه
#+      gettext این ‎-h‎ را به عنوان یک گزینه می‌خواند!
#
#                         یک راه‌حل می‌توانست این باشد
#   
#             به این طریق gettext خوب کار می‌کند، اما
#+      xgettext همچون در بالا «--» را استخراج می‌کند.
#
#راه‌حلی که برای تهیه رشته محلی می‌توانیدبه کار ببرید:
#
#        ما یک ‎\0 (NULL)‎ در ابتدای جمله اضافه کردیم.
#          از این راه gettext به طور صحیح کار می‌کند.
#       علاوه براین، کاراکتر NULL رفتار فرمان echo را
#                                  تغییر نخواهد داد.
#  ------------------------------------------------------------------

bash$ bash -D localized.sh

 "Can't cd to %s."
 "Enter the value: "

این تمام رشته‌های محلی شده را لیست می‌کند(گزینه ‎-D‎ بدون اجرای اسکریپت، تمام رشته‌های نقل‌قولی دوگانه پیشوند شده با یک $ را لیست می‌کند.).

bash$ bash --dump-po-strings localized.sh

 #: a:6
 msgid "Can't cd to %s."
 msgstr ""
 #: a:7
 msgid "Enter the value: "
 msgstr ""

گزینه ‎--dump-po-strings‎ در Bash همانند گزینه ‎-D‎ عمل می‌کند، اما قالب فایل po برنامه ‎gettext‎ را استفاده می‌کند.


‎Bruno Haible‎ اشاره می‌کند:

از ‎gettext-0.12.2‎ به جای ‎bash --dump-po-strings localized.sh‎، استفاده از ‎xgettext -o - localized.sh‎ توصیه می‌شود، چونکه xgettext . . .

‎1‎. فرمان‌های gettext و ‎eval_gettext‎ را می‌فهمد (در حالیکه ‎bash --dump-po-strings‎ تنها ترکیب ‎$"..."‎ نکوهیده‌اش را می‌فهمد)

2. می‌تواند توضیحاتی را که برنامه‌نویس قرار داده تا توسط مترجم خوانده شود، استخراج کند.

این کد پوسته دیگر برای Bash به کار نمی‌رود، همانطور با ‎Bash 1.x‎ و سایر پیاده‌سازی‌های ‎/bin/sh‎ کار می‌کند.

اکنون، با ذکر کردن msgstr یک فایل ‎language.po‎ برای هر زبانی که اسکریپت به آن ترجمه خواهد شد بسازید. ‎Alfredo Pironti‎ مثال زیر را ارایه می‌کند:

fr.po:

#: a:6
msgid "Can't cd to $var."
msgstr "Impossible de se positionner dans le repertoire $var."
#: a:7
msgid "Enter the value: "
msgstr "Entrez la valeur : "

#  رشته با نام‌ متغیرها نسخه‌برداری می‌شود نه با گرامر‎%s‎ مشابه برنامه‌های C
#+  این که برنامه‌نویس نام متغیرهایی به کار ببرد که آن را قابل فهم نماید
#+                                          یک ویژگی بسیار خوشایند است!

سپس، msgfmt را اجرا کنید.

‎msgfmt -o localized.sh.mo fr.po‎

فایل localized.sh.mo به دست آمده را در دایرکتوری ‎/usr/local/share/locale/fr/LC_MESSAGES‎ قرار بدهید، و در ابتدای اسکریپت این سطرها را درج نمایید:

TEXTDOMAINDIR=/usr/local/share/locale
TEXTDOMAIN=localized.sh

اگر کاربری روی یک سیستم فرانسوی اسکریپت را اجرا کند، پیغامها را به زبان فرانسه دریافت خواهد نمود.


با نگارش‌های قدیمی‌تر Bash یا سایر پوسته‌ها، محلی‌سازی به gettext، با استفاده از گزینه ‎-s‎ احتیاج دارد. در این حالت، اسکریپت می‌شود:

#!/bin/bash
# 

E_CDERROR=65

error() {
  local format=$1
  shift
  printf "$(gettext -s "$format")" "$@" >&2
  exit $E_CDERROR
}
cd $var || error "Can't cd to %s." "$var"
read -p "$(gettext -s "Enter the value: ")" var
# ...

لازم است متغیرهای TEXTDOMAIN و TEXTDOMAINDIR تنظیم شده و به محیط export بشوند. این کار باید در داخل خود اسکریپت انجام شود.

---

این پیوست توسط ‎Stéphane Chazelas‎ نوشته شده، با اصلاحات پیشنهاد شده به وسیله ‎Alfredo Pironti‎ و ‎به وسیله ‎Bruno Haible‎ نگهدارنده gettext گنو.