نمیدانم برای شما هم مثل من پیش آمده که دلتان بخواهد کل لینکهای جالبی که فکر میکنید ممکن است در آینده به دردتان بخورد را همراه با نکاتی که در وب پیدا میکنید در یک فایل متنی ساده و به دور از هر پیچیدگی خاصی روی سیستم خود داشته باشید و هر وقت دلتان خواست با ابزارهای جستجوی عجیب و غریبتان پی موارد مورد نظر، شخمش بزنید یا نه؟
حقیقتش از همان اوایلش که وبگردی یاد گرفتم، تمام فهم و درکم از بوکمارک به همین یک پاراگراف بالا خلاصه میشد. این بود که ابزارهایی مثل Delicious یا Diigo برایم زیادی پیچیده و دور از دسترس (اینترنت ایرانی است دیگر، سر بزنگاه خوابش میبرد D:) به نظر میرسیدند.
این بود که با کمی جستجو و انگول کردن ایمکس و چند تا ابزار دیگر مورد استفادهام، فعلا به نتیجهٔ قابل قبولی رسیدهام که در این پست قصد بازگو کردنش را دارم.
ایده
ایده ساده است. عموما دو نوع لینک در وب پیدا میشود که باید ذخیره کنم. اولی مطالبی که جالب به نظر میرسند ولی فعلا وقت مطالعهشان را ندارم و دومی لینک/متنهایی که کاربردیاند و به احتمال زیاد در آینده باید ازشان بهره بگیرم. این دستهٔ دوم حیاتیترند و باید در جای مطمئنی و ترجیحا با قابلیتهای جستجوی درست درمان ذخیره شوند. خصوصا این که در آینده ممکن است خیلی خیلی بزرگ و حجیم شود
ویرایش: برای درک بهتر موضوع سعی کردم یه ویدئو از نحوهٔ کار این ایده آماده کنم براتون که اینجا میبینین:
معرفی کوتاه org-mode ایمکس
احتمالش را نمیدهم که ایمکس را نشناسید و الان در حال خواندن این وبلاگ باشید. اما با وجود شناختن ایمکس، هنوز هم این احتمال وجود دارد که یکی از کاربردیترین و در عین حال سادهترین افزونههایش را نشناسید. org-mode به گفتهٔ سایت اصلیاش این گونه معرفی میشود:
org-mode ابزاری است برای نتبرداری، نگهداری لیست کارهایی که باید انجام دهید، برنامهریزی برای پروژهها و نوشتن مستنداتی با یک سیستم متنی ساده، سریع و تعصیر گذار.
برای فعال سازی حداقلی org-mode به کد زیر درون .emacsتان نیاز دارید:
(setq org-dir "/home/shahin/Workspace/org/")
(setq org-default-notes-file org-dir)
(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-cc" 'org-capture)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cb" 'org-iswitchb)
(setq org-agenda-files (quote ("/home/shahin/Workspace/org/journal.org")))
که در واقع کار اصلیاش معرفی دایرکتوری پیشفرض فایلهای org و تعریف چند کلید میانبر به توابع اصلی این سیستم و معرفی یک agenda-files است که این آخری وصفش از حوصلهٔ این مقاله خارج است و احتمالا در آینده به آن خواهم پرداخت.
معرفی کوتاه org-capture ایمکس
در رابطه با org-mode گفتیم و در حین تعریف کلیدهای میانبرش، به تابع org-capture بر خوردیم. وظیفهٔ این تابع این است که کمکتان کند وقتی در حین کار روی پروژهای ایدهای به ذهنتان زد که حیفتان میآمد جایی یادداشتش نکنید، قادر باشید در کمترین زمان ممکن و با حداقل مزاحمت، ایده را با یک کلید میانبر و یک قالب کاملا مرتب ذخیره کنید. نمونهای از قالبهایی که در حال حاضر درون .emacs من میتوانید پیدا کنید به شرح زیر است.
; Define capture templates:
(setq org-capture-templates
'(("t" "Todo" entry (file+headline (concat org-dir "journal.org") "Tasks")
"\* TODO %?\n%U%i\n")
("m" "Movie" entry (file+headline (concat org-dir "journal.org") "Movie")
"\* TODO [[%^{URL}][%^{Movie name}]] %^{Year}")
("M" "Music" entry (file+headline (concat org-dir "journal.org") "Music")
"\* TODO %^{Artist} %^{Album name}")
("f" "Flashcard" plain (file (concat org-dir "flashcard.org"))
"\* %^{Topic}\t\t\t\t:drill:\n%^{Question}\n\*\* Answer\n%^{Answer}")
("w" "Bookmark web link/note" entry (file+headline (concat org-dir "bookmarks.org") "Links")
"\* %c\t%^g i\n Description: %i \n Source: %U"
:empty-lines 1)))
حالا هر وقت C-c c را فشار دهم، با همچین منویی مواجه میشوم:
select a capture template
[t] Todo
[m] Movie
[M] Music
[f] Flashcard
[w] Bookmark web link/note
که میتوانم با انتخاب هر کدام از گزینهها و پرکردن فرم تولید شده، اطلاعات مربوطه را درون یکی از فایلهای journal.org، flashcard.org و یا bookmark.org بسته به نیازم ذخیره کنم. در رابطه به گزینههای اول این منو هم امروز قرار نیست صحبت کنیم. بحث اصلی ما گزینهٔ [w] است که قالبی برای ذخیرهٔ لینک، متن و تگهای Bookmarkهایمان دارد.
معرفی کوتاه org-protocol در ایمکس
ایمکس به خودی خود، این قابلیت را دارد که به صورت سرور اجرا شود. اجرای به صورت سرور ایمکس، این امکان را برایمان فراهم میکند که برای مثال، یک فایل را از درون ترمینال، داخل یک نشست اجرا شدهٔ ایمکس، بدون هیچ واسط اضافهای اجرا کنیم. برای اجرای ایمکس به صورت سرور دو راه داریم. اولی استفاده از دستور خط فرمانی:
emacs --daemon
و بعدی اضافه کردن خط زیر به درون تنظیمات .emacs:
(server-start)
که من به دلایل مختلفی از جمله به هم ریختن تنظیمات فونت ایمکس در صورت استفاده از emacs --daemon که دلیلش را هنوز نمیدانم، و سر راست بودن روش دوم، از آن استفاده میکنم. حالا هر وقت بخواهم فایلی را از ترمینال درون نشست حاضر اجرا کنم، از دستور زیر استفاده میکنم:
emacsclient FILENAME
حالا، از آنجایی که فرقهٔ org بازهای ایمکس، خلاقیتشان اصلا ته نمیکشد، یک بابایی فکر کرده ممکن است که ما دلمان بخواهد یک راهی پیدا شود که بشود از ترمینال، دستورات org مثلا همین org-capture را وارد کنیم و حالش را ببریم. این است که org-protocol سر و کلهاش پیدا میشود. برای فعال سازی این یکی هم کافیست خط زیر را به .emacsتان اضافه کنید:
(require 'org-protocol)
معرفی xdg-open که هیچ ربطی به ایمکس ندارد
کار این برنامه خیلی سر راست است. میگردد و پیدا میکند که چطور یک فایل باید اجرا شود. حتما این مشکل برایتان یپش آمده که بعد از دانلود یک فایل توسط firefox روی عکس فایل در دانلود منیجر کلیک کنید و فایرفاکس خنگولانه بپرسد که نمیدانم چطور فایل را اجرا کنم. در اینجور مواقع بهتر است که از مسیر احتمالا /usr/bin دستور xdg-open را به خوردش بدهید. همچنین این خانواده xdg یک دستور xdg-mime هم دارد که مثلا میشود از آن به این صورت استفاده کرد:
xdg-mime query default image/jpeg
تا معلوم شود که xdg-open در هنگام مواجهه با فایلی با مشخصات image/jpeg چطور بازش کند. حالا ما برای پیادهسازی کلی ایدهمان در آخر یک انگولک کوچکی باید به این xdg برسانیم.
امکان معرفی یک پروتکل جدید در فایرفاکس
نمیدانم متوجه شدهاید که اینترنت فقط همان http نیست یا نه. کلی از این پروتکلهای کوفتی آن تو پیدا میشود که خیلیهاشان را firefox بدبخت هم نمیشناسد. این است که مثلا از این لینک میتوان پیدا کرد که چطور یک پروتکل جدید برای فایرفاکس تعریف کنیم. این را هم برای آنها که (میدانم یک نفرتان هم اینطور نیست) نمیدانند، بگویم کار این پروتکلها این است که به فایرفاکس بفهماند که چطور یک آدرس خاص را باز کند و اگر کار خودش نیست به کدام برنامه بفرستد.
معرفی Pentadactyl
این یکی را قبلا معرفی کردهام. فقط توجه داشته باشید که برای نصب آن روی فایرفاکستان باید از اینجا دانلودش کنید. متاسفانه آخرین نسخهای که روی سایت فایرفاکس قرار گرفته، مربوط نسخهٔ ۳ فایرفاکس است که دیگر کاربردی ندارد. در ادامه این را هم کمی انگولک میکنیم.
پیادهسازی
در هنگام معرفی، بخش ایمکسی قضیه را حل کردیم. در واقع الان ایمکسمان بعد از اجرا گوش به زنگ میماند که یک پیغام متنی با قوائد خاص (پروتکل org-protocol) از emacsclient دریافت کند و منوی capture را نشانمان دهد. حالا بخش حل نشده این است که چطور این پیغام را بفرستیم. ما میخواهیم این پیغامها از فایرفاکس و با کمترین دخالت ما ارسال شود.
اول از همه به در فایرفاکس میرویم و کلیک راست میکنیم و new > boolean را انتخاب میکنیم. در منوی اول مقدار network.protocol-handler.expose.org-protocol را وارد و OK میکنیم. در منوی بعدی هم false را انتخاب میکنیم و Ok را میزنیم. حالا میآییم بیرون و یک فایل html میسازیم و همچین لینکی درونش قرار میدهیم:
<a href="org-protocol://ishahinism@gmail.com">org-protocol</a>
فایل را درون فایرفاکس باز میکنیم و روی لینک org-protocol کلیک میکنیم. اگر همه چیز درست پیش برود، فایرفاکس باید ازمان بپرسد که چطور این لینک را باز کند. در غیر این صورت میگوید که من این لینک را نمیشناسم و از این قضایا. به هر حال در صورتی که وضعیتتان درست بود به /usr/bin/xdg-open بروید و OK را بزنید. اینجاست که xdg میماند و ازتان میپرسد که چطور این فایل را باز کند. برای حالی کردنش کافیست فایل /usr/share/applications/emacsclient.desktop تان را ویرایش کنید و تنها مقدار زیر را درونش قرار دهید:
[Desktop Entry]
Name=Emacs Client
Exec=emacsclient %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol;
حالا برای این که ببینیم xdg-open برنامه را درست تشخیص میدهد یا نه دستور زیر را میزنیم:
xdg-mime query default x-scheme-handler/org-protocol
که خروجی درست باید emacsclient.desktop باشد. حالا دوباره به فایرفاکس بر میگردیم و یک بوکمارکلت با مقدار زیر به آن اضافه میکنیم:
javascript:location.href='org-protocol://capture://'+encodeURIComponent(location.href)+'/'+encodeURIComponent(document.title)+'/'+encodeURIComponent(window.getSelection())
توجه داشته باشید که باقی فیلدها باید به صورت زیر پر شده باشد:
حالا تنها کافیست که روی یک صفحهای که میخواهیم بوکمارکش کنیم، این بوکمارکلت را اجرا کنیم. بلافاصله درون نشست ایمکسمان یک منوی capture باز میشود که با انتخاب گزینهٔ [w] (طبق تنظیمات من) لینک و اسم صفحه درون org-capture نوشته میشود و org از شما tagهای مناسب را میپرسد. همچنین اگر در هنگام فشردن بوکمارکلت متنی از این صفحه را انتخاب کرده باشید، این متن بعد از description در زیر لینک صفحه اضافه میشود که برای نت برداری از وب فوقالعاده است.
الان ۸۰ درصد کار انجام شده. ولی از آنجایی که من دوست دارم با کیبوردم قادر به کنترل این عملیات باشم، باید خطوط زیر را به .pentadactylrcام اضافه کنم:
command -description "Capture in Emacs" org-capture :open org-capture
:map -builtin -description "Capture in Emacs" -silent z :org-capture<CR>
با این دستورات، تابعی به اسم org-capture روی pentadactyl ایجاد کردیم تا پس از جرا بوکمارکلت org-capture را که قبلا به فایرفاکس اضافه کردیم را اجرا کند. همینطور این دستور را به کلید z کیبورد اضافه کردیم تا پس از فشرده شدنش، مشخصات صفحه به org-capture فرستاده شود. البته این کلید را علیالحساب انتخاب کردهام تا بعد سر فرص کلیدهای میانبر pentadactyl را کمی بیشتر شخصیسازی کنم.
ایده کاملا اجرا شد؟
حقیقتش نه کاملا. هنوز یک بخش قضیه مانده. هر چند با org میتوان ترتیبی داد که لینکهایی با تگ خاص مثلا :ReadLater: برای مطالعه نمایش داده شوند، ولی امکانات وبسروری ابزاری مثل GetPocket یا همان Read it later سابق، نظیر کش کردن صفحات یا داشتن لینکها روی دستگاههای دیگر، قابلیتهای چشمگیری است که نمیتوان به سادگی از کنارش گذشت. خصوصا این که سادگی کاربریاش کاملا وسوسه بر انگیز است. این است که برای مطالبی که میخواهم سر فرصت بخوانم از این ابزار استفاده میکنم. این بار نیز یک بوکمارکلت برای GetPocket با دستور زیر میسازم:
javascript:(function(){var%20e=function(t,n,r,i,s){var%20o=[1915346,6992523,1020608,2862964,2254555,3428606,5437914,5999262,3661015,3685235];var%20i=i||0,u=0,n=n||[],r=r||0,s=s||0;var%20a={'a':97,'b':98,'c':99,'d':100,'e':101,'f':102,'g':103,'h':104,'i':105,'j':106,'k':107,'l':108,'m':109,'n':110,'o':111,'p':112,'q':113,'r':114,'s':115,'t':116,'u':117,'v':118,'w':119,'x':120,'y':121,'z':122,'A':65,'B':66,'C':67,'D':68,'E':69,'F':70,'G':71,'H':72,'I':73,'J':74,'K':75,'L':76,'M':77,'N':78,'O':79,'P':80,'Q':81,'R':82,'S':83,'T':84,'U':85,'V':86,'W':87,'X':88,'Y':89,'Z':90,'0':48,'1':49,'2':50,'3':51,'4':52,'5':53,'6':54,'7':55,'8':56,'9':57,'\/':47,':':58,'?':63,'=':61,'-':45,'_':95,'&':38,'$':36,'!':33,'.':46};if(!s||s==0){t=o[0]+t}for(var%20f=0;f<t.length;f++){var%20l=function(e,t){return%20a[e[t]]?a[e[t]]:e.charCodeAt(t)}(t,f);if(!l\*1)l=3;var%20c=l\*(o[i]+l\*o[u%o.length]);n[r]=(n[r]?n[r]+c:c)+s+u;var%20p=c%(50\*1);if(n[p]){var%20d=n[r];n[r]=n[p];n[p]=d}u+=c;r=r==50?0:r+1;i=i==o.length-1?0:i+1}if(s==264){var%20v='';for(var%20f=0;f<n.length;f++){v+=String.fromCharCode(n[f]%(25\*1)+97)}o=function(){};return%20v+'7e0bb8683d'}else{return%20e(u+'',n,r,i,s+1)}};var%20t=document,n=t.location.href,r=t.title;var%20i=e(n);var%20s=t.createElement('script');s.type='text/javascript';s.src='https://getpocket.com/b/r4.js?h='+i+'&u='+encodeURIComponent(n)+'&t='+encodeURIComponent(r);e=i=function(){};var%20o=t.getElementsByTagName('head')[0]||t.documentElement;o.appendChild(s)})()
و باقی خانههایش را به صورت زیر تکمیل میکنم:
در آخر هم برای دسترسی سریعتر دستورات زیر را به .pentadactylrc اضافه میکنم:
command -description "Read it later" pocket :open pocket
:map -builtin -description "Read it later" a :pocket<CR>
همانطور که میبینید این دستور را به میانبر a متصل کردم که در واقع بوکمارک توکار خود pentadactyl را که از بوکمارک فایرفاکس استفاده میکرد رونویسی کرده و از کار میاندازد. خوب حالا دیگر تقریبا همه چیز تمام است. میتوان از وبگردی با خیال راحتتری لذت برد.
پینوشت ۱: این مطلب چیزی نیست که ایدهٔ ناب خودم باشد. قبلا هم خیلیهای همچین چیزی را پیاده سازی کردهاند و استفاده میکنند. این است که تمامی مطالب ذکر شده در اینجا را میتوانید از توی لینکهای داخل مطلب هم پیدا کیند. کمک هم خواستید همان دور و برها چیزهای خوبی پیدا میشود.
پینوشت ۲: توی این تنظیمات سلیقهٔ شخصی و تنبلی بنده خیلی دخیل بوده. خوشحال میشود روشهای شما را هم بدانم ;-)