<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1427064072400819258</id><updated>2012-02-16T22:34:00.207+02:00</updated><category term='linux'/><category term='google groups'/><category term='apache'/><category term='firefox'/><category term='islamic'/><category term='jabber/xmpp'/><category term='tamuq'/><category term='arabic'/><category term='iphone'/><category term='android'/><category term='nokia'/><category term='javascript'/><category term='personal'/><category term='symbian'/><category term='latex'/><category term='jiggy'/><category term='Ubuntu'/><category term='HTK'/><category term='health'/><title type='text'>Hosam Hammady's blog</title><subtitle type='html'>This is my personal blog. I write both personal and technical blogs. I write about new ideas and technical stuff that interest me.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.hammady.net/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-1389928665020956456</id><published>2011-06-02T07:30:00.007+02:00</published><updated>2011-06-02T08:14:25.574+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arabic'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>الآن يمكنك الكتابة بالعربية على الأندرويد باستخدام لوحة مفاتيح آبل اللاسلكية</title><content type='html'>&lt;div style="text-align: right;direction: rtl; "&gt;لقد كتبت &lt;a href="http://blog.hammady.net/2011/05/android-adding-arabic-layout-for.html"&gt;تدوينة&lt;/a&gt; الأسبوع الماضي تتحدث عن كيفية إضافة اللغة العربية كلغة ثانية على &lt;a href="http://www.apple.com/keyboard/"&gt;لوحة مفاتيح آبل اللاسلكية&lt;/a&gt; لاستخدامها على هاتف الأندرويد. ولكني قد كتبتها باللغة الإنجليزية. وبعد مرور أسبوع تقريبا جاءت مبادرة المجلس الأعلى للاتصالات وتكنولوجيا المعلومات بدولة قطر لدعم المحتوى العربي على شبكة المعلومات. بالطبع لم تكن هذه هي المبادرة الأولى فقد نظم المجلس الأعلى مؤتمر كتكوم الذي كانت إحدى محاوره الرئيسية دعم المحتوى العربي على شبكة المعلومات.&lt;/div&gt;&lt;div style="text-align: right;"&gt;وبعد تشجيعهم لي على موقع تويتر فلم أجد بدا من أن هذه التدوينة هي أولى تدوينة لكتابتها باللغة العربية لأنها تخدم لغتي الحبيبة العربية شكلا ومضمونا، وإليكم التدوينة.&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;إذا كنت محظوظا بما فيه الكفاية بتملك لوحة مفاتيح لاسلكية - بلوتوث وخاصة لوحة مفاتيح آبل اللاسلكية، إذًا فإنه من الممتع استخدامها للكتابة على هاتف الأندرويد خاصتك لكونها مريحة جدا في الكتابة. ولحسن الحظ أيضا، فهناك عدة تطبيقات على سوق تطبيقات أندرويد تتيح لك ذلك، أذكر منها بالأخص اثنين: &lt;a href="https://market.android.com/search?q=blueinput&amp;amp;so=1&amp;amp;c=apps"&gt;BlueInput&lt;/a&gt; و &lt;a href="https://market.android.com/details?id=elbrain.bluekeyboard.ime&amp;amp;feature=search_result"&gt;BlueKeyboard JP&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: right;"&gt;هناك أيضا العديد من مقاطع الفيديو التي تشرح كيفية استخدام هذه البرامج منها على سبيل المثال هذا المقطع:&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;object style="height: 390px; width: 640px" width="640" height="390"&gt;&lt;embed src="http://www.youtube.com/v/Tg4KJ33VwH8?version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="390"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;/div&gt;&lt;span class="fullpost"&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;ربما لاحظت أن اللغات المدعومة في التطبيق السالف ذكره لا تشمل سوى الإنجليزية والألمانية واليابانية، أي أن العربية غير مدعومة. أما في التطبيق الثاني فالإنجليزية فقط هي المدعومة وحدها. وبما أني أكتب كثيرا على الهاتف بالعربية فكم تمنيت أن أكتب باستخدام لوحة المفاتيح لما وجدته من سهولة استخدامها وبالأخص في المؤتمرات والمحاضرات حين أريد كتابة ملاحظات أو إرسال تغريدات آنية. المهم فقد راسلت مطوري هذه التطبيقات وطلبت منهم إضافة العربية، ولكن أحدهم لم يرد مطلقا والآخر أخبرني أنهم بصدد طرح إصدار جديد من شأنه إضافة لغات جديدة حسب اختيار المستخدم. لم يسعني الانتظار وخصوصا أنهم لم يحددوا موعدا ثابتا.&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;بعد البحث في شكبة المعلومات والدراسة السريعة لتصميم وبناء نظام الأندرويد، فقد قررت أن أضف دعم العربية بنفسي. وبالفعل تم بحمد الله مرادي وأنشأت تحديث للأندرويد وهو ما يطلق عليه ROM Update&lt;/div&gt;&lt;div style="text-align: right;"&gt;من شأنه إضافة اللغة العربية كلغة ثانية بحيث تعمل على أي تطبيق للوحة المفاتيح على كل تطبيقات الهاتف. وبما أن هذا التحديث يعدل في نظام التشغيل فيجب أن يكون جهازك مفتوح وهو ما يسمي بالروتنج أو Rooting.&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;a href="http://twitter.com/#%21/hammady/status/28760736985522176"&gt;هذا&lt;/a&gt; دليل جيد جدا للروتنج أنصح بالرجوع إليه إذا لم تكن قد فعلت بعد.&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;في الوقت الحالي هذا التحديث مصمم فقط لجهاز جوجل نكسس إس المحمل بنظام تشغيل معدل &lt;a href="http://android.modaco.com/"&gt;موداكو&lt;/a&gt; أو &lt;a href="http://www.cyanogenmod.com/"&gt;سيانوجنمود&lt;/a&gt;. ولكن لا يعني هذا أن بقية الأجهزة غير مدعومة وذلك لأني ليس عندي الوقت الكافي لحزم التحديث لجميع الأجهزة المتوفرة. إذا كنت مهتما، فقط اترك تعليق أدناه مع ذكر نوع جهازك ونظام تشغيله المعدل وسيسعدني عمل التحديث لجهازك.&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: right;"&gt;للتحميل وكيفية التنصيب والاستخدام، راجع &lt;a href="http://blog.hammady.net/2011/05/android-adding-arabic-layout-for.html"&gt;التدوينة السابقة&lt;/a&gt;.&lt;/div&gt;&lt;div style="text-align: right;"&gt;هذا كل ما أردت كتابته، في انتظار تعليقاتكم ويسعدني مساعدتكم.&lt;/div&gt;&lt;div style="text-align: right;"&gt;والسلام عليكم&lt;/div&gt;&lt;div style="text-align: right;"&gt;حسام&lt;/div&gt;&lt;div style="text-align: right;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-1389928665020956456?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/1389928665020956456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=1389928665020956456' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1389928665020956456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1389928665020956456'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2011/06/blog-post.html' title='الآن يمكنك الكتابة بالعربية على الأندرويد باستخدام لوحة مفاتيح آبل اللاسلكية'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-7469472851908286690</id><published>2011-05-26T21:22:00.016+02:00</published><updated>2011-05-26T22:34:02.953+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>[Android] Adding Arabic Layout for Bluetooth HID Keyboards</title><content type='html'>If you are lucky enough to have a bluetooth &lt;a href="http://en.wikipedia.org/wiki/Human_interface_device"&gt;HID&lt;/a&gt; keyboard, like &lt;a href="http://www.apple.com/keyboard/"&gt;Apple Wireless Keyboard&lt;/a&gt;, then it would be ultimate fun to use it on your Android phone for convenient editing. Luckily as well, there are couple of Market apps that let you do this. The first is &lt;a href="https://market.android.com/search?q=blueinput&amp;amp;so=1&amp;amp;c=apps"&gt;BlueInput&lt;/a&gt; and the other is &lt;a href="https://market.android.com/details?id=elbrain.bluekeyboard.ime&amp;amp;feature=search_result"&gt;BlueKeyboard JP&lt;/a&gt;. There are many tutorials explaining how you use these apps, here is one of them:&lt;br /&gt;&lt;iframe src="http://www.youtube.com/embed/Tg4KJ33VwH8" allowfullscreen="" width="560" frameborder="0" height="349"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;As you can see, only English, Dutch and Japanese layouts are supported. For the other app, only English is supported. As an Arabic speaker, I wished that I could use my keyboard to write in Arabic. I tried to contact the developer of BlueKeyboard JP but he never answered. He even didn't have much time to publish my comment on his website. I contacted &lt;a href="http://www.teksoftco.com/index.php?section=blueinput"&gt;Teksoft&lt;/a&gt;, the developers of BlueInput, but all what they have said is that they are gonna add more layouts soon.&lt;br /&gt;&lt;br /&gt;After some readings in the Android OS architecture, I have developed a ROM update that will add the Arabic layout to &lt;span style="font-weight: bold; font-style: italic;"&gt;ANY&lt;/span&gt; HID app you are using! Obviously, your device should be rooted.&lt;br /&gt;A good guide for rooting Nexus S can be found &lt;a href="http://twitter.com/#%21/hammady/status/28760736985522176"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As of the moment, the update is available only for Nexus S running either &lt;a href="http://www.cyanogenmod.com/"&gt;Cyanogenmod7&lt;/a&gt; or &lt;a href="http://android.modaco.com/"&gt;MoDaCo&lt;/a&gt;. Although, cooking an update for any device is darn easy, but I don't have much time to do this for all and every device on the market. If you are interested, please leave a comment below mentioning your device model and firmware, and I will cook the update for you.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Download (144 KB):&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hammady.net/arabichid-android/update-arabic-hid-NS-CM7-0.1-signed.zip"&gt;Nexus S, Cyanogenmod7&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hammady.net/arabichid-android/update-arabic-hid-NS-modaco-0.1-signed.zip"&gt;Nexus S, MoDaCo&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;How to install:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Because you have a rooted device, you should be already having &lt;a href="http://twitter.com/#%21/clockworkmod"&gt;Clockworkmod &lt;/a&gt;recovery installed as your recovery manager (or a similar). Flash my update the same as you flash any update.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download the appropriate file from above and save it on your device sdcard.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reboot the device in the recovery mode (for Nexus S, hold the Power &amp;amp; Vol-up while switching on, and then select Recovery)&lt;/li&gt;&lt;li&gt;Choose 'install zip for sdcard'&lt;/li&gt;&lt;li&gt;Choose 'choose zip for sdcard'&lt;/li&gt;&lt;li&gt;Select the update file you have saved in step 1&lt;/li&gt;&lt;li&gt;Confirm install by selecting 'Yes - install blah blah...'&lt;/li&gt;&lt;li&gt;Wait a couple of seconds and make sure no errors are displayed&lt;/li&gt;&lt;li&gt;Now choose 'Go Back' and reboot your device normally&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;How to use:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Assuming you have successfully connected your keyboard and can type in English, wherever you want to write in Arabic, just press the Alt key two times, that simple!&lt;/li&gt;&lt;li&gt;To type again in English, just press the Alt key two times, again!&lt;/li&gt;&lt;li&gt;When writing in Arabic, you can use the shift key to write alef hamza, Arabic comma, semicolon, diacritics (tashkeel) and everything you are used to write on your computer.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;You will also notice that digits are written in Hindi, so yes it is real Arabic keyboard :)&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Note: &lt;/span&gt;in BlueKeyboard JP, there is a bug that will not let you switch to Arabic when the bottom ads are shown, to workaround this, just press 'Esc' on your keyboard for the ads to go away and then you can switch back and forth to/from Arabic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Important: &lt;/span&gt;Don't use this update for devices having physical keyboards. Obviously this will modify their layout.&lt;br /&gt;&lt;br /&gt;That's it for now, waiting to hear from you.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-7469472851908286690?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/7469472851908286690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=7469472851908286690' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7469472851908286690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7469472851908286690'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2011/05/android-adding-arabic-layout-for.html' title='[Android] Adding Arabic Layout for Bluetooth HID Keyboards'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/Tg4KJ33VwH8/default.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-882077043584424223</id><published>2010-09-26T13:44:00.003+02:00</published><updated>2010-09-26T14:00:54.340+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Securing apache Basic authentication</title><content type='html'>The easiest way to &lt;a href="http://httpd.apache.org/docs/1.3/howto/auth.html"&gt;secure your apache webserver&lt;/a&gt; is using Basic authentication. Users wanting to access your webserver will be prompted to enter a username/password pair to do that. However, Basic authentication is not secure as it does not encrypt these credentials, nor the content itself. The solution comes in Digest authentication. This is how to migrate your server configuration from Basic to Digest authentication.&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;In Basic authentication, you create a passwords file (using htpasswd command) then configure apache as in the link above. To migrate to Digest authentication all you have to do is to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use the command htdigest instead of htpasswd to create users&lt;br /&gt;&lt;blockquote&gt;htdigest -c /path/to/your/passwords/file "Authentication Realm" username&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Configure apache by adding the following:&lt;br /&gt;&lt;blockquote&gt;AuthType Digest&lt;br /&gt;AuthName "Authentication Realm"&lt;br /&gt;AuthUserFile /path/to/your/passwords/file&lt;br /&gt;Require valid-user&lt;/blockquote&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you have SELinux running, enable httpd to access the passwords file:&lt;br /&gt;&lt;blockquote&gt;setsebool -P httpd_enable_homedirs 1&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;Restart apache:&lt;br /&gt;&lt;blockquote&gt;service httpd restart&lt;/blockquote&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Note: the apache user (usually apache) needs to have read access to the passwords file, apparently!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is worth nothing that Digest authentication only encrypts your password, but not the content. Moreover, anyone sniffing on the packets, having the encrypted password, can use it directly to access your content. To overcome these issues, you have to put your content under SSL, but this is another story.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-882077043584424223?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/882077043584424223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=882077043584424223' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/882077043584424223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/882077043584424223'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2010/09/securing-apache-basic-authentication.html' title='Securing apache Basic authentication'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-3945912005234637875</id><published>2010-08-19T09:37:00.005+02:00</published><updated>2010-08-19T10:04:50.038+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nokia'/><title type='text'>Nokia Ovi Store distribution market and the axis-of-evil countries</title><content type='html'>Today I was reading some technical news and came across &lt;a href="http://blogs.forum.nokia.com/blog/nokia-developer-news/2010/08/16/new-forum-nokia-page-shares-ovi-store-statistics"&gt;an article&lt;/a&gt; from the Forum Nokia Blog. The article highlights the achievements and new features of the &lt;a href="http://store.ovi.com/"&gt;Ovi Store&lt;/a&gt;. What drew my attention in this page is the distribution market map of the store. It basically tells which countries have paid apps, which have free only apps, which are totally blocked!&lt;div&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.forum.nokia.com/pics/distribute-ovi-store-global-map.jpg" style="display:block; margin:0px auto 10px; text-align:center;width: 400px; height: 267px;" border="0" alt="" /&gt;&lt;br /&gt;As you can see from the map, these are the axis-of-evil countries that are blocked from the Ovi Store:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Iran&lt;/li&gt;&lt;li&gt;Syria&lt;/li&gt;&lt;li&gt;Sudan&lt;/li&gt;&lt;li&gt;Cuba&lt;/li&gt;&lt;li&gt;North Korea&lt;/li&gt;&lt;li&gt;Cote d'Ivoire&lt;/li&gt;&lt;li&gt;Congo&lt;/li&gt;&lt;li&gt;Zimbabwe&lt;/li&gt;&lt;li&gt;&lt;i&gt;Did my eyes miss something?&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;This reminds me of the &lt;a href="http://arabcrunch.com/2010/01/following-clintons-internet-freedom-speech-us-based-sourceforge-blocked-syria-sudan-iran-korea-cuba-is-open-source-still-really-open.html"&gt;ban of some of these countries&lt;/a&gt; from the SourceForge website post &lt;a href="http://www.state.gov/secretary/rm/2010/01/135519.htm"&gt;Clinton's Internet Freedom Speech&lt;/a&gt;. At least Nokia should make this block list under the control of the app publishers, exactly like &lt;a href="http://news.northxsouth.com/2010/03/03/sourceforge-and-the-us-laws/"&gt;what SourceForge did&lt;/a&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;I don't like the political influence on the technical world. It does not align with the human rights of the people of these countries.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="fullpost"&gt;You too Nokia?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-3945912005234637875?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/3945912005234637875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=3945912005234637875' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/3945912005234637875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/3945912005234637875'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2010/08/nokia-ovi-store-distribution-market-and.html' title='Nokia Ovi Store distribution market and the axis-of-evil countries'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-5427889241539351649</id><published>2010-06-07T13:12:00.002+02:00</published><updated>2010-06-07T13:16:13.365+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='islamic'/><title type='text'>Who is the true God, Jesus or Allah?</title><content type='html'>Everything that is made should have a maker. The computer you are using right now did not come from nothing randomly. There should be a maker of it. The earth, sky, mountains, rivers, your body and everything should have a maker. This maker should be one and only one because if there is more than one, there would be much discrepancy throughout the creatures. This creator is the only God who is so powerful, so great and so merciful. This God is called for since Adam, Noah, Moses, Jesus and Mohammad, Peace be upon them all. They all call for the same creator, the same God, Allah. This is what Muslims believe.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;As for Jesus, Peace be upon him, he was given birth without a father. Allah sent his angel Gabriel to Jesus mother, Mary with the blessing of a baby. She asked Gabriel, oh how can I have a baby without a father? He replied, for Allah, the most powerful, do you think it is difficult for him? Allah created Eve without a mother, and Adam without a mother, nor a father.&lt;br /&gt;&lt;br /&gt;Jews at that time condemned Mary of making illegal love, they did not believe Jesus is a blessed prophet sent from almighty Allah. They even tried killing him over the Cross when he was an adult. However, Allah, the most merciful, sent someone that resembles him to be prosecuted instead of him. Since then, Christians believe it was Jesus was really prosecuted for the humanity sake. They even believe that he is God himself, or the son of God. But how could a God stay in his mother's womb for 9 months? How could he eat and drink and then urinate and defecate? And how was the world managed while he was in his mother's womb?&lt;br /&gt;&lt;br /&gt;If you need more information about Allah and Islam, you can check these websites:&lt;br /&gt;&lt;a href="http://www.islam-qa.com/en/cat/12"&gt;http://www.islam-qa.com/en/cat/12&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.islamicity.com/education/understandingislamandmuslims/"&gt;http://www.islamicity.com/education/understandingislamandmuslims/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="fullpost"&gt;Peace be upon you.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-5427889241539351649?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/5427889241539351649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=5427889241539351649' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/5427889241539351649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/5427889241539351649'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2010/06/who-is-true-god-jesus-or-allah.html' title='Who is the true God, Jesus or Allah?'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4058911642842750243</id><published>2010-06-03T11:54:00.004+02:00</published><updated>2010-06-03T12:06:32.407+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google groups'/><title type='text'>The undocumented changes in Google Groups posting policies</title><content type='html'>I have been noticing that my email posts on one of the Google Groups I am subscribed to do not get replies from other members anymore. I was starting to get upset and thought my popularity has dropped and people are totally skipping my emails! I asked &lt;a href="http://blog.gammal.org/"&gt;Mahmoud &lt;/a&gt;what was the last email he got from me and he told me it was several days ago! I logged in to the group website and found that my recent posts do NOT get delivered at all, without a single notice from Google!&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;After several tests I came to the following:&lt;br /&gt;When your subscription in Google Groups is on email A, you have to really send from this email account A. If you use an email account B with an alternate account A (that appears in the From field), this will not work (as of May 29th and at least for me!)&lt;br /&gt;You will not even get a delivery error from Google in this case because they think you are forging this email.&lt;br /&gt;&lt;br /&gt;However, if you send from a totally different account C (and don't try to modify the sender), you will get a delivery error.&lt;br /&gt;&lt;br /&gt;Moreover, if you send from account A USING ANY ALTERNATIVE ACCOUNT B, C, D, ... The message will be delivered!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom line, now they only look for the real sender, and if an alternative account is used, they don't reply back with any error.&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4058911642842750243?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4058911642842750243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4058911642842750243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4058911642842750243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4058911642842750243'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2010/06/undocumented-changes-in-google-groups.html' title='The undocumented changes in Google Groups posting policies'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-2761280543750345342</id><published>2009-09-05T16:41:00.000+02:00</published><updated>2009-09-05T15:53:06.395+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>Getting your location using iPhone with no GPS</title><content type='html'>One of the main big features in iPhone 3G that was not shipped with its ancestor iPhone 2G is GPS support. You can determine your location using GPS satellites.&lt;br /&gt;It is known that although very accurate, GPS has some drawbacks. It needs a lot of time to connect to the satellites, in the order of tens of seconds. It won't work indoors as well. Moreover, it is &lt;a href="http://www.cellular-news.com/story/34085.php"&gt;banned&lt;/a&gt; in Egypt, Syria and North Korea!&lt;br /&gt;Update: It is &lt;a href="http://rescommunis.wordpress.com/2009/04/20/egypt-lifts-gps-ban/"&gt;not banned&lt;/a&gt; anymore in Egypt.&lt;br /&gt;&lt;br /&gt;So can one determine his location without the aid of GPS technology? The answer is Yes. This can be done by identifying nearby GSM cell towers and query a database that stores their location. So lets divide the rest of this post into 2 parts:&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Identifying nearby GSM cell towers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Doing this on the iPhone was a bit tricky. Actually it was a challenge for us at &lt;a href="http://www.espace.com.eg/"&gt;eSpace&lt;/a&gt; to get such information. I will list here the challenges we met and how we managed to solve them:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;There is no official SDK for iPhone OS 1.x. This was the easiest challenge to solve. Everybody uses &lt;a href="http://code.google.com/p/iphone-dev/wiki/Building"&gt;iphone-dev&lt;/a&gt; for building the iPhone toolchain. Most of the header files in the toolchain are generated by &lt;a href="http://www.codethecode.com/projects/class-dump/"&gt;class-dump&lt;/a&gt;! This is a tool that takes a binary framework (library) as an input and emits some Objective-C code in a header file that represents symbols in the library. Its idea is as simple as using &lt;a href="http://linux.about.com/library/cmd/blcmdl1_nm.htm"&gt;nm&lt;/a&gt; to query symbol names and some extra code to wrap this info in Objective-C syntax.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Even in the non-official toolchain, there is not a word on how to deal with telephony features like calls and text messaging. Thanks to &lt;a href="http://code.google.com/p/iphone-wireless/source/browse/#svn/trunk/CellStumbler"&gt;CellStumbler&lt;/a&gt;, we used it to get cell information. It is a tool that exploits CoreTelephony framework functionality. CoreTelephony.h is also generated with class-dump.&lt;/li&gt;&lt;li&gt;CellStumbler is very fragile, if you do simple edits in it, it may crash! The guys say it is toolchain bugs! Just keep this in mind if you need to modify it. Be aware that server connection callback never get called, so keep on retrieving cell information until you get something useful.&lt;/li&gt;&lt;li&gt;Because CellStumbler is that fragile, we left the code untouched in its major parts, we just changed the part that outputs results. We then called the binary from a shell and parsed its output to get useful nearby cell information.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Querying a database for cell location&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Google used to have a secret API for this. It is called My Location. This is the API it uses in Maps. Unfortunately, at the time of our development, the API was secret, we had to sniff upon packets to/from Google Maps to know what happens under the hood and replays it. Now this API is &lt;a href="http://googlemobile.blogspot.com/2008/06/google-enables-location-aware.html"&gt;open to developers&lt;/a&gt;, thanks Google.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-2761280543750345342?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/2761280543750345342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=2761280543750345342' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/2761280543750345342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/2761280543750345342'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/11/getting-your-location-with-iphone-with.html' title='Getting your location using iPhone with no GPS'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-7735086772938140322</id><published>2009-06-02T13:24:00.005+02:00</published><updated>2009-06-02T13:36:37.587+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Fortunately, another reason why I use Ubuntu</title><content type='html'>Since I installed Ubuntu 9.04 on my work machine (and replaced Micro$oft Outlook with Evolution), I always wondered why my download speed became surprisingly a lot faster! My surprises approached a relief today when I came across a local speed test service. I tested the speed on Windows (with no firewalls or anything coming in the middle) and Ubuntu.&lt;br /&gt;&lt;br /&gt;The result was Ubuntu achieving &lt;span style="font-weight: bold;"&gt;DOUBLE&lt;/span&gt; speed than Windows! Yes you read it right, &lt;span style="font-weight: bold;"&gt;DOUBLE&lt;/span&gt; speed on the same machine!&lt;br /&gt;I will leave you with the screenshots to witness it yourself.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Windows download speed:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Fxxo5JtY8z8/SiUNqc-3p-I/AAAAAAAAACU/E7lIm9fKHlg/s1600-h/speedtest-windows.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 232px;" src="http://4.bp.blogspot.com/_Fxxo5JtY8z8/SiUNqc-3p-I/AAAAAAAAACU/E7lIm9fKHlg/s400/speedtest-windows.jpg" alt="" id="BLOGGER_PHOTO_ID_5342691555930515426" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Ubu download speed:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Fxxo5JtY8z8/SiUNz4MZYPI/AAAAAAAAACc/kp7L0OTB3R8/s1600-h/speedtest-ubuntu.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 231px;" src="http://4.bp.blogspot.com/_Fxxo5JtY8z8/SiUNz4MZYPI/AAAAAAAAACc/kp7L0OTB3R8/s400/speedtest-ubuntu.jpg" alt="" id="BLOGGER_PHOTO_ID_5342691717853831410" border="0" /&gt;&lt;/a&gt;The only explanation I can tell is that the TCP/IP stack default parameters on Windows are  not optimally configured, while the defaults in Linux are!&lt;br /&gt;Any other suggestions?&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-7735086772938140322?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/7735086772938140322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=7735086772938140322' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7735086772938140322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7735086772938140322'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2009/06/fortunately-another-reason-why-i-use.html' title='Fortunately, another reason why I use Ubuntu'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Fxxo5JtY8z8/SiUNqc-3p-I/AAAAAAAAACU/E7lIm9fKHlg/s72-c/speedtest-windows.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4478228572800224756</id><published>2009-05-17T13:29:00.006+02:00</published><updated>2009-07-01T13:44:10.055+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='tamuq'/><title type='text'>Dr Mohamed Slim Alouini farewell at TAMUQ</title><content type='html'>Today we gathered for the farewell of &lt;a href="http://ecen.qatar.tamu.edu/425.aspx"&gt;Dr Alouini&lt;/a&gt; at &lt;a href="http://www.qatar.tamu.edu/"&gt;TAMUQ&lt;/a&gt;. It has only been one week since I am here at TAMUQ, but Dr Alouini did have an effect on my career! Last October when I came here for an interview, Dr Slim (and &lt;a href="http://ecen.qatar.tamu.edu/838.aspx"&gt;Dr Shehab Ahmed&lt;/a&gt;) urged me to finish my Masters so that they can apply for my VISA.&lt;br /&gt;&lt;br /&gt;After I came back to Egypt, I took an unpaid vacation from my work at &lt;a href="http://www.espace.com.eg/"&gt;eSpace&lt;/a&gt; and started the campus of studying! Thanks to Allah, I got the Masters certificate last February. I was always remembering Dr Alouini's words about pushing my career onwards and finishing the Masters as quickly as possible.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Fxxo5JtY8z8/Sg_3TFzOs7I/AAAAAAAAACM/IkrP-4C-9qU/s1600-h/17052009147.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_Fxxo5JtY8z8/Sg_3TFzOs7I/AAAAAAAAACM/IkrP-4C-9qU/s400/17052009147.jpg" alt="" id="BLOGGER_PHOTO_ID_5336755990803952562" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From right: Hossam Hammady (me), &lt;a href="http://people.qatar.tamu.edu/wessam-mesbah/"&gt;Dr Wessam Mesbah&lt;/a&gt;, Dr Alouini, Dr Ahmed Masoud, Majid Farouqi.&lt;br /&gt;&lt;br /&gt;So although we didn't meet much, but thanks Dr. Alouini for pushing me onwards.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4478228572800224756?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4478228572800224756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4478228572800224756' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4478228572800224756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4478228572800224756'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2009/05/dr-mohamed-slim-alouini-farewell-at.html' title='Dr Mohamed Slim Alouini farewell at TAMUQ'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Fxxo5JtY8z8/Sg_3TFzOs7I/AAAAAAAAACM/IkrP-4C-9qU/s72-c/17052009147.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-1779485683175026540</id><published>2009-05-14T09:32:00.005+02:00</published><updated>2009-05-17T13:43:55.671+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='tamuq'/><title type='text'>My new job at Texas A&amp;M University at Qatar</title><content type='html'>It has been so long since I posted anything here. I am always lazy writing blogs :( Today I thought I should write something. From now on, my blogs should be short so that I don't get lazy writing them!&lt;br /&gt;&lt;br /&gt;So, I am writing this to let you know that I have joined &lt;a href="http://www.qatar.tamu.edu"&gt;Texas A&amp;M University at Qatar&lt;/a&gt; as a Teaching Associate. The hiring process took too long since I had to finish my Masters first before I apply for the VISA. Thanks Allah, I finished my Masters last February, but this is another story, I will write about it soon insha2Allah :)&lt;br /&gt;&lt;br /&gt;I am now in Doha with my little family, my wife and my little 1-year-old kid, Abdullah. My job here includes both teaching tasks and support in IT-related issues for the faculty.&lt;br /&gt;&lt;br /&gt;A lot of paper work to do here to finish my residency permit and settle in my new house. I didn't take any task yet, just all about orientation and settlement. I hope work would be fun here as I have always enjoyed my job :)&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-1779485683175026540?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/1779485683175026540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=1779485683175026540' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1779485683175026540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1779485683175026540'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2009/05/my-new-job-at-texas-university-at-qatar.html' title='My new job at Texas A&amp;M University at Qatar'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4573048065178265834</id><published>2008-11-06T10:24:00.011+02:00</published><updated>2008-12-13T22:51:58.060+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jabber/xmpp'/><title type='text'>MCabber: a command-line-only multi-protocol IM client</title><content type='html'>Command-line geeks, its time to stay focused on your terminals and not switch to X back-and-forth when chatting with your buddies.&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://mcabber.com/"&gt;mcabber&lt;/a&gt; is a small Jabber console client.&lt;br /&gt;mcabber includes features such as SSL support, MUC (Multi-User Chat) support, history logging, command completion, OpenPGP encryption, OTR (Off-the-Record Messaging) support and external action triggers.&lt;/blockquote&gt;&lt;br /&gt;As you can see MCabber is just a Jabber client. So you can not use it to connect to your favorite IM servers like MSN, Yahoo!, GTalk,...&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://mirror.mcabber.com/screenshots/mcabber20060403.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 599px; height: 316px;" src="http://mirror.mcabber.com/screenshots/mcabber20060403.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However, you can use it to connect to these networks with little effort. All you have to do is to install &lt;a href="http://www.igniterealtime.org/projects/openfire/index.jsp"&gt;OpenFire&lt;/a&gt; (or any Jabber server software) and enable the GatewayIM plugin. From its name, this plugin enables you to connect to other IM networks. Just create an account on your Jabber server through its nice web interface and configure it with other networks login information. Next, let MCabber connect to your server and do everything you love.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Fxxo5JtY8z8/SRKzc9WypEI/AAAAAAAAAB4/rWtQcwRCm2g/s1600-h/Screenshot-Openfire+Admin+Console:+Gateway+Registrations+-+Mozilla+Firefox+3.1+Beta+1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 304px;" src="http://2.bp.blogspot.com/_Fxxo5JtY8z8/SRKzc9WypEI/AAAAAAAAAB4/rWtQcwRCm2g/s400/Screenshot-Openfire+Admin+Console:+Gateway+Registrations+-+Mozilla+Firefox+3.1+Beta+1.png" alt="" id="BLOGGER_PHOTO_ID_5265468224437396546" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To install MCabber on Debian/Ubuntu just type:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install mcabber&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Before you connect with the server, you have to configure MCabber first. The only mandatory configuration is server address, port, username (jid format: username@servername, you can know the servername from OpenFire admin console) and password. You can start with the example configuration file by copying it to your home directory:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cd $HOME&lt;br /&gt;mkdir -p .mcabber/histo&lt;br /&gt;zcat /usr/share/doc/mcabber/examples/mcabberrc.example.gz &gt; .mcabber/mcabberrc&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;So far, I have been talking about everything old! Anything cool here?&lt;br /&gt;&lt;br /&gt;A great functionality of MCabber is that you can write an external script in any language and let it handle IM events like message received, buddy logged in, ...&lt;br /&gt;I have wrote a bash script which plays some nice sounds (got them from &lt;a href="http://www.pidgin.im/"&gt;Pidgin&lt;/a&gt;) on some events, so that you don't have to poll mcabber "window" to watch for new messages! You can download the script from &lt;a href="http://downloads.hammady.net/mcabber/event-handler.sh"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Update: The script now "says" the jid of the buddy logging in/out! However, you need to install &lt;a href="http://en.wikipedia.org/wiki/Festival_Speech_Synthesis_System"&gt;festival&lt;/a&gt; before you can use this feaute:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install festival&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Don't forget to turn on execution bit or it won't be able to run.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;chmod u+x $HOME/.mcabber/event-handler.sh&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Don't also forget to edit mcabberrc to tell it to use that script for handling events&lt;br /&gt;&lt;code&gt;&lt;br /&gt;set events_command = /your/home/directory/.mcabber/event-handler.sh&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4573048065178265834?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4573048065178265834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4573048065178265834' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4573048065178265834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4573048065178265834'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/11/mcabber-command-line-only-multi.html' title='MCabber: a command-line-only multi-protocol IM client'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Fxxo5JtY8z8/SRKzc9WypEI/AAAAAAAAAB4/rWtQcwRCm2g/s72-c/Screenshot-Openfire+Admin+Console:+Gateway+Registrations+-+Mozilla+Firefox+3.1+Beta+1.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-7114186259195960193</id><published>2008-11-01T14:56:00.004+02:00</published><updated>2008-11-01T16:13:26.959+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='HTK'/><title type='text'>Building a no-X version of HTK on Linux</title><content type='html'>&lt;blockquote&gt;The Hidden Markov Model Toolkit (HTK) is a portable toolkit for building and manipulating hidden Markov models. HTK is primarily used for speech recognition research although it has been used for numerous other applications including research into speech synthesis, character recognition and DNA sequencing. HTK is in use at hundreds of sites worldwide.&lt;/blockquote&gt;Quoted from the &lt;a href="http://htk.eng.cam.ac.uk/"&gt;HTK website&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;HTK is a free/open-source piece of software. It builds on Linux, Solaris, IRIX, HPUX, Mac OS/X, Windows NT, 2000, XP  and FreeBSD.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The problem:&lt;/span&gt;&lt;br /&gt;If you tried to build HTK on a command-line-only Linux machine (no X installed), it will give build errors. You may face this situation if you need to run your experiments on a hosted solution that has no GUI to exploit its CPU/memory power. The problem happens because there is a single tool that requires graphical user interface: HSLab.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;blockquote&gt;HSLab is an interactive label editor for manipulating speech label ﬁles. An example of using HSLab would be to load a sampled waveform ﬁle, determine the boundaries of the speech units of interest and assign labels to them. HSLab is the only tool in the HTK package which makes use of the graphics library HGraf.&lt;br /&gt;&lt;/blockquote&gt;In most cases you will not need this tool in your regular experiments. So if this is your case, you can disable it so that the rest of HTK would build successfully.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The solution:&lt;/span&gt;&lt;br /&gt;I assume you are using the latest version of HTK (3.4). Disabling HSLab comes in 2 steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Remove HSLab target from file HTKTools/Makefile in line 48.&lt;/li&gt;&lt;li&gt;Remove HGraph from object dependancy in file HTKLib/Makefile lines 49 and 78.&lt;/li&gt;&lt;/ol&gt;If you have no idea how to make this, you can download my &lt;a href="http://downloads.hammady.net/htk/"&gt;2 patches&lt;/a&gt; and place them in HTK src directory. Run the following commands to patch the makefiles and make/install HTK:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# change directory to htk src path, then:&lt;br /&gt;./configure&lt;br /&gt;patch HTKLib/Makefile HTKLib.Makefile.patch&lt;br /&gt;patch HTKTools/Makefile HTKTools.Makefile.patch&lt;br /&gt;make&lt;br /&gt;sudo make install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now the whole HTK installs with no problems.&lt;br /&gt;Enjoy :)&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-7114186259195960193?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/7114186259195960193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=7114186259195960193' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7114186259195960193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7114186259195960193'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/11/building-no-x-version-of-htk-on-linux.html' title='Building a no-X version of HTK on Linux'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4841252995839516498</id><published>2008-09-30T04:47:00.005+02:00</published><updated>2008-10-04T16:38:54.552+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jiggy'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>Writing Large-Scale iPhone Applications using Jiggy</title><content type='html'>Developing for the &lt;a href="http://www.apple.com/iphone/"&gt;iPhone&lt;/a&gt; is the hype nowadays. However, one big obstacle that faces anyone who wish to write iPhone applications is learning &lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/chapter_1_section_1.html"&gt;Objective-C&lt;/a&gt;. After all, it is a high-level Object Oriented language. However, in my point of view, and for many people as well, the C family of languages is not suitable for application development. It is perfectly suited for writing system libraries and frameworks. This is because one should always take care of memory management, types and low level system calls.&lt;br /&gt;&lt;br /&gt;Thats why we are here, quoted from the &lt;a href="http://www.jiggyapp.com/"&gt;Jiggy&lt;/a&gt; official website:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;h3&gt;What is Jiggy?&lt;/h3&gt;&lt;br /&gt;Simply put, Jiggy is the easiest way to create applications for the iPhone (or iPod Touch). With just Jiggy and a browser, you'll be able to write an awesome iPhone application in a matter of minutes. JiggyApps run natively on the iPhone, so there is no messing around with HTML and the limitations of Mobile Safari. At the same time, you don't need a compiler or even a Mac, because JiggyApps are written in JavaScript.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;When you start writing an application with Jiggy you will find it very simple. However, as your application grows it will be so hard to maintain. Thats why I am writing the following guidelines, which if followed, will help you write large-scale, neat and maintainable Jiggy applications:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Don't use the Jiggy IDE, prepare your development environment around ssh.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;If you already installed Jiggy on your iPhone, you will probably have noticed that there are 2 packages your are installing. First one is called Jiggy runtime. This is a set of dynamic-link libraries that encapsulate all native functionality. These are installed in the library path of the system (/usr/lib) and start with the prefix jiggy, as an example: jiggy.UIKit and jiggy.sqlite. The other package is called just Jiggy. This is the Jiggy IDE I am talking about. It is just an application server built on an HTTP server. You run it from SpringBoard, open a browser on your PC and point it to the iPhone IP to get the IDE working inside the browser. This is the simplest way to develop Jiggy applications. You only need a browser. Running into big applications, you will soon find that the browser is never meant to be a reliable IDE. It WILL crash more frequent than you expect. It will leak memory to the ground. It will freeze for seconds as you save and run the application. Moreover, to work on multiple files simultaneously, you have to open several tabs/windows. You can use this IDE as a fast boot but when you eventually develop seriously you need a more reliable environment. Install &lt;a href="http://blog.psmxy.org/pkg-info/openssh/"&gt;OpenSSH&lt;/a&gt; on the iPhone (but be careful if you need to &lt;a href="http://blog.hammady.net/2008/06/only-idiots-change-their-iphone-root.html"&gt;change the root password&lt;/a&gt;). Next, mount the iPhone filesystem using sshfs:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sshfs root@IPHONE_IP /mount/point -o allow_other&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can download sshfs from its &lt;a href="http://fuse.sourceforge.net/sshfs.html"&gt;official site&lt;/a&gt; or if you are using Debian/Ubuntu by:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install sshfs&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;or if you are using Gnome use the menu Places/Connect to Server... and select server type as SSH. Write the iPhone IP and root as the username. A shortcut will be placed in Places and on the desktop. Either way, you can browse through /Applicatoins/ and point to your application folder then double click on any Javascript file to edit using your favorite editor. I personally use gedit or vim. Just a note, be sure the iPhone is mounted before editing the files or the editor may get confused and hangs.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Distribute required runtime libraries along with your applications, don't assume Jiggy runtime.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;These can be found in /usr/lib as discussed earlier. During the installation process, don't copy the libraries in the system /usr/lib in order not to conflict versions. It is safer to leave them in the application directory. By the way, I didn't try leaving them in the application directory yet :) On the contrary, you may prefer to distribute the libraries through Jiggy runtime. However, be very clear in the installation steps.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;For a more stable and collaborative environment, use a code repository and deploy on device as needed. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;When your code-base grows over time, you will discover that it is safer to use a code repostiory (&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; of &lt;a href="http://en.wikipedia.org/wiki/Concurrent_Versions_System"&gt;CVS&lt;/a&gt;). This will also enable you to share the application with other developers. Now you don't have to mount the iPhone filesystem using ssh as you will not be editing files in-place. You will have a working copy on your PC which is linked against some repository. Each time you need to run the application you will have to copy files over the iPhone, you can write a small shell script to do the copy commands. Till the time of writing this line, Jiggy is only available for the iPhone OS 1.x which has no official SDK or emulator from &lt;a href="http://www.apple.com/"&gt;Apple&lt;/a&gt;. If Jiggy is ported to iPhone OS 2.x it would be easier to run applications on the emulator without the need of copying files on each run.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Avoid using off-the-shelf libraries (&lt;a href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt; for example), you don't need larger useless interpretation times.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;Usually you won't need fancy mechanisms or drag-and-drop and alike functionality. If you need to use AJAX, write your own prototype-alike around the XMLHttpRequest object. If you are too lazy to write it, see &lt;a href="http://downloads.hammady.net/jsexamples/jiggy/ajax.js"&gt;mine&lt;/a&gt;.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Don't start the application from SpringBoard (if you don't have to). Start it from an ssh terminal instead&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;Some functionality won't work if you don't start the application from SpringBoard (like the accelerometer). If you don' have to, ssh to your iPhone and change to the applications directory then launch the jiggy binary:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ssh root@IPHONE_IP&lt;br /&gt;cd /Applications/MyApp.app&lt;br /&gt;./jiggy&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This is a must if you need to see useful log messages from Jiggy native implementation. You can also write your own logs straight from Javascript using the global function log(). See my &lt;a href="http://blog.hammady.net/2008/09/your-guide-to-writing-large-scale.html"&gt;other post&lt;/a&gt; for a discussion on logging in Javascript platforms.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Optionally generate a public/private ssh key-pair so that you don't have to enter ssh password every time you login to your iPhone.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;See the &lt;a href="http://blog.psmxy.org/pkg-info/openssh/"&gt;OpenSSH page&lt;/a&gt; or this &lt;a href="http://rcsg-gsir.imsb-dsgi.nrc-cnrc.gc.ca/documents/internet/node31.html"&gt;good tutorial&lt;/a&gt;.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Keep your main.js as small as 10 lines or less. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;This is always a rule-of-thumb for all programming paradigms. The general flow of the program should be readable by anybody. Throw away your implementations inside classes and throw these classes inside files other than your main.js. Even more, I do NOT write any flow in my main, its just a logic switch, or program selector:&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;// main.js&lt;br /&gt;try {&lt;br /&gt;//include("test1.js")&lt;br /&gt;//include("test2.js")&lt;br /&gt;include("myprog1.js")&lt;br /&gt;}&lt;br /&gt;catch(e) {&lt;br /&gt;log(e)&lt;br /&gt;terminate()&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Whenever I need to test any code or run any sample code, I just throw it in a file and switch to it in my main. When I am finished I uncomment back the original program.&lt;br /&gt;The try/catch is there to bust silly alerts that appears on-screen which if not dismissed normally by user, will freeze the SpringBoard.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Create a test-harness because you will need to try various things first.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;You may create a new application for the sole purpose of testing code. Create any testing code in new files and switch between them in main.js. This way you don't need new applications each time you try any code. See the code of main.js in previous point as an example.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Make your files self-contained, don't assume any implicit dependency.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;In Jiggy, there are 2 types of code dependency. First is Plugin dependency where you depend on a native plugin (&lt;a href="http://www.jiggyapp.com/jigglins"&gt;Jigglin&lt;/a&gt;). Second type is Javascript dependency where you depend on other Javascript files. As an example for the first type, if you use the package &lt;span style="font-style: italic;"&gt;Images&lt;/span&gt; don't assume that the &lt;span style="font-style: italic;"&gt;UIKit&lt;/span&gt; plugin is loaded. In the beginning of the file check if it is not loaded and load it accordingly:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (typeof Images == 'undefined')&lt;br /&gt;Plugins.load('UIKit')&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Current Jiggy implementation does not check for loading same plugins more than once, and hence the check above.&lt;br /&gt;As an example for the second dependency type consider this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;include('another.js')&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And in another.js put the inclusion guard which I borrow from C/C++!&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (typeof __ANOTHER_JS == 'undefined') {&lt;br /&gt;__ANOTHER_JS = 0&lt;br /&gt;// write all your Javascript code here&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;This inclusion guard is recommended although not mandatory because re-interpretation of code may cause undesired logical errors.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Use a central include path because you are going to make/use reusable components. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Sticking to the Object Oriented design will render many parts of your code reusable. The straightforward way to reuse the components is to copy them over through different applications. However, you will be changing them frequently and you need a central place for them. You may place them in a separate directory and create symbolic links inside your application folder. I wish I could have time to patch Jiggy source so that it looks in a central include path if it does not find the file in the application directory. Did I hear someone offering help?&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Always remember the restricted memory resources, cache on disk if necessary.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Don't write code that aggressively allocates memory. Don't let your arrays grow indefinitely. If you need large data-structures let them write their data on disk if they exceeded some limit, using sqlite if needed. If it is all about memory cache, let older values drop altogether.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Don't forget your friend, the garbage collector (GC), you may know when to call it better than the engine does.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Let the code be smart and invoke it in places where you are sure many objects have been released. Each time you release an object, or return from a function, increment released objects count and invoke the GC if it reached some limit. The &lt;a href="http://downloads.hammady.net/jsexamples/jiggy/"&gt;AutoReleaseCache and ImageLoader&lt;/a&gt; are perfect examples for restricted memory management and garbage collection. There should be a global GC function when using them. Here it is:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var GC_TRIGGER = 40&lt;br /&gt;var releasedObjectsCount = 0&lt;br /&gt;GC = function(force)&lt;br /&gt;{&lt;br /&gt;if (force || releasedObjectsCount++ &gt; GC_TRIGGER) {&lt;br /&gt;releasedObjectsCount = 0&lt;br /&gt;log("-----------------------------------------------")&lt;br /&gt;log("running gc")&lt;br /&gt;log("-----------------------------------------------")&lt;br /&gt;gc(1)&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4841252995839516498?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4841252995839516498/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4841252995839516498' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4841252995839516498'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4841252995839516498'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/09/writing-large-scale-iphone-applications.html' title='Writing Large-Scale iPhone Applications using Jiggy'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-575277394202390036</id><published>2008-09-30T02:33:00.007+02:00</published><updated>2008-10-04T16:55:24.912+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Your Guide to Writing Large-Scale Javascript Applications</title><content type='html'>&lt;span style="font-size:85%;"&gt;What is peculiar in Javascript is that it is designed for many types of applications. Noobs can learn it in minutes. They can just go write little validation code insided web pages. Advanced web applications also rely heavily on Javascript. It is even taken beyond the web paradigm. Now you can find Javascript running on servers, inside desktop applications, and even on hand-held devices.&lt;br /&gt;&lt;br /&gt;This explains the ongoing war between Javascript interpreters, &lt;a href="http://code.google.com/p/v8/"&gt;V8&lt;/a&gt;, &lt;a href="http://webkit.org/blog/189/announcing-squirrelfish/"&gt;SquirrelFish&lt;/a&gt;  (and &lt;a href="http://webkit.org/blog/214/introducing-squirrelfish-extreme/"&gt;SquirrelFish Extreme&lt;/a&gt;) and &lt;a href="https://wiki.mozilla.org/JavaScript:TraceMonkey"&gt;TraceMonkey&lt;/a&gt;. Each engine fights to dominate the market. Actually this is so important as web applications are becoming a lot more complex and old-style Javascript engines are dying out of performance. Embedded devices also need performant Javascript engines due to their limited resources.&lt;br /&gt;&lt;br /&gt;When your Javascript application grows in size, you will find it very difficult to maintain because the language is designed to be written in a simple way, no enforcements or conventions of any type. Actually, you will most probably end up with a very bad code. To avoid this and to write neat, maintainble and scalable Javascript applications, I have brainstormed with myself and wrote down the following guidelines. Some of them are general and can be applied to any programming language, not necessarily Javascript. I will be constantly adding to these guidelines as I forumalate them.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Use classes instead of separate global functions. &lt;/span&gt;&lt;br /&gt;One may simply write an old C-style program around functions. The good, although old, news is that Javascript can be written in an object-oriented (OO) style. Although there are no explicit class definitions or inheritance, you still can work around this and define your own classes with both public and private access to data members and member functions. As implied by the OO design, your application will neatly grow as it goes. I will not discuss how to write classes but you can see the &lt;a href="http://downloads.hammady.net/jsexamples/jiggy/"&gt;these examples&lt;/a&gt; and see these useful links (&lt;a href="http://www.xml.com/pub/a/2006/06/07/object-oriented-javascript.html"&gt;1&lt;/a&gt; and &lt;a href="http://www.developertutorials.com/tutorials/javascript/writing-classes-in-javascript-050404/page1.html"&gt;2&lt;/a&gt; or google it).&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Don't pollute the global context, always use namespaces/singletons.&lt;/span&gt;&lt;br /&gt;If you strictly followed the previous point of the OO design, you will end up with a lot of class names. These class names are nothing but global variables, we approach the start point again. You can create namespaces to hold class definitions inside. For example:&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;&lt;code&gt;var MyPackage = {&lt;br /&gt;MyClassA: function() {...},&lt;br /&gt;MyClassB: function() {...}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This way, we have just hidden MyClassA and MyClassB inside MyPackage namespace. To instanciate objects we write:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;x = new MyPackage.MyClassA().&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note also that similarly we can write a singleton class:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var MySingleton = {&lt;br /&gt;method1: function() {...},&lt;br /&gt;method2: function() {...},&lt;br /&gt;variable1: 10,&lt;br /&gt;variable2: "hello"&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You access singleton members as:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;MySingleton.method1()&lt;br /&gt;MySingleton.variable1&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and so on.&lt;br /&gt;&lt;/span&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Make your functions anonymous and give them variable names.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;Functions in Javascript may be anonymous as well as named. For example you can define a function like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function myfunc() {...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can also write:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function() {...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The latter form can be used as a closure or as an inline function. See &lt;a href="http://www.jibbering.com/faq/faq_notes/closures.html#clClose"&gt;this&lt;/a&gt;, &lt;a href="http://blog.morrisjohns.com/javascript_closures_for_dummies"&gt;this&lt;/a&gt; and &lt;a href="http://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Closures"&gt;that&lt;/a&gt; for more information about closures.&lt;br /&gt;Being an inline function you can set it to a variable:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var myfunc = function() {...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This form may seem equivalent to the named form example above. However, they are not always equivalent. It is interpreter-specific. In IE JScript (I think it was IE6), named functions are always given their name regardless of their scope. This has the side effect of defining the function name as a global variable name. Take this example for more clarification:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (a &gt; 1)&lt;br /&gt;function foo() {...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In bad interpreters (Micro$oft JScript for example) foo is always a global variable of type function. It can be called in all cases not only if a &gt; 1!&lt;br /&gt;Need a dangerous scenario? Take this example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (typeof foo == 'undefined')&lt;br /&gt;function foo() {...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Suppose you need to check whether a function is defined or not, and if not define it your own way. This could happen inside a large application where you test if some sources are included and act accordingly. This will not work as expected due to the missbehavior of such interpreter. I faced this problem when writing some code that checks if &lt;a href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt; was included or not. So I wrote:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (typeof $ == 'undefined')&lt;br /&gt;function $(element) {return document.getElementById(element)}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The result was my $ always overriding prototype's $!&lt;br /&gt;The solution is easy, just use:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if (typeof $ == 'undefined')&lt;br /&gt;var $ = function (element) {return document.getElementById(element)}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This way, $ will not be defined unless it is already defined before.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Keep your files small, don't worry about number of files.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;As a general practice, don't place more than 1 class definition in a file. Consider Java public classes where you cannot define more than 1 public class in a file and file name should be the same as that public class. If this has changed in current specification, please tell me as I am not an active Java developer. This will add to modularity and will make your classes more liable to reusability.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Never use alerts for debugging.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;Debugging Javascript code using alerts always proves to be not practical. It pauses execution until the user dismisses the alert. You cannot just put 10 alerts and have them displayed each run waiting for you to dismiss them! Sometimes it is invalid to log through alerts. Suppose you need to simulate real time performance while you are having multiple threads, for AJAX requests as an example. Alerts will ruin the synchronization of threads because they pause their owning threads. Its worth noting that text inside alerts are limited to the display area.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Always use log messages for debugging.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;A better solution for debugging, still not the best, is using log messages rather than alerts. Logging debug information has many benifits of not blocking the running thread, playing the 10 messages with no code interruption and simulating the real time performance of threads. If you are inside a web page, you can log to some text area by modifying its value property. In &lt;a href="http://www.jiggyapp.com/"&gt;Jiggy&lt;/a&gt;, you can use the global function log() to throw away any message to the console. It is important to note that logging is not only for debugging. You have to log your application activity for inspection afterwards. This may help you enhance its performance or monitor user activity.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;li style="font-weight: bold;"&gt;&lt;span style="font-size:130%;"&gt;Consider using dynamic log-levels when your logs become bloated.&lt;/span&gt;&lt;/li&gt;&lt;span style="font-size:85%;"&gt;Following the logging paradigm will render your log stream unreadable. When you add a new log line it will not be noticed among tens and hundreds of other log lines. Thinking of disabling older log lines is not the best solution, you may need to come back and debug something old. By enabling/disabling log lines you will be uncommenting/commenting some code. As a general practice code inside comments is highly discouraged. Actually you will need to debug several aspects continuously, like requests sent/received on network. Thats why log levels are for. However, I don't mean here the basic 4 levels that are widely used: Error, Warning, Info and Debug. These levels are placed according to severity of log. What I mean here is dynamically creating log levels according to different aspects of your application logic. For example, you may have aspects called "Network", "Database", "Rendering", "Flow" and such. Lets call them log aspects as opposed to log levels. When you log any message you define its aspect from these aspects. You may also combine an aspect with one of the 4 basic log levels mentioned above. When you wish to debug warnings from the network aspects you enable Warning level and Network aspect from a central configuration file. Such file may turn on and off all aspects and levels for your application. For example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var ENABLE_LOGS = true&lt;br /&gt;var DEBUG_ASPECT_NETWORK = true&lt;br /&gt;var DEBUG_ASPECT_DATABASE = false&lt;br /&gt;...&lt;br /&gt;var DEBUG_LEVEL_ERROR = false&lt;br /&gt;var DEBUG_LEVEL_WARN = true&lt;br /&gt;...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;and in your log lines:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;LOG("message here", DEBUG_ASPECT_NETWORK &amp;amp;&amp;amp; DEBUG_LEVEL_WARN)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;where LOG is simply defined as:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var LOG = function(message, enabled)&lt;br /&gt;{&lt;br /&gt;if (ENABLE_LOGS &amp;amp;&amp;amp; enabled) log(message)&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can add debug aspects and levels dynamically as your application grows. You can enable/disable aspects and levels as required without commenting/uncommenting your code.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;li&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;If you are working inside a web browser, consider a Javascript debugger.&lt;/span&gt;&lt;/span&gt; For Firefox there is &lt;a href="http://www.mozilla.org/projects/venkman/"&gt;Venkman&lt;/a&gt; and &lt;a href="http://getfirebug.com/"&gt;Firebug.&lt;/a&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt; If your log mechanism didn't help you, you may consider a real debugger which steps you into your code and helps you inspecting variables.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size:85%;"&gt;Thats all for now, stay tuned for a more focused post about writing large-scale Jiggy applications!&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-575277394202390036?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/575277394202390036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=575277394202390036' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/575277394202390036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/575277394202390036'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/09/your-guide-to-writing-large-scale.html' title='Your Guide to Writing Large-Scale Javascript Applications'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-7712767689451252001</id><published>2008-07-25T23:12:00.002+02:00</published><updated>2008-10-04T16:56:57.018+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='symbian'/><title type='text'>Building your first Javascript-powered Symbian application using Webkit</title><content type='html'>&lt;p&gt;The 10-years old &lt;a href="http://www.symbian.com/" class="external text" title="http://www.symbian.com/"&gt;Symbian OS&lt;/a&gt; is the open mobile operating system, that powers millions of smartphone worldwide, especially &lt;a href="http://www.nokia.com/" class="external text" title="http://www.nokia.com/"&gt;Nokia&lt;/a&gt; mobile phones.&lt;br /&gt;Symbian itself is the OS engine that is customized by device manufacturers to produce real operating systems. Symbian has 3 platforms, the S60 which runs mostly on Nokia phones, the UIQ which runs mostly on &lt;a href="http://www.sonyericsson.com/" class="external text" title="http://www.sonyericsson.com/"&gt;Sony Ericsson&lt;/a&gt; and &lt;a href="http://www.motorola.com/" class="external text" title="http://www.motorola.com/"&gt;Motorola&lt;/a&gt;, and the MOAP (new).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Developing for Symbian is an inevitable task for developers targeting mobile platforms. Depending on the target platform, a developer should select a Symbian SDK to use. The S60 platform itself contains a lot of versions with a corresponding SDK for each version. 1st, 2nd and 3rd editions exist, each one having as many as 3 to 4 feature packs. This results in about 9 versions. 1st edition represents Symbian OS v6.1 and the latest is v9.5. &lt;a href="http://developer.symbian.com/main/index.jsp" class="external text" title="http://developer.symbian.com/main/index.jsp"&gt;The Symbian Developer Network (SDN)&lt;/a&gt; and &lt;a href="http://www.forum.nokia.com/" class="external text" title="http://www.forum.nokia.com/"&gt;Forum Nokia&lt;/a&gt; has been always Sybmian developers heaven.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Symbian applications are written in C++ (native) or Java (requires J2ME). The Internet browsing on Symbian started with &lt;a href="http://www.opera.com/" class="external text" title="http://www.opera.com/"&gt;Opera&lt;/a&gt; in its first releases. However, after releasing &lt;a href="http://webkit.org/" class="external text" title="http://webkit.org/"&gt;Webkit&lt;/a&gt; as an open-source project, it has been adopted by Symbian starting from 3rd edition as its default browser engine.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The good news is that you can develop your own Symbian application that links with the Webkit and exploits its capabilities in Javascript interpretation and DOM manipulation. The bad news is that there is no guide, up to my knowledge, that demonstrates this!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So here are simple steps for creating your first Javascript-enabled S60 application:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; First of all, download and build S60Webkit using &lt;a href="http://wiki.forum.nokia.com/index.php/Building_S60Webkit#Configure_Your_Computer" class="external text" title="http://wiki.forum.nokia.com/index.php/Building_S60Webkit#Configure_Your_Computer"&gt;this guide&lt;/a&gt;. Don't panic for build errors, you will find all solutions in this guide. This should work for Carbide.c++ the latest release v1.3. You will need also &lt;a href="http://symbiangeek.blogspot.com/2008/02/change-details-compiling-s60webkit-with.html" class="external text" title="http://symbiangeek.blogspot.com/2008/02/change-details-compiling-s60webkit-with.html"&gt;this guide&lt;/a&gt; because Carbide v1.0 is obsolete. Remember 3 simple rules:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; to build for the emulator use "build -w"&lt;br /&gt;&lt;/li&gt;&lt;li&gt; to build for the device use "build -g"&lt;br /&gt;&lt;/li&gt;&lt;li&gt; to build a special target use "build -? targetname"&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; There is a bug in the Perl script that scans build output to show number of errors/warnings. Find the file in: C:\Symbian\9.1\S60_3rd\Epoc32\tools\scanlog.pm, or change path to your SDK installation path. To fix it, find the condition following the comment:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;code&gt;&lt;/code&gt;# make: *** [SAVESPACECONVTOOL] Error 2&lt;br /&gt;&lt;br /&gt;&lt;p&gt;with&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;if ($line =~ /make(\[\d+\])?:\s*\*\*\*.*(E|e)rror/)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;Start a new project in Carbide.c++ IDE using File-&amp;gt;New-&amp;gt;Symbian OS C++ project and select 3rd-Future ed. GUI application. Follow on-screen steps and you now have a simple HelloWorld application.&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Now its time to link with the Webkit. You will have to edit some header and configuration files to get it working:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; modify S60/JavaScriptCore/kjs/list.h and add&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;#if NOKIA_CHANGES&lt;br /&gt;#include &amp;lt;oom.h&amp;gt;&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;somewhere in the beginning of the file&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt; Edit the project mmp file (&amp;lt;projectname&amp;gt;.mmp) using Carbide IDE visual editor:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; In the libraries tab at the bottom click on Add to add 2 libraries: JavaScriptCore_sdk.lib and MemMan_sdk.lib. If you did not find either then the building of S60Webkit was incomplete.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; In the options tab add 4 entries in the Compiler Settings area:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; User includes: /Symbian/9.1/S60_3rd/s60/JavaScriptCore/kjs&lt;br /&gt;&lt;/li&gt;&lt;li&gt; System includes: /Symbian/9.1/S60_3rd/s60/MemoryManager/Inc and /epoc32/include/libc&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Macros: NOKIA_CHANGES&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Edit the file where you want to write webkit-specific code, for example: xxxxAppUI.cpp:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Include the interpreter header file:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;#include "interpreter.h"&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt; write some code for Javascript interpretation, for example in the handler for first menu action:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;   using namespace KJS;&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;   InterpreterLock lock;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;   Object globalObj(new ObjectImp);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;   Interpreter *interp = new Interpreter(globalObj);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;   UString code = KJS::UString("10 * 5");&lt;br /&gt;&lt;/p&gt;&lt;p&gt;   Completion result = interp-&amp;gt;evaluate(code);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;   ComplType resultType = result.complType();&lt;br /&gt;&lt;/p&gt;&lt;p&gt;   if (resultType == Normal) {&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    // OK&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    textResource = StringLoader::LoadLC(R_MESSAGE_OK);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    // textResource loaded with StringLoader.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    informationNote-&amp;gt;ExecuteLD( *textResource);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    // Pop HBuf from CleanUpStack and Destroy it.&lt;br /&gt;    CleanupStack::PopAndDestroy(textResource);   &lt;br /&gt;&lt;/p&gt;&lt;p&gt;   }&lt;br /&gt;&lt;/p&gt;&lt;p&gt;   else {&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    // failure&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    textResource = StringLoader::LoadLC(R_MESSAGE_FAILURE);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    // textResource loaded with StringLoader.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    informationNote-&amp;gt;ExecuteLD( *textResource);&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    // Pop HBuf from CleanUpStack and Destroy it.&lt;br /&gt;    CleanupStack::PopAndDestroy(textResource);   &lt;br /&gt;&lt;/p&gt;&lt;p&gt;   }&lt;br /&gt;&lt;br /&gt;You may replace the variable "code" with any valid Javascript code.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt; add some string resources for the previous code to compile. In file data/&amp;lt;projectname&amp;gt;.rls add these 2 lines:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;#define qtn_message_ok "OK"&lt;br /&gt;#define qtn_message_failure "Failure"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt; In file data/&amp;lt;projectname&amp;gt;.rss add:&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;code&gt;&lt;br /&gt;RESOURCE TBUF r_message_ok { buf=qtn_message_ok; }&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;RESOURCE TBUF r_message_failure { buf=qtn_message_failure; }&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Build your project for the emulator&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Open the emulator from Start menu and browse to Installed-&amp;gt;&amp;lt;projectname&amp;gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;p&gt;Your application sould open, press the left menu button to show the menu, then select Message and get your previous Javascript evaluated by seeing 'OK'!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I hope I have covered all dark parts, in case something was missing, please comment here to augment any missing part.&lt;br /&gt;&lt;/p&gt;&lt;div class="fivestar-static-form-item"&gt;&lt;div class="form-item"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-7712767689451252001?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/7712767689451252001/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=7712767689451252001' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7712767689451252001'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7712767689451252001'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/07/building-your-first-javascript-powered.html' title='Building your first Javascript-powered Symbian application using Webkit'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-6687608458936137178</id><published>2008-07-25T23:08:00.000+02:00</published><updated>2008-07-25T23:09:03.115+02:00</updated><title type='text'>Which programming language I am</title><content type='html'>&lt;a href="http://www.bbspot.com/News/2006/08/language_quiz.php"&gt;&lt;img src="http://www.bbspot.com/Images/News_Features/2006/08/language/java.jpg" alt="You are Java.  You are very strong and sturdy, but this makes you a bit sluggish." height="90" width="300" border="0" /&gt;&lt;br /&gt;Which Programming Language are You?&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-6687608458936137178?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/6687608458936137178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=6687608458936137178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/6687608458936137178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/6687608458936137178'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/07/which-programming-language-i-am.html' title='Which programming language I am'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-8312781469630217192</id><published>2008-06-22T14:59:00.000+02:00</published><updated>2008-06-22T15:01:01.076+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>Only idiots change their iPhone root password!</title><content type='html'>&lt;p&gt;If you are a happy &lt;a href="http://www.apple.com/iphone/" class="external text" title="http://www.apple.com/iphone/"&gt;iPhone&lt;/a&gt; owner and you are an &lt;a href="http://en.wikipedia.org/wiki/Secure_Shell" class="external text" title="http://en.wikipedia.org/wiki/Secure_Shell"&gt;ssh&lt;/a&gt; geek, then the first thing you will install on your iPhone is &lt;a href="http://blog.psmxy.org/pkg-info/openssh/" class="external text" title="http://blog.psmxy.org/pkg-info/openssh/"&gt;OpenSSH&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You will be happy with the installation, but you will find no GUI on your device, so it is supposedly accepting your ssh connections. Great, now find your iPhone IP and go ssh it with root login. Of course it is not passwordless, after googling this you will find it is 'dottie' prior to firmware 1.1.1 and 'alpine' later on. In the same site (&lt;a href="http://blog.psmxy.org/pkg-info/openssh/" class="external text" title="http://blog.psmxy.org/pkg-info/openssh/"&gt;OpenSSH&lt;/a&gt;) you are advised to change your root password, so intuitive: "You should change your password, after you install OpenSSH. Everyone knows the default password".&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Now login, fire passwd command and change it. Congratulations, you have put your iPhone in a wreck! After restarting it you will get a notice "Edit home screen" and the springboard crashes and restarts infinitely! If you try to connect it to your Mac or PC to reset it, or even &lt;a href="http://www.ziphone.org/" class="external text" title="http://www.ziphone.org/"&gt;jailbreak&lt;/a&gt; it, you will find your Mac/PC clueless and can't even discover the device.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Being trapped in such frustration for more than an hour, I finally found &lt;a href="http://blog.matsimitsu.nl/english/183/howto-fix-the-edit-home-screen-loop-for-iphone" class="external text" title="http://blog.matsimitsu.nl/english/183/howto-fix-the-edit-home-screen-loop-for-iphone"&gt;someone&lt;/a&gt; talking about this problem and saying that changing the root password causes this and one should restore the old password files. The hard point is that I changed the password and did a lot of things then restarted the device so I never related the problem to its real cause.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;So, the passwd binary is not working for the iPhone. Either don't change your password or hash it manually using the &lt;a href="http://blog.matsimitsu.nl/english/183/howto-fix-the-edit-home-screen-loop-for-iphone" class="external text" title="http://blog.matsimitsu.nl/english/183/howto-fix-the-edit-home-screen-loop-for-iphone"&gt;guide above&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;phew, restarting your iPhone now solves the problem. Play wisely, even conservatively, with your little cute iPhone.&lt;br /&gt;&lt;/p&gt;&lt;div class="fivestar-static-form-item"&gt;&lt;div class="form-item"&gt;&lt;br /&gt; &lt;div class="fivestar-widget-static fivestar-widget-static-5 clear-block"&gt;&lt;div class="star star-1 star-odd star-first"&gt;&lt;span class="off"&gt;0&lt;/span&gt;&lt;/div&gt;&lt;div class="star star-2 star-even"&gt;&lt;span class="off"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="star star-3 star-odd"&gt;&lt;span class="off"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="star star-4 star-even"&gt;&lt;span class="off"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="star star-5 star-odd star-last"&gt;&lt;span class="off"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt; &lt;div class="description"&gt;&lt;div class="fivestar-summary fivestar-summary-"&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-8312781469630217192?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/8312781469630217192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=8312781469630217192' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8312781469630217192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8312781469630217192'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/06/only-idiots-change-their-iphone-root.html' title='Only idiots change their iPhone root password!'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4555091244689154566</id><published>2008-05-28T13:50:00.003+02:00</published><updated>2008-05-28T19:56:20.957+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><title type='text'>Firefox bug: deceiving select onchange event</title><content type='html'>I have been experiencing a silly bug in Firefox for 2 years now. It happens on my Ubuntu (Gnome) and formerly on Debian (Gnome too). I tried it on a Windows machine but it didn't work.&lt;br /&gt;As usual, I am lazy to try it on all available platforms, so please help me in your comments!&lt;br /&gt;&lt;h4&gt;Bug description:&lt;/h4&gt;&lt;br /&gt;If a select element has no option selected (selectedIndex == -1), an outside-select click behavior deceives the browser to fire the onchange event for the select.&lt;br /&gt;&lt;h4&gt;How to reproduce bug:&lt;/h4&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Click to open a select element&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Move your mouse over any option (make sure the option is highlighted, but don't click on anything)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Click outside the select twice&lt;/li&gt;&lt;br /&gt;&lt;li&gt;As a result of the bug, the onchange event is fired with the option under mouse as the select value&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;To see an example, the bug is illustrated &lt;a href="http://downloads.hammady.net/select-gnome-bug.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I tried it on Ubuntu (Gnome and KDE) and it happens too.&lt;br /&gt;I tried also on Firefox for Windows (through &lt;a href="http://www.winehq.org/"&gt;wine&lt;/a&gt;) and it happens too!&lt;br /&gt;&lt;br /&gt;Now what?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4555091244689154566?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4555091244689154566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4555091244689154566' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4555091244689154566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4555091244689154566'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/05/firefoxgnome-bug-deceiving-select.html' title='Firefox bug: deceiving select onchange event'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-5348054361848316436</id><published>2008-05-28T11:09:00.003+02:00</published><updated>2008-05-28T12:03:57.546+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>SELECT threads FROM GMail ORDER BY sender, subject, thread_activity</title><content type='html'>GMail is a very good mail service, it has a lot of useful features, mainly searching. However, it misses a very important feature: sorting. Someone may argue, why sort while you can find any message using fast search? I say, sometimes you want to view your threads sorted alphabetically when you don't know the exact phrases to search with.&lt;br /&gt;&lt;br /&gt;I wrote a Javascript &lt;a href="http://en.wikipedia.org/wiki/Bookmarklet"&gt;bookmarklet&lt;/a&gt; (GMail Sorter) to add sort controls in your GMail Inbox view. Once you enable the bookmarklet, you can see the following above your threads:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_Fxxo5JtY8z8/SD0hkvAL2rI/AAAAAAAAABs/26A3AipSynE/s1600-h/gmail-sorter.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_Fxxo5JtY8z8/SD0hkvAL2rI/AAAAAAAAABs/26A3AipSynE/s400/gmail-sorter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5205353659286411954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Clicking on the links asc/desc sorts visible threads by sender, subject or thread activity. Actually I wrote this bookmarklet mainly for the thread activity feature. Sometimes I don't have time to check community messages, until I come back after several days to see a lot of unread messages there. I wished there could be a way to sort them by their activity: threads that more people have replied on seems more interesting, I need to read them first.&lt;br /&gt;&lt;br /&gt;The bookmarklet is heavily based on &lt;a href="https://www.squarefree.com/bookmarklets/pagedata.html#sort_table"&gt;another bookmarklet&lt;/a&gt; which adds sort controls to all tables in page. Actually what I did was customizing that bookmarklet to work on GMail Inbox and adding different sort criteria. The sorting code is taken almost as is.&lt;br /&gt;&lt;br /&gt;If you just need to use the bookmarklet and don't care about some implementation details, you can skip to section "How to install" below.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How GMail Sorter is different&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;Let me refer to that bookmarklet as B and mine as M. In B, all tables are tampered. In M only the Inbox table is tampered. It was a challenge finding the Inbox. Guys at Google seem to obfuscate ids and class names for all DOM elements. For example, they are something like 1d3f, 3xua,...&lt;br /&gt;I attacked this issue by finding the "widest table". The Inbox table happens to be the 2nd widest table, where the notification area that appears on top of the table is the 1st widest one. However, the Inbox table does have an id and the notification area does not. So I find it by getting the widest table having an id:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function getWidestTable(tables) {&lt;br /&gt;    var maxTable = undefined;&lt;br /&gt; var maxWidth = -1;&lt;br /&gt; for (var i = 0; i &lt; tables.length; i++) {&lt;br /&gt;  var table = tables[i];&lt;br /&gt;  if (table.clientWidth &gt;= maxWidth &amp;&amp; table.id != '') {&lt;br /&gt;   maxWidth = table.clientWidth;&lt;br /&gt;   maxTable = table;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; return maxTable;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Applying B on GMail will give you an alert: "This page does not contain any tables". Wow, all these tables and B can't find it! The problem is that B searches for table tags in current document. In M, I had to iterate through all iframes and search in tables in their documents. Shortly I discovered that the Inbox table exists in an iframed named "canvas_iframe", so the code became a little simpler:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function getAllTables() {&lt;br /&gt; g_tables = toArray(document.getElementsByTagName('table'));&lt;br /&gt; var iframe = document.getElementById('canvas_frame');&lt;br /&gt; if (!iframe) return null;&lt;br /&gt; var iframedoc = iframe.contentDocument.document || iframe.contentWindow.document;&lt;br /&gt; iframetables = toArray(iframedoc.getElementsByTagName('table'));&lt;br /&gt; if (iframetables.length)&lt;br /&gt;  g_tables = g_tables.concat(iframetables);&lt;br /&gt; if (!g_tables.length)&lt;br /&gt;  return null;&lt;br /&gt; return g_tables;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How to install:&lt;/h3&gt;&lt;br /&gt;In Firefox, Just create a new bookmark and paste the following code in the URL:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;javascript:function toArray (c) {var a, k;a = new Array;for (k=0; k &lt; c.length; ++k)a[k] = c[k];return a;}function insAtTop(par,child) {if (par.childNodes.length)par.insertBefore(child, par.childNodes[0]);else par.appendChild(child);}function countCols(tab) {var nCols, i;nCols = 0;for(i = 0; i&lt;tab.rows.length; ++i)if (tab.rows[i].cells.length &gt; nCols)nCols = tab.rows[i].cells.length;return nCols;}function makeHeaderLink(colNo, ord, regex, numeric) {var link;link = document.createElement('a');link.href = '#';link.onclick = function() {var __st = window == top ? window : top;__st.sortTable(colNo, ord, regex, numeric);return false;};link.appendChild(document.createTextNode((ord&gt;0)? 'asc':'desc'));return link;}function makeSortControl(header, col, title, regex, numeric) {header.appendChild(document.createTextNode(title + ' ['));header.appendChild(makeHeaderLink(col, 1, regex, numeric));header.appendChild(document.createTextNode('/'));header.appendChild(makeHeaderLink(col, -1, regex, numeric));header.appendChild(document.createTextNode(']'));}function makeHeader(nCols) {var header, headerCell, i;header = document.createElement('span');/*put links in columns 2 and 4 only (sender, subject)*/makeSortControl(header, 2, 'Sender(s)');header.appendChild(document.createTextNode(' | '));makeSortControl(header, 4, 'Subject');header.appendChild(document.createTextNode(' | '));makeSortControl(header, 2, 'Thread Activity', /\(\d*\)$/, true);return header;}function getWidestTable(tables) {var maxTable = undefined;var maxWidth = -1;for (var i = 0; i&lt;tables.length; i++) {var table = tables[i];if (table.clientWidth &gt;= maxWidth &amp;&amp; table.id != '') {maxWidth = table.clientWidth;maxTable = table;}}return maxTable;}function getAllTables() {g_tables = toArray(document.getElementsByTagName('table'));var iframe = document.getElementById('canvas_frame');if (!iframe)return null;var iframedoc = iframe.contentDocument.document || iframe.contentWindow.document;iframetables = toArray(iframedoc.getElementsByTagName('table'));if (iframetables.length)g_tables = g_tables.concat(iframetables);if (!g_tables.length)return null;return g_tables;}(function () {/* ----  main() ---- ENTRY POINT HERE ------------------------- */g_tables = getAllTables();if (!g_tables) {alert(&amp;quot;It seems that this script is not compatible with your gmail version (no tables), giving up!&amp;quot;);return;}inboxtable = getWidestTable(g_tables);if (inboxtable.id.length&lt;4) {alert(&amp;quot;It seems that this script is not compatible with your gmail version (no inbox), giving up!&amp;quot;);return;}var control = makeHeader(countCols(inboxtable));var tableparent = inboxtable.parentNode.parentNode;while(tableparent.previousSibling.style.display == 'none')tableparent = tableparent.previousSibling;tableparent.previousSibling.appendChild(control);/*tableparent.parentNode.insertBefore(control, tableparent);*/}) ();function compareRows(a,b) {if (a.sortKey == b.sortKey)return 0;return (a.sortKey &lt; b.sortKey) ? g_order : -g_order;}function compareRowsNumeric(a,b) {if (a.sortKey == b.sortKey)return 0;return ((a.sortKey + '').match(/\d+/) - (b.sortKey + '').match(/\d+/)) * g_order;}function sortTable(colNo, ord, regex, numeric) {var table, rows, nR, bs, i, j, temp;g_order = ord;g_colNo = colNo;g_tables = getAllTables();table = getWidestTable(g_tables);rows = new Array();nR = 0;bs = table.tBodies;for (i = 0; i &lt; bs.length; ++i)for(j=0; j &lt; bs[i].rows.length; ++j) {rows[nR] = bs[i].rows[j];temp = rows[nR].cells[g_colNo];if (!temp)rows[nR].sortKey = '';else if (!regex)rows[nR].sortKey = temp.textContent.toLowerCase();else {var val = temp.textContent.toLowerCase().match(regex);rows[nR].sortKey = val ? val : '';}++nR;}if (numeric)rows.sort(compareRowsNumeric);else rows.sort(compareRows);for (i = 0; i &lt; rows.length; ++i)insAtTop(table.tBodies[0], rows[i]);}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Put it in the Bookmarks Toolbar folder so that it is always visible. Anytime you need to enable the bookmarklet, open your Inbox view (or any messages view) and click on the bookmark you have just created. You will see a sort control added on top of the table. Play and enjoy!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How to modify:&lt;/h3&gt;&lt;br /&gt;If you are a Javascript geek and need to play with the code, &lt;a href="http://downloads.hammady.net/sorttables.js"&gt;here&lt;/a&gt; is a clear source where you can play with. After playing you will have to remove all new lines and prepend "javascript:" to form a valid URL that will fit in a bookmark. Don't worry, here is a one-liner to do this task:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(echo "javascript:" ; cat sorttables.js) | tr -d "\n\t" &gt; sorttables_bookmarklet.js&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This will read in the file sorttables.js that contains your code and outputs a file sorttables_bookmarklet.js where you can grasp its contents and paste it in your bookmark URL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-5348054361848316436?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/5348054361848316436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=5348054361848316436' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/5348054361848316436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/5348054361848316436'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/05/select-threads-from-gmail-order-by.html' title='SELECT threads FROM GMail ORDER BY sender, subject, thread_activity'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp0.blogger.com/_Fxxo5JtY8z8/SD0hkvAL2rI/AAAAAAAAABs/26A3AipSynE/s72-c/gmail-sorter.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-8028707698044301197</id><published>2008-05-08T13:42:00.001+02:00</published><updated>2008-05-08T13:44:56.836+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><title type='text'>Upgrading unupgradable Firefox extensions</title><content type='html'>&lt;div class="content"&gt;&lt;br /&gt;    &lt;p&gt;To their bad fortune, many of you may have already upgraded to Firefox 3 beta. Ouch!&lt;br /&gt;You may have also tried to upgrade your extensions and found most of them failed to do :(&lt;br /&gt;Now you have either of 2 solutions:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; downgrade back to Firefox 2&lt;br /&gt;&lt;/li&gt;&lt;li&gt; force upgrade of your extensions&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;"2" seems nice, huh?&lt;br /&gt;OK, lets go straight, now follow me on these:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; Any extension is an .xpi file (pronounced as zippy), download the .xpi. If you click on a .xpi link in Firefox it will be installed instead, so you can get it with any other browser, or right-click and Save as... You can also type the following in a shell: &lt;code&gt;wget XPI_URL&lt;/code&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Extract the .xpi with any archive manager (it is actually a ZIP file renamed)&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Open install.rdf with any text editor&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Locate the line: &lt;em:maxVersion&gt;...&lt;/em:maxVersion&gt; and replace this value to something like 3.0b5. This will make your extension &lt;i&gt;pretend&lt;/i&gt; to work on up to FF3 beta5!&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Now zip back your files and drag on any Firefox open window and it will automatically install.&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Enjoy!&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;IMPORTANT&lt;/b&gt;:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt; The new archive you created in step 5 MUST have the extension .xpi&lt;br /&gt;&lt;/li&gt;&lt;li&gt; Files in the archive should be directly on the root not inside an internal directory&lt;br /&gt;&lt;/li&gt;&lt;li&gt; The extension will claim to work on your browser, but it may not function as you expect, simply because the extension maker did not test it on your version. So forcing it to work is solely on your responsibility with NO WARRANTY!&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-8028707698044301197?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/8028707698044301197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=8028707698044301197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8028707698044301197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8028707698044301197'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/05/upgrading-unupgradable-firefox.html' title='Upgrading unupgradable Firefox extensions'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-8273048282548966485</id><published>2008-05-08T13:39:00.001+02:00</published><updated>2008-05-08T13:42:30.038+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Busting Javascript alerts</title><content type='html'>&lt;p&gt;Sometimes it is annoying to see alerts every now and then in web pages. It is not practical to switch off alerts altogether (see &lt;a href="http://www.mozilla.org/projects/security/components/ConfigPolicy.html" class="external text" title="http://www.mozilla.org/projects/security/components/ConfigPolicy.html"&gt;this&lt;/a&gt;), however it may seem convenient to get control over alerts and do whatever actions: mute, show somewhere else, ...&lt;br /&gt;It is simple like overriding the &lt;code&gt;window.alert&lt;/code&gt; function:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;br /&gt;window.alert = function(msg)&lt;br /&gt;{&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt; // do whatever, for example:&lt;br /&gt; document.title = "busted alert: " + msg&lt;br /&gt; var div = document.getElementById('divid').innerHTML = msg&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Of course this is applicable for &lt;code&gt;window.confirm&lt;/code&gt; and &lt;code&gt;window.prompt&lt;/code&gt; too.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This may appear trivial and useless. However, you can elevate its potential in 2 ways:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;First: You can bust alerts of embedded iframes by getting a reference to its content window:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;br /&gt;function loaded(iframe) {&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt; var iframe = document.getElementById('iframeid')&lt;br /&gt; // or iframe = document.frames[0]&lt;br /&gt; // or iframe = document.frames[frame_name]&lt;br /&gt; // or just use the iframe function argument above&lt;br /&gt; iframe.contentWindow.alert = function(msg) {...}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You will have to put previous code in the onload function of the iframe:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;iframe onload="loaded(this)&amp;gt;&amp;lt;/iframe&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I tried this on both Firefox2 and IE7 and it worked with no problems. Other browsers?&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The other way to make this useful is to install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748" class="external text" title="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;Greasemonkey&lt;/a&gt; and create a new user script containing the overriding code.&lt;br /&gt;You will have to access the &lt;a href="http://wiki.greasespot.net/UnsafeWindow" class="external text" title="http://wiki.greasespot.net/UnsafeWindow"&gt;unsafe window object&lt;/a&gt; to do so:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;&lt;br /&gt;unsafeWindow.alert = function(msg){...}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This way you can do anything to alerts coming from any site that will run the user script.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-8273048282548966485?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/8273048282548966485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=8273048282548966485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8273048282548966485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8273048282548966485'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/05/busting-javascript-alerts.html' title='Busting Javascript alerts'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-3684612747698656736</id><published>2008-03-30T07:17:00.005+02:00</published><updated>2008-03-30T07:30:59.679+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='islamic'/><title type='text'>Prophet Muhammad`s (PBUH) Farewell Sermon</title><content type='html'>(Taken from &lt;a href="http://www.islamicity.com/articles/Articles.asp?ref=IC0107-322"&gt;IslamiCity)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This sermon was delivered by Prophet Muhammad (PBUH) on the Ninth Day of Dhul Hijjah 10 A.H. in the 'Uranah valley of Mount Arafat' (in Mecca).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.islamicity.com/islamitv/?ref=5739"&gt;Audio&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;AKA: خطبة الوداع&lt;span style="color: rgb(0, 0, 0);font-family:Verdana,Arial,Helvetica;font-size:85%;"  &gt;                 &lt;div id="divTextContent"&gt;&lt;p align="left"&gt;&lt;span style=";font-family:Verdana,arial;font-size:85%;"  &gt;After praising, and thanking Allah he said:&lt;/span&gt;&lt;/p&gt; &lt;div align="center"&gt;   &lt;center&gt;   &lt;table style="float: left;" border="0" cellpadding="2" cellspacing="4" width="17%"&gt;     &lt;tbody&gt;&lt;tr&gt;       &lt;td width="100%"&gt;&lt;img src="http://www.islamicity.com/global/images/photo/Islam/Arafat_ic%5B175x156%5D.JPG" border="0" height="156" width="175" /&gt;&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;   &lt;/center&gt; &lt;/div&gt; &lt;h3&gt; &lt;code&gt;"O People, lend me an attentive ear, for I know not whether after this year, I shall ever be amongst you again. Therefore listen to what I am saying to you very carefully and TAKE THESE WORDS TO THOSE WHO COULD NOT BE PRESENT HERE TODAY.&lt;br /&gt;&lt;br /&gt;O People, just as you regard this month, this day, this city as Sacred, so regard the life and property of every Muslim as a sacred trust. Return the goods entrusted to you to their rightful owners. Hurt no one so that no one may hurt you. Remember that you will indeed meet your Lord, and that He will indeed reckon your deeds. ALLAH has forbidden you to take usury (interest), therefore all interest obligation shall henceforth be waived. Your capital, however, is yours to keep. You will neither inflict nor suffer any inequity. Allah has Judged that there shall be no interest and that all the interest due to Abbas ibn 'Abd'al Muttalib (Prophet's uncle) shall henceforth be waived...&lt;br /&gt;&lt;br /&gt;Beware of Satan, for the safety of your religion. He has lost all hope that he will ever be able to lead you astray in big things, so beware of following him in small things.&lt;br /&gt;&lt;br /&gt;O People, it is true that you have certain rights with regard to your women, but they also have rights over you. Remember that you have taken them as your wives only under Allah's trust and with His permission. If they abide by your right then to them belongs the right to be fed and clothed in kindness. Do treat your women well and be kind to them for they are your partners and committed helpers. And it is your right that they do not make friends with any one of whom you do not approve, as well as never to be unchaste.&lt;br /&gt;&lt;br /&gt;O People, listen to me in earnest, worship Allah, say your five daily prayers (Salah), fast during the month of Ramadan, and give your wealth in Zakat. Perform Hajj if you can afford to.&lt;br /&gt;&lt;br /&gt;All mankind is from Adam and Eve, an Arab has no superiority over a non-Arab nor a non-Arab has any superiority over an Arab; also a white has no superiority over black nor a black has any superiority over white except by piety and good action. Learn that every Muslim is a brother to every Muslim and that the Muslims constitute one brotherhood. Nothing shall be legitimate to a Muslim which belongs to a fellow Muslim unless it was given freely and willingly. Do not, therefore, do injustice to yourselves.&lt;br /&gt;&lt;br /&gt;Remember, one day you will appear before Allah and answer your deeds. So beware, do not stray from the path of righteousness after I am gone.&lt;br /&gt;&lt;br /&gt;O People, no prophet or apostle will come after me and no new faith will be born. Reason well, therefore, O People, and understand words which I convey to you. I leave behind me two things, the QURAN and my example, the SUNNAH and if you follow these you will never go astray.&lt;br /&gt;All those who listen to me shall pass on my words to others and those to others again; and may the last ones understand my words better than those who listen to me directly. Be my witness, O Allah, that I have conveyed your message to your people". &lt;/code&gt; &lt;/h3&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And here I am conveying the message to you, for those who didn't hear it before.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-3684612747698656736?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/3684612747698656736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=3684612747698656736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/3684612747698656736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/3684612747698656736'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/prophet-muhammads-pbuh-farewell-sermon.html' title='Prophet Muhammad`s (PBUH) Farewell Sermon'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-1128860209645690099</id><published>2008-03-30T05:56:00.008+02:00</published><updated>2008-03-30T06:15:16.029+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><title type='text'>Footnotes from floats in LaTeX: problem &amp; solution</title><content type='html'>(Excerpted from &lt;a href="http://rhaptos.org/devblog/cbearden/blogentry.2007-09-28.4935639575"&gt;Rhaptos Software Development&lt;/a&gt; )&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;a href="http://blog.hammady.net/2008/03/tex-latex-lyx-authors-kit-and-more.html"&gt;LaTeX&lt;/a&gt; has floating environments, of which tables and figures are the most important. Footnotes from within those environments are problematic.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The LaTeX engine will by default move floats around, even onto different pages, in order to achieve optimal horizontal and vertical page layouts. Human book editors and typesetters do the same thing when preparing books for press.&lt;br /&gt;&lt;br /&gt;Because of the way the LaTeX engine handles floats, footnotes from within them are problematic. In the normal case, the author inserts a &lt;code&gt;\footnote{}&lt;/code&gt; command with the footnote text within the curly braces into the text at the point where the footnote marker should appear:&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;This is my blog\footnote{Actually, it is hosted at Google} site.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;However, if the author is making a footnote from within a float environment, one inserts a &lt;code&gt;\footnotemark&lt;/code&gt; command into the text in the float at the point where the footnote mark should appear, and then after the end of the float, one tacks on a &lt;code&gt;\footnotetext{}&lt;/code&gt; command with the text of the footnote in it:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;\begin{figure}&lt;br /&gt;\includegraphics{blorgy.png}&lt;br /&gt;\caption{This figure caption has a footnote.\footnotemark}&lt;br /&gt;\end{figure}&lt;br /&gt;\footnotetext{This is the text of the footnote.}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The &lt;code&gt;\footnotemark&lt;/code&gt; command increments the footnote counter, so if you have more than one &lt;code&gt;\footnotemark&lt;/code&gt; before the &lt;code&gt;\footnotetext{}&lt;/code&gt; commands, you have to set the footnote counter back so that the first &lt;code&gt;\footnotetext{}&lt;/code&gt; doesn't get the count of the last &lt;code&gt;\footnotemark&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;\begin{figure}&lt;br /&gt;\includegraphics{blorgy.png}&lt;br /&gt;\caption{This figure caption has a footnote.\footnotemark}&lt;br /&gt;In fact, it has two.\footnotemark&lt;br /&gt;\end{figure}&lt;br /&gt;\addtocounter{footnote}{-2}&lt;br /&gt;\stepcounter{footnote}\footnotetext{This is the text of the first footnote.}&lt;br /&gt;\stepcounter{footnote}\footnotetext{This is the text of the second footnote.}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And that's it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-1128860209645690099?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/1128860209645690099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=1128860209645690099' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1128860209645690099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1128860209645690099'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/footnotes-from-floats-in-latex-problem.html' title='Footnotes from floats in LaTeX: problem &amp; solution'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-7836013505754359308</id><published>2008-03-29T13:29:00.002+02:00</published><updated>2008-03-29T14:17:12.861+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='health'/><title type='text'>Health - Important Tips</title><content type='html'>I got this by email (thanks uncle Alaa), please comment if you find anything untrue.&lt;br /&gt;&lt;ol&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Answer the phone by LEFT ear.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt; &lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Do not drink coffee Twice day.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(96, 0, 191);"&gt; &lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Do not take pills with COOL water.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt; &lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Do not have HUGE meals after 5pm.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(96, 0, 191);"&gt; &lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Reduce the amount of OILY food you consume.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt; &lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Drink more WATER in the morning, less at night.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(96, 0, 191);"&gt; &lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Keep your distance from hand phone CHARGERS.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt; &lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Do not use headphones/earphone for LONG period of time.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="color: rgb(96, 0, 191);"&gt; &lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Best sleeping time is from 10pm at night to 6amin the morning.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt; &lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(96, 0, 191);font-family:comic sans ms;font-size:100%;"  &gt;&lt;b&gt;Do not lie down immediately after  taking medicine before sleeping.&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;  &lt;/li&gt;&lt;li style="margin: 0cm 0cm 0pt; line-height: 12pt;"&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="font-family:comic sans ms;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(96, 0, 191);"&gt;&lt;b&gt;When &lt;span style="color: rgb(96, 0, 191);"&gt;bat&lt;/span&gt;&lt;/b&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="font-family:comic sans ms;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(96, 0, 191);"&gt;&lt;b&gt;tery&lt;/b&gt; &lt;/span&gt;&lt;/span&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="color: rgb(96, 0, 191);"&gt;is down to the LAST grid/bar, do not&lt;/span&gt; &lt;span style="color: rgb(96, 0, 191);"&gt;answer&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="font-family:comic sans ms;"&gt;&lt;b&gt;&lt;span style="color: rgb(96, 0, 191);font-size:100%;" &gt; the phone as the &lt;/span&gt;&lt;span style=";font-size:10;color:black;"  &gt;&lt;span style="color: rgb(128, 255, 0);font-family:comic sans ms;font-size:100%;"  &gt;&lt;span style="color: rgb(96, 0, 191);"&gt;radiatiion is 1000 times&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-7836013505754359308?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/7836013505754359308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=7836013505754359308' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7836013505754359308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/7836013505754359308'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/health-important-tips.html' title='Health - Important Tips'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-8195966183444269497</id><published>2008-03-25T11:40:00.002+02:00</published><updated>2008-03-25T11:50:33.542+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>I love Egypt, but...</title><content type='html'>Do I love Egypt? I have to love my country. So why they imprisoned me for a whole year plus 45 days as a soldier? I wish I have practiced something useful when fighting comes. Instead I practiced writing letters, cleaning bathrooms and even electing good bean and rice particles to cook.&lt;br /&gt;&lt;br /&gt;I still love Egypt, I have to. So why they took my driving license today? Should this solve corruption? Is this the only possible way to raise our country instead of busting rich thieves? Does everyone in his vehicle wrap his seat belt? Or it was only because I am long-bearded and my wife is wearing black?&lt;br /&gt;&lt;br /&gt;I still love Egypt, but 26 years are enough and Egypt is not Syria!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-8195966183444269497?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/8195966183444269497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=8195966183444269497' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8195966183444269497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/8195966183444269497'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/i-love-egypt-but.html' title='I love Egypt, but...'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-1400700987766943247</id><published>2008-03-24T15:04:00.006+02:00</published><updated>2008-03-30T06:16:39.356+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jabber/xmpp'/><title type='text'>OpenFire: a Java Jabber/XMPP server</title><content type='html'>&lt;a href="http://www.igniterealtime.org/projects/openfire/index.jsp"&gt;OpenFire&lt;/a&gt; is an open source project from &lt;a href="http://www.igniterealtime.org/index.jsp"&gt;igniterealtime&lt;/a&gt;. It is an IM (Instant Messaging) server that can be installed on any&lt;br /&gt;corporate private network to provide IM solutions to its community. It uses the popular &lt;a href="http://www.jabber.org/"&gt;Jabber&lt;/a&gt;/&lt;a href="http://www.xmpp.org/"&gt;XMPP&lt;/a&gt; protocol so you can communicate with it through almost any multi-protocol IM client (&lt;a href="http://www.pidgin.im/"&gt;Pidgin&lt;/a&gt; for example). It has a counterpart IM client, &lt;a href="http://www.igniterealtime.org/projects/spark/index.jsp"&gt;Spark&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;OpenFire has many plugins that extend its functionality. Examples are IM Gateway, SIP phone, Content Filter... The IM Gateway enables you to connect to other networks (&lt;a href="http://messenger.yahoo.com/"&gt;Yahoo! IM&lt;/a&gt;, &lt;a href="http://get.live.com/messenger/overview"&gt;MSN&lt;/a&gt;, &lt;a href="http://www.google.com/talk/"&gt;Google Talk&lt;/a&gt;, ...). Support for such protocols in a Jabber server is a built-in functionality in the XMPP (Extensible Messaging and Presence Protocol) itself. In an XMPP server you may broadcast any number of services so that your XMPP clients can perform service discovery and "register" in such services. Once they are registered, they can "log in" and "log out" from services through the XMPP exchange. Services may add/remove to registered users' rosters (contact-lists). You can send/receive messages to/from your roster contacts. All of this through the XMPP XML messages. The XMPP server takes the responsibility of implementing service-specific protocols, on behalf of clients.&lt;br /&gt;&lt;br /&gt;Building on this, OpenFire created the Gateway IM plugin that implements famous IM protocols: Yahoo!, MSN, GTalk, ICQ,... You can implement your own protocol and configure the plugin to broadcast it as a service. Your Jabber clients can discover such new service and log in to their favorite networks without touching the client.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-1400700987766943247?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/1400700987766943247/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=1400700987766943247' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1400700987766943247'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/1400700987766943247'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/openfire-is-open-source-project-from.html' title='OpenFire: a Java Jabber/XMPP server'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-6364480493165829153</id><published>2008-03-24T12:11:00.004+02:00</published><updated>2008-03-24T15:48:01.252+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><title type='text'>LaTeX problem: Integrating ArabTeX with LLNCS</title><content type='html'>LaTeX, the typesetting system enables you to produce high-quality documents with less effort. &lt;a href="http://blog.hammady.net/2008/03/tex-latex-lyx-authors-kit-and-more.html"&gt;Read more&lt;/a&gt; in my other post about LaTeX. On submitting to a conference, I had to work with their class files so I used &lt;code&gt;\documentclass{llncs}&lt;/code&gt;. They use LaTeX Lecture Notes in Computer Science (&lt;a href="http://www.springer.com/computer/lncs?SGWID=0-164-7-72376-0#anchor5"&gt;llncs&lt;/a&gt;) from &lt;a href="http://www.springer.com/"&gt;Springer&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;  In the same document, I use &lt;a href="http://en.wikipedia.org/wiki/ArabTeX"&gt;ArabTeX&lt;/a&gt; package to render Arabic characters. When I applied both packages I found that section numbers disappered! So instead of "1. Introduction" and "1.2 Title" I got "Introduction" and "Title". After spending an hour or two I found that ArabTeX redefines the section formatting command &lt;code&gt;\section&lt;/code&gt; using &lt;code&gt;\renewcommand&lt;/code&gt; in asect.sty. So I disabled the inclusion of such file in apatch.sty by commenting the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;%\UsePackage {asect} % load LaTeX extensions for Arabic sections.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;  For a normal LaTeX installation, all files exist in &lt;code&gt;/usr/share/texmf/tex/latex/arabtex/&lt;/code&gt;&lt;br /&gt;I don't know who will ever make use of this piece of information, just spreading the word. Let &lt;a href="http://www.google.com/"&gt;Google&lt;/a&gt; help me in that!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-6364480493165829153?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/6364480493165829153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=6364480493165829153' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/6364480493165829153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/6364480493165829153'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/latex-problem-integrating-arabtex-with.html' title='LaTeX problem: Integrating ArabTeX with LLNCS'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-5958451976389598746</id><published>2008-03-24T12:00:00.004+02:00</published><updated>2008-03-24T15:48:28.877+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latex'/><title type='text'>TeX, LaTeX, LyX: Authors kit and more</title><content type='html'>If you are related to IT and computer industry, most probably you heard about these terms. Its all about documents preparation. If you have used Microsoft Word (sorry, no hyperlink here) or &lt;a href="http://www.openoffice.org/"&gt;OpenOffice.org&lt;/a&gt; then you have already practiced with document processing systems.&lt;br /&gt;&lt;br /&gt; So what is the difference between document preparation and processing? The latter are &lt;a href="http://en.wikipedia.org/wiki/WYSIWYG"&gt;WYSIWYG&lt;/a&gt; systems. You take care of everything to see it as you want to get it. It is a convinient matter for small documents. However, if you are preparing a technical paper or a thesis then those won't save you much. In such complex documents you include figures, tables, complex equations and refer to them by numbers. You include a lot of citations and footnotes. You may even number your pages in different manners in the same document. You don't want to track such numberings so that moving any section around won't mess with the numbers.&lt;br /&gt;&lt;br /&gt; You might say Word supports many such features. In Word you have to format eveything, nevertheless you may select styles to be applied to different sections. Changing the format of the style will make you pass over all formatted instances. On the contrary, in &lt;a href="http://en.wikipedia.org/wiki/TeX"&gt;TeX&lt;/a&gt;, the typesetting system, you only define your logical structure instead of formatting constructs. You define &lt;code&gt;\title&lt;/code&gt;, &lt;code&gt;\author&lt;/code&gt;, &lt;code&gt;\chapter&lt;/code&gt;, &lt;code&gt;\section&lt;/code&gt;, &lt;code&gt;\subsection&lt;/code&gt;... and the TeX (or &lt;a href="http://www.latex-project.org/"&gt;LaTeX&lt;/a&gt;) compiler will take care of the formatting according to &lt;code&gt;\documentclass&lt;/code&gt;, whether it is book, article, CV or whatever.&lt;br /&gt;&lt;br /&gt; If you aim at posting your paper to a technical conference, you have to abide to formatting rules of the conference. This is simply done by downloading the class files specific to that conference (usually available at the conference site) and including them in your document. Just run the LaTeX compiler and you instantly have a PostScript/PDF conforming to the conference style.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.wolfram.com/products/publicon/samples/images/LaTeX.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www.wolfram.com/products/publicon/samples/images/LaTeX.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt; TeX, LaTeX? What is the difference? TeX is a macro language invented by &lt;a href="http://www-cs-faculty.stanford.edu/%7Eknuth/"&gt;Donald Knuth&lt;/a&gt; in the late 1970s It include simple commands to define logical structure and formatting. It is something like assembly code, noboy writes in TeX. LaTeX is a bundle of macro definitions that abstracts TeX in easy-to-write macros (\section, \title, ...). You write your documents in LaTeX and run the LaTeX compiler to generate DVI (DeVice Independant) files that can be viewed with Evince or KDVI. You may run dvips to generate PostScripts or pdflatex directly on the LaTeX source to generate PDFs. There are many other ways to convert between such formats.&lt;br /&gt;&lt;br /&gt; Another reason why Word is not adequate for complex documents is that it may even crash! I know examples where some MS Office documents crashed when became quite complex. They left their owner with locked documents that are rendered useless.&lt;br /&gt;MS Office stands against openness. When you write your docuemtns in Word and send them to others, you are urging them to purchase Microsoft products to see your "closed-format" document. OpenOffice could be a solution, but Microsoft deliberately changes its format almost from version to version. You may &lt;a href="http://www.gnu.org/philosophy/no-word-attachments.html"&gt;read more&lt;/a&gt; about this format conflict.&lt;br /&gt;&lt;br /&gt; For LaTeX newbies, it is not easy to be productive. You have to be very familiar with LaTeX to play with it. &lt;a href="http://www.lyx.org/"&gt;LyX&lt;/a&gt; is a front-end software for LaTeX. It is WYSIWYM, as they claim: What You See Is What You Mean! You define logical structure through menus, toolbars and keyboard shortcuts and you instantly get an immediate near-preview of the format. LyX has a special language syntax (TeX, LaTeX and LyX all store files in ASCII format and can be edited with any usual text editor). However, you can export your document in LaTeX, PS, PDF,... etc.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.lyx.org/LGT/11.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://www.lyx.org/LGT/11.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;My experience with such tools suggests boot-straping with LyX as a fast startup with TeX. The more you work, the more you know about LaTeX. At a certain stage, when you find LyX restrictive, you will export in LaTeX and continue writing in LaTeX. You may &lt;a href="http://kile.sourceforge.net/"&gt;Kile&lt;/a&gt; for that to autocomplete commands and easily generate DVIs and PostScripts.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://kile.sourceforge.net/images/screenshots/snap_autocomplete.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px;" src="http://kile.sourceforge.net/images/screenshots/snap_autocomplete.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-5958451976389598746?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/5958451976389598746/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=5958451976389598746' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/5958451976389598746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/5958451976389598746'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2008/03/tex-latex-lyx-authors-kit-and-more.html' title='TeX, LaTeX, LyX: Authors kit and more'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-6530934147824962134</id><published>2007-06-29T22:30:00.001+02:00</published><updated>2008-03-25T11:51:47.801+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>مش انا اتجوزت؟</title><content type='html'>&lt;div style="text-align: center;"&gt;بسم الله،&lt;br /&gt;أيوة اتجوزت&lt;br /&gt;بس الكلام ده عدى عليه شهرين ونص&lt;br /&gt;13/4/2007&lt;br /&gt;ياااااااه دي الايام بتجري&lt;br /&gt;وبصراحة انا كنت مكسل اكتب من ساعتها&lt;br /&gt;مش فاضي بقة&lt;br /&gt;أصل الدنيا مشاغل والبيت والعيال وأم العيال وخال العيال وعم العيال وأبو أم العيال...&lt;br /&gt;على العموم الخبر ده قديم ومحدش مش عارفه&lt;br /&gt;بس أنا قلت واجب ندونه عشان التوثيق التاريخي والعولمة والخصخصة والفكر الجديد وأولويات اﻹصلاح :)&lt;br /&gt;وسلملي على اﻷمانة العامة...&lt;br /&gt;&lt;br /&gt;والسلام عليكم&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-6530934147824962134?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/6530934147824962134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=6530934147824962134' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/6530934147824962134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/6530934147824962134'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2007/06/blog-post.html' title='مش انا اتجوزت؟'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4600337178027753505</id><published>2007-01-17T20:09:00.001+02:00</published><updated>2008-03-25T11:52:26.132+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><title type='text'>خبر الموسم!</title><content type='html'>&lt;div style="text-align: center;"&gt;السلام عليكم،&lt;br /&gt;أحبتي في الله،&lt;br /&gt;يسعدني أن أزف إليكم جميعا هذا الخبر العظيم:&lt;br /&gt;إن شاء الله تعالى سيتم&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);font-family:times new roman;font-size:180%;"  &gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt; عقد زواجي&lt;/blockquote&gt;&lt;/span&gt;&lt;/span&gt; بفضل الله ومنته يوم الجمعة السابع من شهر الله المحرم&lt;br /&gt;لعام ثمانية وعشرين وأربعمائة وألف هجريا،&lt;br /&gt;&lt;br /&gt;يعني بالبلدي كدة&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;26/1/2007&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;الجمعة بعد الجاية بعد صلاة العشاء بإذن الله.&lt;br /&gt;&lt;br /&gt;المكان:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 51, 255);font-size:180%;" &gt;&lt;span style="font-weight: bold;"&gt; مسجد السلام بستانلي&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;الوصف: وانت جاي من على البحر حتاخد البحر على شمالك وحتعدي شارع سوريا على يمينك&lt;br /&gt;وبعدين شارع رشدي، حتلاقي ماكدونالدز ستانلي.&lt;br /&gt;بعد كدة حتفوت شارع وتخش في اللي بعده.&lt;br /&gt;الكلام ده لو جي على رجلك أو بالمواصلات من على البحر.&lt;br /&gt;إنما لو جاي بالسيارة حتخش في الشارع اﻷول اللي بعد ماكدونالدز عشان شارع المسجد مافيهوش دخول من على البحر.&lt;br /&gt;&lt;br /&gt;لو تحب برضه تاخد فكرة من على :&lt;br /&gt;&lt;a href="http://www2.blogger.com/img/gl.link.gif"&gt;Google maps&lt;/a&gt;&lt;br /&gt;دوس عليها&lt;br /&gt;&lt;span style="font-size:78%;"&gt;&lt;a href="http://www2.blogger.com/img/gl.link.gif"&gt;http://maps.google.com/?ie=UTF8&amp;amp;om=1&amp;amp;amp;z=17&amp;amp;ll=31.233848,29.948956&amp;amp;spn=0.003614,0.007231&amp;amp;t=k&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;بص برضه على الصورة دي، أنا موضح فيها كل الوصف:&lt;br /&gt;.&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_Fxxo5JtY8z8/Ra5shDbDh3I/AAAAAAAAAAY/xQF4L6s6l40/s1600-h/my3akdmap.png"&gt;&lt;img style="cursor: pointer;" src="http://bp3.blogger.com/_Fxxo5JtY8z8/Ra5shDbDh3I/AAAAAAAAAAY/xQF4L6s6l40/s400/my3akdmap.png" alt="" id="BLOGGER_PHOTO_ID_5021069949674948466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;هذه الدعوة عامة لكل من شاهد هذه الصفحة من إخوتي في الله&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic; font-weight: bold;font-size:130%;" &gt;أسأل الله تعالى أن يبارك لنا في هذه الزواج&lt;br /&gt;وأن يجعلك قرة عين لي&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;وإن شاء الله عقبالكم جميعا&lt;br /&gt;&lt;br /&gt;سبحانك الله وبحمدك&lt;br /&gt;أشهد ألا إله إلا أنت&lt;br /&gt;أستغفرك وأتوب إليك&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4600337178027753505?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4600337178027753505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4600337178027753505' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4600337178027753505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4600337178027753505'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2007/01/blog-post.html' title='خبر الموسم!'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp3.blogger.com/_Fxxo5JtY8z8/Ra5shDbDh3I/AAAAAAAAAAY/xQF4L6s6l40/s72-c/my3akdmap.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-2086685206209385551</id><published>2006-12-06T15:44:00.000+02:00</published><updated>2006-12-06T16:08:17.398+02:00</updated><title type='text'>See how rich I am!</title><content type='html'>&lt;TABLE BORDER=0 CELLPADDING=8 CELLSPACING=0 style='border: 2px solid #000000;width:140px;'&gt;&lt;TR&gt;&lt;TD align=left style='font-size=12px; font-family:arial; color:#000000; line-height: 120%;'&gt;&lt;strong&gt;I'm loaded.&lt;br&gt;It's official.&lt;br&gt;&lt;/strong&gt;I'm the &lt;font style='font-size=12px; font-family:arial; color:#ff0000;'&gt;835,128,870&lt;/font&gt; richest person on earth!&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;a href='http://www.globalrichlist.com' onFocus='blur();' style='text-decoration: none; font-weight: bold; color: #000000;'&gt;&lt;img src='http://globalrichlist.com/_images/logo.gif' width=102 height=10 border=0&gt;&lt;br&gt;How rich are you? &gt;&gt;&lt;/a&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TABLE&gt;&lt;br /&gt;&lt;span id="copybox"&gt;&lt;strong&gt;&lt;span class="red"&gt;$8&lt;/span&gt;&lt;/strong&gt; could buy you&lt;br&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span id="copybox"&gt;15 organic apples&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="copybox"&gt;&lt;/span&gt;OR 25 fruit trees for farmers in Honduras to grow and sell fruit at their local market.&lt;br&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="copybox"&gt;&lt;br&gt;&lt;strong&gt;&lt;span class="red"&gt;$30&lt;/span&gt;&lt;/strong&gt; could buy you &lt;br&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span id="copybox"&gt;an ER DVD Boxset &lt;br&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="copybox"&gt;OR a First Aid kit for a village in Haiti.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="copybox"&gt;&lt;br&gt;&lt;strong&gt;&lt;span class="red"&gt;$73&lt;/span&gt;&lt;/strong&gt; could buy you &lt;br&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span id="copybox"&gt;a new mobile phone &lt;br&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="copybox"&gt;OR a new mobile health clinic to care for AIDS orphans in Uganda.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="copybox"&gt;&lt;br&gt;&lt;strong&gt;&lt;span class="red"&gt;$2400&lt;/span&gt;&lt;/strong&gt; could buy you &lt;br&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span id="copybox"&gt;a second generation High Definition TV&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span id="copybox"&gt;OR schooling for an entire generation of school children in an Angolan village.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span id="copybox"&gt;&lt;br&gt;&lt;/span&gt;&lt;span style="font-weight: bold;" class="blackheader"&gt; DID YOU KNOW..? &lt;/span&gt;&lt;br&gt;&lt;span id="didyou"&gt;The world's 225 richest people now have a combined wealth of $1 trillion. That's equal to the combined annual income of the world's 2.5 billion poorest people.&lt;/span&gt;&lt;br&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.globalrichlist.com/index.php"&gt;http://www.globalrichlist.com/index.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-2086685206209385551?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/2086685206209385551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=2086685206209385551' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/2086685206209385551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/2086685206209385551'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2006/12/see-how-rich-i-am.html' title='See how rich I am!'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-4143480568301576810</id><published>2006-12-03T19:45:00.000+02:00</published><updated>2006-12-10T16:23:18.265+02:00</updated><title type='text'>بسم الله نبدأ</title><content type='html'>&lt;div style="text-align: center;"&gt;بسم الله الرحمن الرحيم&lt;br /&gt;الحمد لله رب العالمين&lt;br /&gt;الرحمن الرحيم&lt;br /&gt;مالك يوم الدين&lt;br /&gt;والعاقبة للمتقين&lt;br /&gt;ولا عدوان إلا على الظالمين.&lt;br /&gt;&lt;br /&gt;إن الحمد لله نحمده ونستعينه ونستغفره&lt;br /&gt;ونعوذ بالله من شرور أنفسنا ومن سيئات أعمالنا&lt;br /&gt;من يهده الله فلا مضل له&lt;br /&gt;ومن يضلل فلا هادي له.&lt;br /&gt;&lt;br /&gt;أما بعد فإن خير الهدي هدي محمد صلى الله عليه وسلم&lt;br /&gt;وشر اﻷمور محدثاتها&lt;br /&gt;وكل محدثة بدعة&lt;br /&gt;وكل بدعة ضلالة&lt;br /&gt;وكل ضلالة في النار.&lt;br /&gt;&lt;br /&gt;وما قل وكفى خير مما كثر وألهى&lt;br /&gt;وإن ما توعدون ﻵت وما أنتم بمعجزين.&lt;br /&gt;&lt;br /&gt;أحبتي في الله&lt;br /&gt;زوار مدونتي المتواضعة&lt;br /&gt;وكيف لا أحبكم وانا في شرف ضيافتكم!&lt;br /&gt;فهذا أول تدوين أرجو من الله أي يكون في ميزان الصالحات وأن لا يكون وبالا علينا يوم القيامة.&lt;br /&gt;فأهلا ومرحبا بكم،&lt;br /&gt;يسعدني تلقي التهاني بمناسبة هذا الحدث العظيم :)&lt;br /&gt;&lt;br /&gt;والسلام عليكم ورحمة الله وبركاته&lt;br /&gt;حسام حمادي&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-4143480568301576810?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/4143480568301576810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=4143480568301576810' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4143480568301576810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/4143480568301576810'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2006/12/blog-post.html' title='بسم الله نبدأ'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1427064072400819258.post-9156762629973275025</id><published>2006-12-03T18:14:00.000+02:00</published><updated>2006-12-03T22:30:55.353+02:00</updated><title type='text'>رحم الله إمرئ أهدى لي عيوبي</title><content type='html'>&lt;div style="text-align: center;"&gt;بسم الله،&lt;br /&gt;&lt;span style="font-size:130%;"&gt;  يقول عمر بن الخطاب رضي الله عنه:&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;رحم الله امرئ أهدى إليّ عيوبي &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;أنا لا أعلم صحة نسبة هذا القول إلى سيدنا عمر رضي الله عنه وأرضاه. ولكن يعجبني معناه. لو حد يعرف يصحح لنا هذا الأثر، ياريت ما يبخلش علينا.&lt;br /&gt;إذن من المفيد، مع أنه من المؤلم، أن يخبرنا الناس وخصوصا اﻹخوة واﻷصدقاء عن عيوبنا. فهي حقا نعم الهدية. إذ العاقل من يسمع هذا النقد البناء حتى يصلح من نفسه.&lt;br /&gt;ومن منا يخلو من العيوب؟&lt;br /&gt;تصوروا حتى أنا عندي عيوب :))&lt;br /&gt;المهم...&lt;br /&gt;كل اللي انا عايزه منكم إن كل واحد زي الشاطر كدة يجمع شوية عيوب لي، ويجمع شجاعته ويدونها هنا.&lt;br /&gt;متخافوش أنا مش حضرب والا حامد ايدي والا اتنرفذ والا أي حاجة من دي خالص،&lt;br /&gt;كل ما في الأمر أني حــــا....&lt;br /&gt;والا بلاش، خليها مفاجأة :)&lt;br /&gt;&lt;br /&gt;طبعا مش ضروري حد يمضي باسمه،&lt;br /&gt;احنا مش عايزين ضرب،&lt;br /&gt;بس اللي عايز، مايخافش، احنا قلنا مفيش مد ايد :)&lt;br /&gt;&lt;br /&gt;بجد بجد أنا نفسي تشاركوا وخصوصا:&lt;br /&gt;جمال، رشدي، السايح، ميدو،&lt;br /&gt;أنا منتظر....&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;وربنا يستر على الفضايح :)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;والسلام عليكم&lt;br /&gt;حسام&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1427064072400819258-9156762629973275025?l=blog.hammady.net' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.hammady.net/feeds/9156762629973275025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1427064072400819258&amp;postID=9156762629973275025' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/9156762629973275025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1427064072400819258/posts/default/9156762629973275025'/><link rel='alternate' type='text/html' href='http://blog.hammady.net/2006/12/blog-post_03.html' title='رحم الله إمرئ أهدى لي عيوبي'/><author><name>hammady</name><uri>http://www.blogger.com/profile/17387936164476486881</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry></feed>
