pandoc-filter

اینم یه تجربه پراکنده دیگه!

همنطور که اخیرا زیاد نوشتم فرمت مورد علاقه تولید مستندات من markdown شده و برای تبدیل کردنش به یه متن تر و تمیز pdf از pandoc به همراه xepersian استفاده می‌کنم. حالا این وسط من یه مشکلی داشتم و اونم این بود که متون انگلیسی توی فارسی به درستی به فرمت xepersian تبدیل نمی‌شدند و هی مجبور بودم بصورت دستی متن latex بدست آمده رو ویرایش کنم. به همین خاطر علاقه مند شدم که ببینم چطور می‌شه این مشکل رو توی pandoc حل کرد. راه حل از این قراره که شما بایستی یه فیلتر برای pandoc تعریف کنی و اون pandoc filter اون کاری که ما دوست داریم رو برای ما انجام میده!

فیلترهای pandoc

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

همچنین میشه این فیلترها رو به زبانی غیر از haskell توسعه داد. این زبان‌های پایتون، جاوا اسکریپت(در محیط nodejs)، پرل و php هست. من به علت آشنایی بیشترم با پایتون از اون استفاده کردم

نحوه توسعه

کل روند از این قراره که شما فایل پایتون رو بصورت یک فیلتر با دسترسی اجرایی در اختیار pandoc قرار میدید و اون تابع main رو صدا میزنه. پس از اون اطلاعات از stdin به برنامه داده شده و خروجی‌ها از stdout گرفته می‌شه. خود توسعه دهنده pandoc هم پکیجی به نام pandocfilters توسعه داده که با استفاده از pip یا ابزارهای مشابه قابل نصب و استفاده است.

تنها کاری که باید انجام بشه اینه که تابعی نوشته بشه و به عنوان آرگومان به تابع ‍‍

پاس داده بشه. این تابع بایستی چهارتا ورودی داشته باشه که به ترتیبت ‍‍

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

همین!
پ.ن.: برای مطالعه بیشتر به اینجا مراجعه کنید.

go introduction

اینم یه تجربه پراکنده دیگه!

من از طریق twitter با دوستان مجله hive آشنا شدم و یه مطب معرفی اولیه زبان go نوشتم. خوشحال میشم که برید و بخونیدش

لینک مطلب

همین!

Markdown Doc Generation

اینم یه تجربه پراکنده دیگه!

من معمولا محتواهای زیادی تولید می‌کنم. یعنی گزارش پروژه، مستند‌سازی و … انجام میدم. معمولا قبلا برای این‌کار از word و office استفاده می‌کردم. بزرگترین مشکلی که با این سیستم داشتم این بود که به علت اینکه سیستم عامل اصلیم لینوکسه مجبور بودم توی یک ماشین مجازی کار کنم که به علت سرعت کم هارد دیسک لپ تاپم معمولا اذیتم می‌کرد. اما اخیرا یه مستند تقریبا ۷۰ صفحه‌ای با استفاده از markdown نوشتم که من رو به این نتیجه رسوند که الان وقت مهاجرت از ورد رسیده

قبلا نوشته بودم که چطور میشه یه متن رو یه بار نوشت و به فرمت‌های مختلف اون رو داشت. حالا من به کمک pandoc و markdown و latex و xepersian تونستم یه مجموعه ابزار کامل برای تبدیل متن با سر و شکل قابل قبول و قابل ارائه ایجاد کنم. حالا تصمیم گرفتم که این کار رو ادامه بدم و مشکلاتی که ممکنه بر بخورم رو اینجا مستند کنم.

همین!

اینم یه تجربه پراکنده دیگه!

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

وضعیت من از این قرار بود:

  • یه نقشه به فرمت ArcGIS داشتم که هیچ برنامه‌ای برای بازکردنش نداشتم. اون فرمت شامل یه نوع فایل خاص به نام shapeFile بود که نقشه رو توصیف می‌کرد.
  • من هیچ ایده‌ای نداشتم که کار به چه صورت باید انجام بشه.
  • هیچ تجربه قبلی هم با html5 و بالاخص canvas نداشتم.

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

  • اول shapeFile رو بعد از تحقیقات زیاد با استفاده از نرم‌افزار متن‌باز qGIS تبدیل کردیم به فرمت KML که یه فرمت متن‌باز برای نقشه‌هاست.
  • دوم اینکه با استفاده از jQuery فایل KML رو خونده و parse کردیم.
  • حالا که نقاط نقشه یا بهتره بگم نقاط چند ظلعی‌ها رو بصورت مجزا داشتیم هریک از اونها رو توی html5 کشیدیم و بهش رنگ و فرمت دادیم
  • یه سری هم محاسبه انجام دادم که بتونم عناصر داینامیک رو روی نقشه نشون بدم.

در کل تجربه خیلی جالبی بود و برای منی که کلا از وب سررشته خاصی نداشتم غول مرحله آخر به حساب می‌اومد و از انجامش لذت بردم.

همین!

خب اینم یه تجربه پراکنده دیگه!

من یه مدته که دارم golang رو یاد میگیرم. تاحالا بخاطر اینکه تجربه قابل قبول خوبی توی این یادگیری وجود نداشت چیزی ننوشته بودم. اما اخیرا به یه موضوع توی این زبان علاقه مند شدم و رفتم و ته توش رو در اوردم که به نظر جالب اومد که اینجا هم بنویسمش.

یکی از ویژگی‌هایی که go وجود داره اینه که خود زبان بصورت توکاری شده از یه مفومی به نام goroutine ها پشتیبانی می‌کنه. goroutine ها یه ابزاری برای ایجاد همروندی در برنامه است و تقریبا نحوه استفاده از اونها شبیه جاهایی است که ما از Thread ها استفاده می‌کنیم. یعنی هر جایی که بخوایم عملیاتی رو که به هر دلیل بلوکه میشه رو انجام بدیم و نمیخوایم اصل برنامه گیر کنه ازش استفاده می‌کنیم. واسه من این سوال بوجود اومد که خب اگه اینقدر این دوتا شبیه هستن چرا اسمشون شده دوتا و این جا بود که تحقیقات شروع شد:

اول از همه بگذارید یکم بگم Thread یا goroutine چیه:

  • خب Thread و goroutine ها هر کدام Stack متفاوتی دارند. یعنی متغیرهای محل مختص به خودشون رو دارن!
  • همه Thread ها و goroutineها بخش Data Segment یکسانی دسترسی دارند. یعنی متغیرهای عمومی برنامه رو می‌بینند.
  • همه Threadها و goroutineها بخش Code Segment یکسانی دسترسی دارند. یعنی توابع کل برنامه رو میبینن
  • همه Threadها و goroutineها بخش Heap Segment یکسانی دسترسی دارند. یعنی به شیٔ هایی که در برنامه new شدن دسترسی دارن

حالا نوبت تفاوتهاست:

  • اولین تفاوت در سایز stack بود.
    • یعنی اینکه به ازای هر Thread جدید سیستم عامل نزدیک به ۲ مگ و دیده شده تا ۸ مگ حافظه به stack اون Thread اختصاص میده و این درحالیه که هر goroutine در یسری نسخه‌ها ۴ کیلو بایت و در یسری نسخه جدید تر ۸ کیلو بایت حافظه اختصاص میده
    • سایز stack در Threadها در طول اجرا تغییر نمیکنه یعنی این سایز همین مقدار میمونه ولی سایز stack در goroutineها بر اساس نیاز زیاد میشه.
    • نتیجه تفاوت حجم هم اینها هستن
      • همین تفاوت حجم باعث میشه که وقتی یک گیگ مموری داریم میتونیم بین ۱۲۸ تا ۵۱۲ Thread بسازیم ولی میتونیم حدودا ۱۲۸۰۰۰ تا ۲۵۶۰۰۰ goroutine بسازیم.
      • همین تفاوت حجم باعث میشه ساختن و پاک کردن goroutine ها بسیار کم هزینه تر از Thread ها باشه
  • دوم تفاوت هم نحوه زمانبندی برای اجراست:
    • threadها توسط سیستم عامل زمانبندی شده و اجرا میشن که با توجه به حجم stack معمولا کار پر هزینه‌ای است
    • goroutine ها در محیطی به نام go runtime هست که کل کدها توی اون اجرا میشن. یعنی اینکه go runtime مسئول لود کرد حافظه مورد نیاز برای goroutineها رو بر عهده داره. همچنین زمانبندی اجرا هم توسط همین محیط انجام میشه. این محیط خودش از یک یا چند Thread تشکیل شده که goroutine ها رو اجرا میکنن و عین اینه که شما یه سری کار رو بصورت اتوماتیک به یک Thread pool داده باشی. به همین خاطر کل این روند بسیار از نظر برنامه نویس ساده شده. همچنین وجود این go runtime این امکان رو بوجود آورده که از الگوریتم‌های زمانبندی بهینه تری برای این زبان استفاده بشه که خودش افزایش کارایی رو نتیجه میده. البته این روش معایبی هم داره که اگر عمری بود در موردش مینویسم.
  • سومین تفاوت هزینه بازگذاری و خروج از مموری:
    • برای اجرای Thread ها تقریبا تمام رجیسترهای سی پی یو (شامل  ۱۶ رجیستر عمومی، PC، SP، رجیسترهای سگمنت و …) تغییر میکند. که در مواردی که تغییر بین Threadها زیاد است هزینه قابل توجهی است.
    • در goroutine ها تنها سه رجیستر(SP, PC, DX) تغییر میکند.

فعلا همین!

اینم یه تجربه پراکنده دیگه!

این پست یه پست کوتاه خواهد بود. من همانطور که اگه اینجا رو خونده باشید میدونید که علاقه به ساختن چیزهای مختلف دارم. هدفم هم از این کار صرفا این نیست که یه محصول ارزونتر تولید کنم یا به فکر راه انداختم کسب و کار جدیدی باشم. بلکه هدفم سرگرمی و انجام کارهای جدیده. یه جورایی پاسخ به تنوع طلبی خودمه. در خارج این مملکت به این کا Do it yourself یا diy میگن.

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

  • معمولا به مواد یا قطعات خام هست که اینجا در دسترس نیست
    • برای ساختن یه روتر مبتنی بر pfSense من نیاز به مادربردهای خاص منظوره دارم که در ایران گیر نمیاد
    • برای ساختن یه NAS نیاز به یه مادربرد با تعداد زیاد پورت SATA و یه کیس کوچک و جمع و جور
    • برای ساختن یه سرویس داخلی نیاز به سرورهایی با قیمت مناسب
    •  …
  • معمولا دانش برای انجام این کار کمه
    • شما اطلاعات کافی رو برای انجام این کارها به سختی به دست میاری
  • معمولا تکنسین و استادکار ساختن وسایل مختلف در دسترس نیستن
    • من میخواستم یه قطعه چوبی برای زیر لپ تاپم بسازم اما هنوز که هنوز نتونستم استادکاری که بخواد این کار رو انجام بده رو پیدا نکردم

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

امیدوارم یه روزی اونجوری که دلم میخواد بشه!

همین!

پ.ن. وقتی آدم خودش رو مقید کنه که مثلا هر از ۳ روز یک بار بنویسه کیفیت نوشته‌ها تحت تاثیر قرار میگیره 😉