تبدیل PDF فارسی به متن با استفاده از چند ابزار لینوکسی و کمی پایتون

مشکل این‌جاست که در ایمکس فونت سراسری‌ام متن فارسی را به صورت جدا جدا نشان می‌دهد‌. ولی طبق روشی که به آن اشاره کردم‌، کاراکتر‌هایی که در رنج خاصی از کد‌های یونیکد هستند‌، باید با فونت Tahoma (انتخاب من) نمایش داده شوند. اما وقتی فایل خروجی Okular را باز می‌کنم می‌بینم کاراکتر‌ها کاملا درست‌، ولی با فونتی غیر از تاهوما دیده می‌شوند‌. خوب تجربه ثابت کرده که هیچ مشکلی به این راحتی حل نمی‌شود‌. کمی از خروجی را به یک فایل tex تبدیل می‌کنم و خروجی PDFش را بررسی می‌کنم‌. خروجی تقریبا قابل قبول است ولی در بعضی از خطوط کاراکتر‌ها به صورت مبهمی به هم ریخته‌اند‌. از آن‌جایی که خودم برنامهٔ officeای روی سیستم ندارم و وضع اینترنت‌ام هم معلوم است‌، از دوست libreoffice کار قهارم می‌خواهم که فایل خروجی Okular را یک بار دیگر و این‌بار با libreoffice تست کند و ببیند آیا قابل ویرایش است یا نه‌؟ ایمان در جواب می‌گوید که کاراکتر‌ها مثل تصویر عمل می‌کنند و قدرت ویرایش چندانی روی آن‌ها ندارم.(اگر دروغ گفته‌، یقهٔ خودش رو بگیرید ;-))

پس حالا نوبت این است که کمی دست‌هایمان را کثیف‌تر کنیم‌. مساله ساده است‌. فایلی داریم شامل کاراکتر‌هایی که امیدواریم حداقل یونیکد باشند‌، ولی می‌خواهیم آن‌ها را به رنج استانداردی که می‌شناسیم تبدیل کنیم (یک Find & Replace سریع و دوست داشتنی D:)‌. پایتون دوست‌داشتنی چند تابع خیلی‌، خیلی باحال برای کمک به ما در همچین وضعیت‌هایی دارد‌. اولی‌شان ord است‌. کارش این است که یک کاراکتر را به عنوان ورودی بگیرد و در خروجی کد معادلش را چاپ کند‌. دیگری unichr است که تقریبا کاری برعکس کار ord می‌کند‌. یک کد (که فکر می‌کند یونیکد است) در ورودی می‌گیرد‌، و کاراکتر یونیکد معادلش را در خروجی بر می‌گرداند‌.

پس برای شروع کار چند تابع کوچک می‌نویسیم که برای دستکاری فایل کمک‌مان کند‌. تابع اول‌مان‌، چیزی است که در بقیه راه نیازش داریم‌. تابعی که یک فایل را از ورودی بخواند‌:

def read_file(file_name):

the_file = codecs.open(file_name, encoding="utf-8")

return the_file

همین‌طور برای این که خیال‌مان راحت شود‌، تابعی می‌نویسیم که کل محتوای فایل ورودی‌اش را به صورت کاراکتر به کاراکتر (هر کاراکتر در یک خط) چاپ کند:

def show_characters(input_file):

for line in read_file(input_file).readlines():

for char in line:

print char

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

def show_unicode_code(input_file):

for line in read_file(input_file).readlines():

for char in line:

print ord(char)

و سر‌انجام تابعی می‌نویسیم که عکس کار بالا را انجام دهد:

def replace_unicode_char(input_file):

for line in read_file(input_file).readlines():

print unichr(int(line)).encode('utf-8')

مطمئنا می‌شد این توابع را به صورت‌های ساده‌تری هم نوشت‌. ولی خوب اولا سواد من به همین‌قدر می‌رسید‌، دوما هم به نظرم برنامه خوانا‌تر شده‌. برای کسانی که پایتون می‌دانند به نظرم کد‌ها به قدر کافی گویا هستند (آن‌هایی هم که نمی‌دانند کافیست انگلیسی‌شان کفایت کند‌. نا سلامتی هنر پایتون همین است D:). فقط یک نکته در تابع replace_unicode_char باقی می‌ماند و آن هم این که کاراکتر‌های ورودی به صورت رشته هستند و قبل از خوراندنشان به unichar باید تبدیل به عدد (int) شوند‌. همینطور اگر می‌خواهید کاراکتر‌ها را در خروجی چاپ کنید‌، باید به صورت utf-8 کد کنید که خود دستور به قدر کافی گویا هست‌.

من کل این توابع به علاوهٔ یک تابع مهم‌تر از آن‌ها را (که پایین‌تر توضیح‌اش می‌دهم) به صورت یک اسکریپت نوشته‌ام که می‌توانید از این‌جا دریافتش کنید‌. که خوب به عنوان راهنما اضافه کنم که در صورتی که خواستید فایل را به صورت کاراکتر به کاراکتر در خروجی ببینید از دستور زیر بهره بگیرید:

python chrvalidator.py -i INPUT_FILE -c

اگر خواستید که کد‌های یونیکد کاراکتر‌هایش را ببینید از دستور زیر استفاده کنید:

python chrvalidator.py -i INPUT_FILE -u

و اگر هم خواستید که بر عکس کار فوق (تبدیل کد‌های یونیکد به کاراکتر‌های نظیرشان) را انجام دهید‌، به جای ‎-u در دستور فوق از ‎-U استفاده کنید‌. خوب بگذارید به مسالهٔ اصلی‌مان برگردیم‌. برای شروع کار بیایید با دستورات زیر‌، لیستی از کد‌های کاراکتر استفاده شده در فایل‌مان به دست آوریم:

python chrvalidator.py -i ashamloo.txt -u > chrcodes.txt

sort -u chrcodes.txt > uniq.txt

خوب همان‌طور که معلوم است اول از همه کد تمام کاراکتر‌ها را استخراج کردیم‌. و سپس از آن‌جایی که مطمئنیم کاراکتر‌های تکراری زیادی داریم‌، و صد البته مطمئن‌تریم که یک فایل مرتب شده بیشتر به دردمان می‌خورد با استفاده از دستور sort -u کاراکتر‌های تکراری را حذف کرده و فایل را مرتب می‌کنیم‌. حالا همین فایل مرتب شده را دوباره به اسکریپت‌مان می‌خورانیم تا کاراکتر‌های نظیر‌شان را پیدا کنیم:

python chrvalidator.py -i uniq.txt > uniqchr.txt

یک بررسی سرسری‌، نشان‌مان می‌دهد که تنها کاراکتر‌های محدودی از مجموع کاراکتر‌ها نیاز به تعویض دارند‌. دسته‌ای از کل کاراکتر‌ها مربوط به حروف انگلیسی یا اعدادند‌. دسته‌ای دیگر هم در این بین کاراکتر‌های استانداردند. و این وسط ما اکثرا نیاز به تغییر کاراکتر‌هایی موسوم به Arabic Presentation Forms-B داریم‌. خوب همانطور که می‌بینید در بین این کاراکتر‌ها برای نمونه حرف «ب» در سه حالت مختلف «اول‌، وسط‌، آخر» نمایش داده می‌شود که هر کدام کاراکتر مربوط به خود و در نتیجه کد مربوط به خود را دارند‌. برای همین ما تابعی دیگری نیز به صورت زیر به اسکریپت‌مان اضافه می‌کنیم:

for line in read_file(input_file).readlines():

for char in line:

if ord(char) in (64343, 64344, 64345):

char = "پ"

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

sys.stdout.softspace=False

try:

print char.encode("utf-8"),

except UnicodeDecodeError:

print char,

خوب خط اول این مجموعه مربوط به این است که به پایتون بفهمانیم در هنگام چاپ کاراکتر‌ها بین‌شان فاصله نگذارد‌. اگر این مقدار درست باشد‌، کاراکتر‌ها به صورت س ل ا م نوشته می‌شوند، که خوب به درد ما نمی‌خورد‌. همینطور ممکن است به دلیل این که بعضی اوقات در بین کاراکتر‌ها‌، کاراکتر به صورت utf-8 کد شده‌ای پیدا شود و خروجی را بشکند‌، با یک try, except جلوی این اتفاق را می‌گیریم‌، که یک کمی ممکن است گیج کنند باشد‌. در این مورد فقط به من اعتماد داشته باشید که اسکریپت کار می‌کند ;-)

برای پایان کار هم فایل تکست اولیه‌مان را به صورت زیر با اسکریپت حاضرمان ویرایش می‌کنیم:

python chrvalidator.py -i ashamloo.txt > validashamloo.txt

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

پی‌نوشت: Okular از قرار‌، قادر نیست PDF‌هایی که رمزگذاری شده‌اند را باز کند (خودم امتحان نکردم) در آن صورت یک ابزار پایتونی برای این کار وجود دارد که در آینده در موردش می‌نویسم‌. تا این‌جای کار‌، خروجی‌های این تابع زیاد با روش ذکر شده همخوانی ندارد‌، پس باید به فکر دستکاری‌اش باشم‌. اسم این تابع هم در صورتی که دل‌تان می‌خواهد کشفش کنید pdfminer است.

وقتی دزدی می‌کن(م،ن،ید)

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

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

ماشالله نیست که بیشعور‌های سطح بالایمان کم اینترنت‌مان را با بهانهٔ این که کشور‌های غربی هم آن را محدود می‌کنند محدود کرده‌اند (کسی هم نیست بگوید آن‌ها اینترنت را با کیفیتی غیر قابل مقایسه با آنی که شما ارائه می‌دهید و با قیمتی خیلی‌، خیلی‌، خیلی پایین‌تر از چیزی که شما به مردم تحمیل می‌کنید ارائه می‌دهند‌، چرا آن‌وقت شما چیز‌های بدش رو بهانه قرار می‌دهید‌) و اصلا بیشعور‌های سطح بالای دنیوی (یکیش همین دار و دستهٔ گوگل) باقی جاهای باقی مانده را از دستمان در نیاورده‌اند، این شرکت‌های به قولی غیر دولتی که از میان همین مردم در آمده‌اند‌، در آن زخم سر باز کرده مثل چی نمک می‌ریزند و کیف می‌کنند‌!

نمی‌دانم این تبلیغات اخیر پارس آنلاین را در سایتش دیده‌اید یا نه‌. این‌جاها را ببینید:

این سرویس مناسب چه کسانی است؟

کاربران پرمصرفی که مصرف گیگ بسیار بالایی دارند. قاعدتاً برای این گروه از کاربران به لحاظ مالی مقرون به صرفه نخواهد بود تا پکیج های حجمی محدود به همراه گیگ اضافه را خریداری نمایند. کاربرانی که نیاز به اطمینان خاطر از بابت اتصال دائمی به اینترنت و عدم قطعی اینترنت خود دارند و مایلند در تمام شبانه روز آنلاین باشند. برای این دسته از کاربران نیز بهینه نیست که پکیج های حجمی محدود به همراه گیگ اضافه خریداری نمایند.

یا خصوصا این بخش را:

کاربرانی که پکیج های نامحدود را خریداری می نمایند مطمئن باشند همواره سرعت اسمی پکیج خود را دریافت می نمایند و هیچ نگرانی از این بابت وجود ندارد و می توانند بدون محدودیت حجمی از اینترنت پرسرعت استفاده نمایند.

مای از همه جا بی‌خبر‌، که دیگر داشت دردش خیلی زیاد می‌شد که هر ماه یک پکیج چهار گیگی بخریم و در صورت کم آمدنش که عموما همان ۱۰ روز اول می‌آمد‌، پول یک گیگ حجم را ۵۰۰۰ تومانی واریز کنیم (خداییش درد دارد) به امید این که یک ماه اینترنت با سرعت ۱۲۸ کیلوبایت (دانلود) و بدون استرس تمام شدن حجم داشته باشیم‌، خر شدیم (هر چه گشتم عبارت با مسماتری پیدا نکردم) و به مبلغ ۲۸۵۰۰ تومان‌، یعنی ۲۷۰۰۰ تومان هزینهٔ سرویس + ۱۵۰۰ تومان مالیات (یعنی حتی مالیات هم دادم) یک دانه‌اش را خریدم‌. تا دو هفتهٔ اول خوب بود‌. واقعا خوب بود‌. سرعت گاها تا ۱۳۰ کیلوبایت هم می‌رسید‌. ولی این وضعیت تا زمانی ادامه داشت که حجم دانلودی‌ام زیر هشت گیگابایت بود‌.

الان که این متن را می‌نویسم یک هفته‌ای می‌شود که سرعت دانلودم به زور از ۱۳، ۱۴ کیلوبایت فراتر می‌رود‌. تازه آن هم در صورتی که بتوانم کانکت شوم‌. خواستم بگویم که همچین یاد حرف آن بندهٔ خدایی افتادم که گفته بود:

اگر همین فردا کل کابینهٔ دولت را یکجا بردارند و همتایان سوئیسی‌شان را بنشانند سر جایشان‌، یک هفتهٔ بعد باز هم وضع همین است.

هر چه هم سعی کردم نفهمیدم این حرف را از کدام بندهٔ خدا خوانده‌ام‌.

داستان…

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

این مقدمهٔ بی‌نمک بلند را گفتم تا به این‌جا برسم که خوشبختانه جدای از اینترنت بی‌مزه‌مان که شده میدان ارابه کشی یک سری فرماندهٔ در حسرت جنگ مانده و باقی عرصه‌های قلم و هنر و سخن‌مان هم شده ضمیمهٔ دستمالی رهبران آن فرماندهان ذکر شده‌، گاها آدم چیز‌هایی می‌بیند که جدا امیدوار کننده است‌.

عکس روی جلد نسخهٔ آبان ماه مجلهٔ داستان عکس روی جلد نسخهٔ آبان ماه مجلهٔ داستان

چند ماه پیش (دقیقا تیر ماه) بود که سر گذرم از یک مطبوعاتی‌، چشمم به مجله‌ای خوشدست و جمع و جور به اسم «‌داستان‌»+ افتاد که به بهانهٔ هدیه برای خواهرم یک نسخه‌اش را خریدم‌. مجله زیر مجموعهٔ مجلات همشهری است.

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

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

مخلص کلام این که حیفم آمد همچین مجله‌ای را بخوانم و تجربهٔ شیرین خواندنش را با شما در میان نگذارم‌.

*: قصهٔ آن جام کمی طول و دراز است‌. خلاصه‌اش این که یکی دوست دارد با سیگار کتاب بخواند‌. یکی با ماگ قهوه‌. یکی هم با جام آب انگور گندیده ;-)

عشق بازی با ترمینال لینوکس‌ (urxvt, رنگ‌آمیزی و کانفیگش)

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

قبلا در مورد Terminator پستی داشتم‌ (+). تا همین چند روز پیش هم از آن استفاده می‌کردم‌. واقعا معرکه بود‌. همه چیز را آماده داشت و تا جای ممکن کمکت می‌کرد‌. اما چند روزی است که urxvt و قابلیت‌هایش نظرم را جلب کرده‌. این است که ضمن جایگزین کردنش با Terminator چیز‌هایی از آن یاد گرفتم که می‌خواهم در این پست در موردش صحبت کنم‌.

رنگ‌آمیزی urxvt و Terminator

اول این که حیفم آمد این روش تغییر رنگ Terminator را که یاد گرفته‌ام باز‌گو نکنم‌. این است که در این پست با یک تیر دو نشان می‌زنم‌.

دوم هم این که شاید این کار را بیهوده بدانید‌. ولی قرار است که مدت زیادی در این ترمینال کار کنیم و به نظرم حیاتی‌ترین کاری که باید انجام دهیم‌، قابل تحمل کردن رنگ‌بندی‌اش است ;-)

ترمینال‌هایی مثل urxvt و Terminator سر جمع ۱۸ رنگ را برای رنگ کردن خروجی‌شان استفاده می‌کنند‌. رنگ پس‌زمینه‌، رنگ اصلی خروجی‌، هشت رنگ تیره و هشت رنگ روشن‌. سر هم کردن این همه رنگ‌، جوری که بتوان از ترکیب‌شان استفاده کرد‌، جدا کار طاقت‌فرسایی است‌. حقیقتش من یکی که هرگز موفق نشدم به صورت دستی این کار را انجام دهم‌. همین سختی هم باعث شده که 4bit به وجود بیاید‌. طرز کارش خیلی سر راست و ساده است‌. پالت رنگ‌تان را ایجاد کنید‌، و وقتی از خروجی خوشتان آمد روی Get scheme کلیک کنید (‌رنگ‌های مورد استفاده من). همان‌طور که می‌بینید‌، برای اکثر ترمینال‌ها یک خروجی حاضر کرده‌‌، جز Terminator. خوب اگر می‌خواهید مثل من urxvt را کانفیگ کنید‌، کد مربوطه‌اش را بگیرید و بسته به تنظیمات توزیع‌تان آن را در ‎.Xdefaults یا ‎.Xresources وارد کنید‌ (برای فهمیدن چند و چون ماجرا man urxvt توضیحات خوبی داده).

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

python xterm_to_terminator.py color_scheme_file

خروجی را کپی کنید و در مسیر ‎.config/terminator/config جایگزین خطوط مربوطه کنید‌. (همه چیز سر راست است فکر کنم ;-))

یک نکته هم اضافه کنم‌. 4bit رنگ‌های خروجی‌اش را به صورت colorN یا background ارائه می‌دهد‌. در حالت کلی خوب است‌. ولی ممکن است شما دوست نداشته باشید تمام نرم‌افزار‌هایی که تنظیم رنگ‌شان را از منابع X می‌خوانند همین رنگی شود‌. این است که می‌توانید با تبدیل متغیر‌ها به صورت URxvtcolorN یا URxvtbackground آن‌ها را به urxvt محدود کنید ;-)

رنگ آمیزی تمام شد‌.

کانفیگ urxvt

urxvt عالی است‌. امکانات فوق‌العاده‌ای دارد‌. ولی تنظیمات پیش‌فرضش حال به هم زن است‌! یک ترمینال بی روح سفید نافرم‌! مشکل سفیدی‌اش که حل شد‌. ولی هنوز کار دارد‌.

font:

نویسندهٔ اصلی urxvt قبلا از mlterm استفاده می‌کرد‌. اما همیشه مجبور بود برای دیدن کاراکتر‌های ژاپنی (یا شایدم چینی) و لاتین‌، بین فونت‌های مختلف سوئیچ کند‌. چون هیچ فونت مناسبی پیدا نمی‌کرد که تمام کاراکتر‌های مورد نیازش را داشته باشد‌. همین می‌شود که کلافه از این که چرا توسعه دهنده‌ها فکر می‌کنند تمام کاراکتر‌های unicode را می‌توان با یک فونت نشان داد‌، دست به انگولک rxvt می‌زند و علاوه بر قابلیت یونیکد‌، پستیبانی از چند فونت را هم به آن اضافه می‌کند. برای تغییر فونت می‌توانید مثل من خط زیر را به ‎.Xdefaults اضافه کنید:

URxvt*font: xft:Terminus:pixelsize=12

و یا اگر فکر می‌کنید فونت انتخابی‌تان به حد کافی کامل نیست‌، از ویژگی چند فونتی به صورت زیر استفاده کنید:

URxvt.font: 9x15bold,

-misc-fixed-bold-r-normal--15-140-75-75-c-90-iso10646-1,

-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1,

[codeset=JISX0208]xft:Kochi Gothic:antialias=false,

xft:Code2000:antialias=false

یک قابلیت جالب دیگر urxvt این است که می‌توان تعیین کرد که نوشته‌های Bold, Italic و یا Underline با فونت‌های متفاوتی نشان داده شوند‌. من خودم این‌ها را تنظیم نکردم (حقیقتش وقت نکردم هنوز) ولی می‌توانید در manpage به دنبال کانفیگ‌های boldFont, italicFont, boldItalicFont و … بگردید‌.

تنظیم رابط:

اسکرول‌بار به نظرم چیز زیادی‌ای است‌. ضمن این که خود urxvt میانبر‌هایی برای پیمایش متن دارد‌. همچنین urxvt این قابلیت را دارد که بهش بفهمانیم که چند خط از خروجی ترمینال را برای‌مان ذخیره کند تا بتوانیم آن را پیمایش کنیم‌.

URxvt*scrollBar: False

URxvt*scrollTtyOutput: False

URxvt*scrollTtyKeypress: True

URxvt*secondaryScroll: True

URxvt*saveLines: 8000

URxvt*letterSpace: 0

URxvt*cursorBlink: True

URxvt*cursorUnderline: True

پنج خط اول این تنظیمات که باید در فایل منبع X‌تان ذخیره کنید مربوط به چیز‌هایی است که ذکر‌شان رفت‌. ممکن است با توجه به شرایط نصب و کانفیگ‌تان احساس کنید که کاراکتر‌های متن در urxvt کمی فشرده است‌. تنظیم leterSpace می‌تواند در این رابطه کمک کند‌. اعدادی در بازهٔ اعداد صحیح می‌تواند برای کنترل این آپشن استفاده شود‌.

همینطور به طور پیش‌فرض نشانکر Urxvt ثابت است و من دوست دارد که بی‌حیائی کند و چشمک بزند‌. و البته به جای آن مربع همیشگی کاراکتر _ را ترجیح می‌دهم‌. دو خط آخر این تنظیمات مربوط به همین علایق است ;-)

Modifier:

کلید Modifier همان کلیدی است که برای زدن کاراکتر‌های ترکیبی (کنترل) urxvt مورد استفاده قرار می‌گیرد‌. این کلید قرار است به طور پیش‌فرض Alt باشد ولی نمی‌دانم چرا اصلا هیچ‌کدام از Modifier ها برای من کار نمی‌کرد‌. اگر شما هم در چنین وضعیتی هستید‌، با استفاده از خط زیر این ویژگی را تعریف کنید:

URxvt*modifier: alt
افزونه‌ها:

یکی از قابلیت‌های خوشگل urxvt افزونه‌های perl‌اش است‌. افزونه‌هایی که قابلیت‌های گاها غیرقابل باوری به آن اضافه می‌کنند‌. فعلا ما تنها به باورپذیر‌هایش کار داریم‌. و اما از آن‌جایی که افزونه‌هایی که به طور پیش‌فرض همراه urxvt هستند کفاف نیازمان را نمی‌دهند‌، یک چند‌تایی هم از این‌جا می‌گیریم‌.

فایل‌های این افزونه‌ها را دریافت کنید‌، و در مسیر ‎/usr/lib/urxvt/perl (یا اگر ۶۴ بیتی هستید lib64) قرار دهید‌. حالا خط زیر را برای وارد کردن‌شان به urxvt اضافه کنید:

URxvt.perl-ext-common : default,matcher,tabbed,keyboard-select,url-select,clipboard

چند‌تای اول همراه خود i3 هستند که من آن tabbed را خیلی دوست دارم‌. می‌گذارد urxvt برای‌تان تب کند ;-) شوخی کردم‌، همان تب‌بندی خودمان است‌. برای این که به طور به درد بخوری کانفیگش کرده باشیم‌، خطوط زیر را به تنظیمات اضافه کنید (اعداد جلویشان همان شماره رنگ‌ها هستند):

URxvt.tabbed.tabbar-fg: 5

URxvt.tabbed.tabbar-bg: 0

URxvt.tabbed.tab-fg: 14

URxvt.tabbed.tab-bg: 0

فوق‌العاده است‌. با Shift و فلش پایین می‌توانید تب جدید اضافه کنید‌. با Shift و فلش‌های دو طرف به این‌ور آن‌ور بروید و با Ctrl+D تب را ببندید‌. کلید‌های بیشترش را از ویکی آرچ یاد بگیرید ;-)

اما سه افزونهٔ آخر آن‌هایی هستند که urxvt-perls برایمان ساخته‌. حقیقتش این است که این‌ها فقط یه سری تابع ساده به زبان perlاند‌. پس باید غیر از فعال کردن‌شان‌، کلید‌های میانبری برای اجرای‌شان تعریف کنیم‌.

تعریف کلید میانبر:

مثل همه جای دیگر‌، کار بسیار آسانی است‌. کلید متا یا Modifier‌مان را که تعریف کردیم‌، حالا کافیست که با سینتکس:

keysym.: Action

یک کلید میانبر تعریف کنیم‌. خوب بگذارید کمی مثال‌های واقعی‌تری بزنیم‌. افزونهٔ اول‌مان keyboard-select است که قابلیت‌های پیمایش ماهی در ترمینال به ما می‌دهد‌. تقریبا از ماوس بی‌نیازمان می‌کند. خطوط زیر را برای کانفیگش اضافه کنید:

URxvt.keysym.M-Escape: perl:keyboard-select:activate

URxvt.keysym.M-s: perl:keyboard-select:search

حالا گفتیم با M-Escape یا همان Alt+Esc تابع پرل به نام keyboard-select را فعال کن. این کلید‌ها کمک می‌کند که با کلید‌های میانبر vim درون متن ترمینال پیمایش کنید‌. همینطور M-s قابلیت سرچ درون متن ترمینال را از تابع keyboard-select رو نویس می‌کند‌. (این قابلیت به صورت پیش‌فرض در urxvt وجود دارد ولی این یکی بهتر است ;-))

افزونهٔ بعدی url-select است‌. خیلی پیش می‌آید که می‌خواهیم تنها روی یک url از توی ترمینال کلیک کنیم‌. خوبیت ندارد که تابع Search را برای این کار انتخاب کنیم‌. این است که به صورت زیر این افزونه را فعال می‌کنیم:

URxvt.keysym.M-u: perl:url-select:select_next

URxvt.url-select.autocopy: True

URvxt.url-select.button: 2

URxvt.url-select.launcher: firefox

URxvt.url-select.underline: True

فکر کنم تنظیمات به قدر کافی گویا هستند‌. پس دیگر زیاد شلوغش نمی‌کنم!

و افزونهٔ آخر clipboard که یک کمی درد‌سرش بیشتر است‌. این تابع به طور پیش‌فرض از xsel برای کپی و پیست متن استفاده می‌کند‌. (البته در ادامه می‌گویم که اگر خواستید چطور تغییرش دهید‌). این برنامه به دستور xsel -ib متن را کپی می‌کند (می‌توانید این دستور را تایپ کنید‌، انتر کنید‌، متن مورد نظر‌تان را تایپ کنید و Ctrl+D بزنید) و با xsel -ob متن را پیست کنید‌. به نظرم فکر خوبی است که این برنامه را نصب کنید (ضمن این که باقی برنامه‌ها هم عکس‌العمل خوبی بعد از نصب این برنامه نشان دادند ;-)) و بعد با خطوط زیر این افزونه را تنظیم کنید:

URxvt.keysym.M-c: perl:clipboard:copy

URxvt.keysym.M-v: perl:clipboard:paste

URxvt.keysym.M-C-v: perl:clipboard:paste_escaped

جای Ctrl+c و یا غیره ما از همان M استفاده کردیم‌ (آن هم از روی کالیبر بالایمان ;-)) ولی اگر دوست دارید که همان کلید‌های همیشگی را داشته باشید‌، به جای M حرف C بزرگ را تایپ کنید!

اما اگر حال نصب xsel را ندارید و دستور کپی دیگری مد نظرتان است‌، می‌توانید آن دستور‌ها را به صورت زیر جایگزین xsel کنید:

URxvt.clipboard.copycmd: Command

URxvt.clipboard.pastecmd: Command

خوب تا همین اندازه فکر کنم برای شروع کار کافی باشد‌. فایل کانفیگ کامل من را می‌توانید در این لینک ببینید‌. اما هنوز هم نکاتی هست که ذکرشان خالی از لطف نیست:

نکات اضافه:
  • یکی از قابلیت‌های خیلی به درد بخور urxvt این است که می‌توان به صورت daemon اجرایش کرد‌. یعنی یک بار هستهٔ daemon را اجرا می‌کنید و پس از آن ترمینال‌های مختلف را روی همان هستهٔ اصلی به صورت کلاینت صدا می‌کنید‌. مزیت این کار سرعت خیلی بالای فراخوانی ترمینال‌هاست‌. ولی خوب یک مشکل هم دارد‌. اگر یک ترمینال کرش کند‌، کل ترمینال‌ها به فنا می‌روند‌، ولی خوب مگر تا به حال چند بار ترمینال زیر دست‌تان کرش کرده؟ این است که روی i3 با هر بار لود مدیر پنجره urxvtd را برای ران شدن daemon صدا می‌کنم و هر وقت نیاز به ترمینال داشتم urxvtc را اجرا می‌کنم ;-) توصیه می‌کنم که این بخش از ویکی آرچ را در این رابطه بخوانید‌. اسکریپت به درد بخوری است‌!
  • ممکن است بعد از بعد از هر بار تغییر Xdefaults فایل کانفیگ به درستی لود نشود‌، این است که می‌توانید از دستور زیر برای بارگذاری دوباره‌اش استفاده کنید:
xrdb -merge ~/.Xdefaults
  • قبلا گفتم که می‌توان برای حالت‌های Bold, Italic و … فونت‌های مختلفی تعیین کرد‌. حالا اضافه می‌کنم که رنگ‌های این فونت‌ها نیز قابل تغییر است در manpage به دنبال آپشن‌هایی مثل colorBD, colorIT, colorUL و … بگردید‌.
  • مسیر پلاگین‌های perl برای urxvt به صورت پیش‌فرض ‎/usr/lib/urxvt/perl است‌. اما ممکن است دوست نداشته باشید که این افزونه‌ها به صورت systemwide در دسترس باشد‌. یا شاید شما دسترسی نوشتن در این آدرس را ندارید‌. با آپشن زیر می‌توانید مسیر جدیدی برای این افزونه‌ها اضافه کنید:
perl-lib: PATH
  • گاها ممکن است نیاز داشته باشید که ترمینال‌های‌تان را به صورت login shell ران کنید‌. که خوب مزیت‌های خودش را دارد‌. با اپشن loginShell: True می‌توانید به این عمل دست یابید‌.
  • نکتهٔ آخر و خیلی مهم هم این که شما می‌توانید تمام این امکاناتی که بحثشان رفت را تنها در زمان فراخوانی urxvt اعمال کنید‌. تمام آپشن‌های ذکر شده‌، یک آرگومان خط فرمان هم دارند که کار همین‌ها را انجام می‌دهد‌.

ترمینال dropdown (مثل quake) در مدیر پنجرهٔ i3

گذشت تا امروز که دیدم Arch باز‌ها یک کلکی سوار کرده‌اند و توانسته‌اند urxvt را به صورت quake در OpenBox (یک راهنمای عالی برای کار با این مدیرپنجره را دوست خوبم ایمان در ویکی لینوکس ریویو فراهم کرده) اجرا کنند‌. بماند که کلی ژانگولر بازی در آوردم که پیاده‌اش کنم و اخرش نتوانستم در i3 اجرایش کنم‌.

این شد که طبق معمول دست به دامن i3 باز‌ها شدم و با کمال تعجب دیدم که نوشابه در کوزه و ما دنبال آب می‌گردیم‌! قضیه از این قرار است که i3 با تمام کوچکی‌اش یک قابلیت خیلی ماه دارد به اسم scratchpad. که یعنی می‌توانید با آن هر موقع خواستید هر پنجره‌ای را غیب کنید و هر وقت دیگر خواستید ظاهر کنید‌. این است که برای مثال ما که مصادف شده با مهاجرتم به ترمینال urxvt‌، این چنین i3 را کانفیگ می‌کنیم تا به نتیجهٔ دلخواه‌مان برسیم:

for_window [instance="dropdown_urxvt"] move to scratchpad, border 1pixel

for_window [instance="dropdown_urxvt"] focus; resize grow width 300px

bindsym F12 [instance="dropdown_urxvt"] scratchpad show, move position 110px 0px

آن بخش instance را داشته باشید تا در آخر کار بهش برگردیم‌. در خط اول می‌گوییم که اگر پنجرهٔ مورد نظرمان صدا شد‌، بفرستش به scratchpad و کلا آن بردارش را (که دور تمام پنجره‌ها در i3 وجود دارد) را حذف کن. در خط دوم هم همان پنجرهٔ مورد نظر را کمی عریض‌تر می‌کنیم‌. و در آخر کار هم در خط سوم می‌گوییم که هر وقت کلید F12 را زدیم‌، پنجرهٔ موردنظرمان را که برده‌ای آن پشت مشت‌ها‌، در فلان مختصات صفحه ظاهر کن‌.

در مورد این توضیحات بالا می‌توانید به راحتی در راهنمای کاربران i3 اطلاعات به درد بخوری پیدا کنید‌. و اما می‌ماند نکات کنکوری:

تا این‌جای کار‌، ما گفتیم که اگه پنجرهٔ مورد نظرمان را دیدی‌، چه کار کن‌. اما حالا مسئله این‌جاست که این پنجره را چطور ایجاد کنیم‌. طوری که منحصر به فرد باشد‌. هر چه باشد نمی‌خواهم هر بار که urxvt را صدا زدم همان بالا باز شود‌. گاهی به یک ترمینال گنده نیاز دارم‌!

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

این است که اول از همه ترتیبی می‌دهیم که با باز شده i3 به صورت خودکار این daemon هم اجرا شود:

exec urxvtd

حالا هم نوبت به ساخت پنجره‌مان می‌رسد‌. ظاهر خوشی ندارد که هر بار به صورت دستی بازش کنم‌، چون بلافاصله غیب می‌شود و باید با F12 صدایش کرد‌. این است که این را هم می‌گذارم خود i3 موقع بالا آمدن اجرا کند‌. به هر حال ما که یک نمونه از این کلاینت بیشتر نمی‌خواهیم:

exec urxvtc -name dropdown_urxvt

ها‌، همین‌جاست که به i3 می‌فهمانیم که کدام پنجره منظورمان است‌. حالا کافیست که یک بار i3 را ریست کنیم و F12 را بزنیم‌. نتیجهٔ کار عالیست:

dropdown urxvt in i3

پی‌نوشت: درست است که طی حل این ماجرا راه‌های عجیب و غریبی را غیر از آسان‌ترین راهی که جلوی رویم بود انتخاب کردم‌، ولی چیز‌های جالبی یاد گرفتم که در پست‌های آینده در موردشان خواهم گفت ;-)

پی‌نوشت۲: ممکن است روی نسخهٔ استیبل i3 (در این تاریخ) با دستور focus که در این آموزش استفاده شده مشکل دارین‌. آخرین نسخهٔ git این مشکل را بر طرف کرده‌!