BTPARSE(1) btparse BTPARSE(1)

btparse - کتابخانه تجزیه و اعتبارسنجی داده‌های BibTeX در زبان‌های برنامه‌نویسی C و Perl

#include <btparse.h>
/* راه‌اندازی و پاک‌سازی اولیه کتابخانه */
void bt_initialize (void);
void bt_free_ast (AST *ast);
void bt_cleanup (void);
/* ورودی و رابط به تجزیه‌کننده */
void   bt_set_stringopts (bt_metatype_t metatype, btshort options);
AST * bt_parse_entry_s (char *    entry_text,
                        char *    filename,
                        int       line,
                        btshort    options,
                        boolean * status);
AST * bt_parse_entry   (FILE *    infile,
                        char *    filename,
                        btshort    options,
                        boolean * status);
AST * bt_parse_file    (char *    filename,
                        btshort    options,
                        boolean * overall_status);
/* پیمایش و پرس‌وجوی AST */
AST * bt_next_entry (AST * entry_list,
                     AST * prev_entry)
AST * bt_next_field (AST *entry, AST *prev, char **name);
AST * bt_next_value (AST *head,
                     AST *prev,
                     bt_nodetype_t *nodetype,
                     char **text);
bt_metatype_t bt_entry_metatype (AST *entry);
char *bt_entry_type (AST *entry);
char *bt_entry_key (AST *entry);
char *bt_get_text (AST *node);
/* تفکیک نام‌ها و فهرست‌های نام */
bt_stringlist * bt_split_list (char *   string,
                               char *   delim,
                               char *   filename,
                               int      line,
                               char *   description);
void bt_free_list (bt_stringlist *list);
bt_name * bt_split_name (char *  name,
                         char *  filename,
                         int     line,
                         int     name_num);
void bt_free_name (bt_name * name);
/* قالب‌بندی نام‌ها */
bt_name_format * bt_create_name_format (char * parts, boolean abbrev_first);
void bt_free_name_format (bt_name_format * format);
void bt_set_format_text (bt_name_format * format,
                         bt_namepart part,
                         char * pre_part,
                         char * post_part,
                         char * pre_token,
                         char * post_token);
void bt_set_format_options (bt_name_format * format,
                            bt_namepart part,
                            boolean abbrev,
                            bt_joinmethod join_tokens,
                            bt_joinmethod join_part);
char * bt_format_name (bt_name * name, bt_name_format * format);
/* ساخت درخت از گروه‌های TeX */
bt_tex_tree * bt_build_tex_tree (char * string);
void          bt_free_tex_tree (bt_tex_tree **top);
void          bt_dump_tex_tree (bt_tex_tree *node, int depth, FILE *stream);
char *        bt_flatten_tex_tree (bt_tex_tree *top);
/* ابزارهای متفرقه رشته‌ها */
void bt_purify_string (char * string, btshort options);
void bt_change_case (char transform, char * string, btshort options);

کتابخانه btparse یک کتابخانه C برای تجزیه و پردازش پرونده‌های BibTeX است. این کتابخانه یک اسکنر واژگانی (lexical scanner) و یک تجزیه‌کننده LR (ساخته‌شده توسط PCCTS) فراهم می‌کند که هر دو کارآمد بوده و قابلیت تشخیص و بازیابی خطای مناسبی ارائه می‌دهند؛ مجموعه‌ای از توابع برای پیمایش درخت نحو انتزاعی (AST) تولید‌شده توسط تجزیه‌کننده؛ و توابع کمکی برای دستکاری رشته‌ها بر اساس قراردادهای BibTeX. (توجه داشته باشید که هیچ بخشی از کتابخانه فرض نمی‌کند که شما الزاماً از پرونده‌های BibTeX برای هدف اصلی آن‌ها یعنی داده‌های کتاب‌شناختی انتشارات علمی استفاده می‌کنید؛ می‌توانید از این قالب برای هر مقصدی که با آن سازگار باشد استفاده کنید. با این حال، کدهایی در کتابخانه وجود دارد که منحصراً برای استفاده با رشته‌هایی مناسب است که قرار است همانند خود BibTeX پردازش شوند. هرچند استفاده از همه این موارد کاملاً اختیاری است.)

توجه داشته باشید که رابط ارائه‌شده توسط btparse گرچه کامل است، اما نسبتاً سطح پایین محسوب می‌شود. اگر به امکانات پیشرفته‌تری نیاز دارید، ممکن است ماژول Text::BibTeX برای Perl 5 (موجود در CPAN) برای شما مناسب‌تر باشد.

برای درک این مستند و استفاده از btparse, باید با زبان BibTeX -- به‌ویژه زبان توصیف داده‌های BibTeX -- آشنایی داشته باشید. (از آنجا که BibTeX ساختار پیچیده‌ای دارد، این اصطلاح می‌تواند به برنامه، زبان داده، ساختار پایگاه داده خاص توصیف‌شده در مستندات اصلی BibTeX، زبان قالب‌بندی ".bst" و مجموعه‌ای از قراردادهای موجود در سبک‌های استاندارد همراه با توزیع BibTeX اطلاق شود. در این مستند، ما به دو معنای اول پایبند خواهیم بود: زبان داده، زیرا چیزی است که btparse با آن سر و کار دارد؛ و برنامه اصلی، زیرا گاهی اوقات توضیح تفاوت‌های میان تجزیه‌کننده این کتابخانه و BibTeX ضروری است.)

به‌ویژه، باید متوجه ساختار نمونه زیر باشید:

@string{and = { and },
        joe = "Blow, Joe",
        john = "John Smith"}
@book(ourbook,
      author = joe # and # john,
      title = {Our Little Book})

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

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

سطح بالا (top-level)
تمام متن موجود در یک پرونده BibTeX از ابتدای پرونده تا آغاز نخستین مدخل، و همچنین متن‌های میان مدخل‌ها پس از آن.
نام (name)
رشته‌ای از حروف، ارقام و نویسه‌های زیر:
! $ & * + - . / : ; < > ? [ ] ^ _ ` |

یک «نام» یک اصطلاح فراگیر برای انواع مدخل، کلیدهای مدخل، و نام‌های فیلد و ماکرو است. برای سازگاری با BibTeX، قوانین اندک متفاوتی برای این چهار موجودیت وجود دارد؛ در حال حاضر، تنها قانونی که پیاده‌سازی شده این است که نام فیلدها و ماکروها نباید با رقم آغاز شوند. برخی از نام‌ها در مثال بالا: string و and.

مدخل (entry)
تکه‌ای از متن که با نویسه ات‌ساین (@) در سطح بالا آغاز می‌شود، با یک نام (نوع مدخل یا entry type) و یک جداکننده مدخل ({ یا () ادامه می‌یابد و تا جداکننده پایانی متناظر پیش می‌رود. همچنین، ساختار داده‌ای که از تجزیه این تکه متن حاصل می‌شود. در مثال بالا دو مدخل وجود دارد.
نوع مدخل (entry type)
نامی که بلافاصله پس از @ در سطح بالا می‌آید. نمونه‌ها از مثال بالا: string و book.
فراتایپ مدخل (entry metatype)
طبقه‌بندی انواع مدخل که امکان گروه‌بندی یک یا چند نوع مدخل را ذیل یک عنوان فراهم می‌کند. در ساختار استاندارد پایگاه‌داده BibTeX، انواع article، book، inbook و غیره همگی ذیل فراتایپ «مدخل عادی» (regular entry) قرار می‌گیرند. سایر فراتایپ‌ها عبارتند از: «تعریف ماکرو» (macro definition برای مدخل‌های string)، «دیباچه» (preamble برای مدخل‌های preamble) و «توضیح» (comment برای مدخل‌های comment). در واقع، هر مدخلی که نوع آن یکی از string، preamble یا comment نباشد، یک مدخل «عادی» نامیده می‌شود.
جداکننده‌های مدخل (entry delimiters)
جفت‌های { و }، یا ( و ): جفت نویسه‌هایی که (تقریباً) مرزهای یک مدخل را مشخص می‌کنند. «تقریباً» از این جهت که شروع مدخل با نویسه @ مشخص می‌شود، نه با جداکننده آغازین مدخل.
کلید مدخل (entry key)
(یا صرفاً کلید زمانی که زمینه گفتگو مشخص است.) نامی که بلافاصله پس از جداکننده آغازین در یک مدخل عادی قرار می‌گیرد و آن مدخل را به‌طور یکتا مشخص می‌کند. نمونه از مثال بالا: ourbook. تنها مدخل‌های عادی دارای کلید هستند.
فیلد (field)
نامی در سمت چپ علامت مساوی در یک مدخل عادی یا مدخل تعریف ماکرو. در حالت دوم، ممکن است نام ماکرو نیز نامیده شود. نمونه‌ها از مثال بالا: joe و author.
فهرست فیلدها (field list)
در یک مدخل عادی، تمام محتوای میان جداکننده‌های مدخل به‌جز کلید مدخل. در مدخل تعریف ماکرو، تمام محتوای میان جداکننده‌های مدخل (که احتمالاً فهرست ماکرو نیز نامیده می‌شود).
مقدار ترکیبی (compound value)
(معمولاً صرفاً «مقدار».) متنی که پس از علامت مساوی (=) در یک مدخل عادی یا تعریف ماکرو تا کاما یا جداکننده پایانی مدخل می‌آید؛ فهرستی از یک یا چند مقدار ساده که با علامت هش (#) به یکدیگر متصل شده‌اند.
مقدار ساده (simple value)
یک رشته، ماکرو یا عدد.
رشته (string)
(یا گاهی «رشته درون کوتیشن».) بخشی از متن میان علامت‌های نقل‌قول ( ) یا آکولادها ({ و }). آکولادها باید تراز و متوازن باشند: عبارت {this is a {string} یک رشته معتبر BibTeX نیست، اما عبارت {this is a {string}} معتبر است. (عبارت this is a {string نیز غیرمجاز است، عمدتاً برای جلوگیری از احتمال تولید کد نادرست TeX -- که BibTeX در شرایط خاصی ایجاد می‌کند.)
ماکرو (macro)
نامی که در سمت راست علامت مساوی ظاهر می‌شود (یعنی به عنوان یک مقدار ساده درون یک مقدار ترکیبی). این نام نشان می‌دهد که در یک مدخل تعریف ماکرو قبلی تعریف شده است، هرچند این موضوع تنها زمانی بررسی می‌شود که از btparse خواسته شود ماکروها را به تعاریف کامل آن‌ها بسط دهد.
عدد (number)
رشته‌ای بدون نقل‌قول از ارقام.

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

محتوای گره‌های AST محدوده خصوصی کتابخانه است و نباید مستقیماً به آن‌ها دسترسی پیدا کنید. در زبان C چیزی مانع این کار نمی‌شود مگر اصول کدنویسی تمیز و این احتمال که ممکن است ساختار AST در نسخه‌های آینده تغییر کند و کدهای غیراستاندارد را از کار بیندازد. همچنین نیازی به دانستن روابط ساختاری میان گره‌ها در AST نیست -- این کار توسط توابع پرس‌وجو و پیمایش انجام می‌شود.

با این حال، آگاهی از برخی اطلاعاتی که btparse در AST قرار می‌دهد و از طریق توابع پرس‌وجو و پیمایش بازمی‌گرداند مفید است. ابتدا اینکه هر گره دارای یک «نوع گره» (node type) است که عنصر نحوی متناظر با آن گره را ثبت می‌کند. برای نمونه، مدخل

@book{mybook, author = "Joe Blow", title = "My Little Book"}

دارای یک گره ریشه از نوع "entry" است؛ ذیل آن یک گره "key" (برای کلید مدخل) و دو گره "field" (برای فیلدهای "author" و "title") قرار دارد؛ و با هر گره فیلد، یک گره "string" مرتبط است. این موضوع تنها زمانی اهمیت دارد که از کتابخانه یک مقدار ساده درخواست کنید؛ صرفاً مشاهده متن برای تشخیص رشته‌های درون کوتیشن، اعداد و نام‌های ماکرو کافی نیست، بنابراین btparse نوع گره را نیز همراه متن بازمی‌گرداند.

علاوه بر نوع گره، btparse فراتایپ (metatype) هر گره "entry" را نیز ثبت می‌کند. این ویژگی به شما (و کتابخانه) امکان می‌دهد برای نمونه مدخل‌های عادی را از مدخل‌های توضیح (comment) تفکیک کنید. این مدخل‌ها نه تنها ساختارهای بسیار متفاوتی دارند و باید به شیوه‌های متفاوتی توسط کتابخانه پیمایش شوند، بلکه برخی توابع پیمایش روی برخی فراتایپ‌های مدخل بی‌معنی هستند -- بنابراین توانایی تشخیص این موارد برای شما نیز ضروری است.

با این تفاصیل، تمام اطلاعات مورد نیاز برای کار با AST در راهنمای bt_traversal توضیح داده شده است.

کتابخانه btparse چندین نوع داده مورد نیاز برای رابط خارجی خود تعریف می‌کند. ابتدا، نوع داده boolean را (همراه با ماکروهای TRUE و FALSE) تعریف می‌نماید. این موضوع هنگام گنجاندن هدر btparse.h در کد شما ممکن است تأثیرگذار باشد -- از آنجا که کد نمی‌تواند تشخیص دهد که آیا پیش‌تر نوع boolean تعریف شده است یا خیر، شاید نیاز باشد نماد پیش‌پردازنده HAVE_BOOLEAN را تعریف کنید تا typedef مربوط به boolean در btparse.h غیرفعال شود.

سپس، دو نوع شمارشی (enumeration) تعریف شده‌اند: bt_metatype و bt_nodetype. هر دوی این‌ها به‌طور گسترده در خود کتابخانه استفاده می‌شوند و در دسترس کاربران کتابخانه نیز قرار دارند، زیرا در گره‌های AST مربوط به btparse یافت می‌شوند. (یعنی پرس‌وجو از AST مقادیر bt_metatype و bt_nodetype را برمی‌گرداند، بنابراین typedef آن‌ها باید در کد شما در دسترس باشد.)

نوع داده bt_metatype_t شامل مقادیر زیر است:

  • BTE_UNKNOWN
  • BTE_REGULAR
  • BTE_COMMENT
  • BTE_PREAMBLE
  • BTE_MACRODEF

که توسط نشانه «نوع مدخل» تعیین می‌شوند. (مدخل‌های @string دارای فراتایپ BTE_MACRODEF هستند؛ مدخل‌های @comment و @preamble متناظر با BTE_COMMENT و BTE_PREAMBLE می‌باشند؛ و هر نوع مدخل دیگر دارای فراتایپ BTE_REGULAR است.)

نوع داده bt_nodetype شامل مقادیر زیر است:

  • BTAST_UNKNOWN
  • BTAST_ENTRY
  • BTAST_KEY
  • BTAST_FIELD
  • BTAST_STRING
  • BTAST_NUMBER
  • BTAST_MACRO

از این میان، شما تنها با سه مورد آخر سر و کار خواهید داشت. این موارد هنگامی که از AST یک مقدار ساده درخواست می‌کنید بازگردانده می‌شوند -- زیرا صرف مشاهده متن برای تفکیک میان رشته درون کوتیشن، عدد و ماکرو کافی نیست، بنابراین نوع گره AST همراه متن ارائه می‌شود.

از آنجا که BibTeX در اصل سیستمی برای چسباندن رشته‌ها به روش‌های گوناگون است، پردازش انجام‌شده روی رشته‌های آن اهمیت زیادی دارد. بیشتر تبدیل‌های رشته‌ای خارج از لکسر/تجزیه‌کننده انجام می‌شوند؛ این کار پیچیدگی آن‌ها را کاهش داده و خاموش و روشن کردن تبدیل‌های مختلف را آسان‌تر می‌کند. این کنترل با یک نگاشت بیتی (bitmap) «گزینه‌ها» انجام می‌شود که می‌تواند به ازای هر فراتایپ مدخل تعیین گردد. (یعنی می‌توانید یک مجموعه تبدیل روی رشته‌های تمام مدخل‌های عادی، و مجموعه دیگری روی رشته‌های تمام مدخل‌های تعریف ماکرو و غیره اعمال کنید.) اگر به کنترلی دقیق‌تر از این نیاز دارید، در حال حاضر خارج از کتابخانه در دسترس نیست.

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

"BTO_CONVERT"
تبدیل مقادیر «عدد» به رشته. (این تبدیل ساده است و شامل تغییر نوع گره AST نماینده عدد از BTAST_NUMBER به BTAST_STRING می‌شود. مقادیر «عدد» همانند داده‌های ورودی به‌صورت رشته‌ای از ارقام ذخیره می‌شوند.)
"BTO_EXPAND"
بسط فراخوانی‌های ماکرو به متن کامل ماکرو.
"BTO_PASTE"
چسباندن مقادیر ساده به یکدیگر.
"BTO_COLLAPSE"
فشرده‌سازی فاصله‌های خالی بر اساس قوانین BibTeX.

برای نمونه، ارائه BTO_CONVERT | BTO_EXPAND به عنوان بیت‌مپ گزینه‌های رشته برای فراتایپ BTE_REGULAR به این معنی است که تمام مقادیر ساده در مدخل‌های «عادی» به رشته تبدیل خواهند شد: نوع گره اعداد تغییر می‌کند و ماکروها بسط داده می‌شوند. با این حال کار دیگری روی مقادیر ساده انجام نخواهد شد -- آن‌ها به یکدیگر الحاق نمی‌شوند و فاصله‌های خالی فشرده نخواهند شد. برای اطلاعات بیشتر درباره گزینه‌های مختلف تجزیه، توابع bt_set_stringopts() و bt_parse_*() را در bt_input ببینید؛ برای جزئیات پس‌پردازش، bt_postprocess را مشاهده فرمایید.

کد زیر یک اسکلت ساده از نحوه استفاده از کتابخانه btparse است:

#include <btparse.h>
int main (void)
{
   bt_initialize ();
   /* پردازش داده‌ها */
   bt_cleanup ();
   exit (0);
}

لطفاً به فراخوانی تابع bt_initialize() توجه کنید؛ این مورد بسیار حائز اهمیت است! بدون آن، کتابخانه ممکن است با خطا مواجه شده یا متوقف شود. شما باید پیش از فراخوانی هر تابع دیگر btparse، تابع bt_initialize() را فراخوانی کنید. تابع bt_cleanup() صرفاً حافظه تخصیص‌یافته توسط bt_initialize() را آزاد می‌کند؛ اگر دقت کنید که این تابع را پیش از خروج فراخوانی نمایید و تابع bt_free_ast() را روی هر درخت نحو انتزاعی تولید‌شده توسط btparse پس از اتمام کار اجرا کنید، برنامه شما نباید هیچ‌گونه نشت حافظه‌ای داشته باشد. (مگر مواردی که ناشی از کدهای اختصاصی خودتان باشد!)

کتابخانه btparse دارای چندین محدودیت ذاتی است که ناشی از اسکنر واژگانی و تجزیه‌کننده تولید‌شده توسط PCCTS 1.x می‌باشد. به‌طور خلاصه، اسکنر و تجزیه‌کننده هر دو وابستگی شدیدی به متغیرهای سراسری دارند، به این معنی که ایمنی نخ‌ها (thread safety) -- یا حتی توانایی باز کردن و تجزیه همزمان دو پرونده -- تقریباً غیرممکن است. این وضعیت تا زمان مهاجرت به ANTLR 2.0 (جانشین PCCTS) تغییر نخواهد کرد.

محدودیت دیگری که ناشی از PCCTS است: مدخل‌هایی با تعداد بسیار زیاد فیلد (بیش از حدود ۹۰ فیلد، اگر مقدار هر فیلد تنها یک رشته تکی باشد) باعث از کار افتادن تجزیه‌کننده خواهند شد. این موضوع به دلیل استفاده تجزیه‌کننده از پشته‌های با تخصیص ایستا برای ویژگی‌ها و گره‌های درخت نحو انتزاعی غیرقابل اجتناب است. افزایش میزان تخصیص ایستا صرفاً احتمال مواجهه با مشکل را کاهش می‌دهد اما آن را به‌طور ریشه‌ای برطرف نمی‌کند.

به‌جز این محدودیت‌های ذاتی، هیچ باگ شناخته‌شده دیگری در btparse وجود ندارد. هرگونه خطای حافظه (segmentation fault) یا خطای گذرگاه (bus error) از کتابخانه باید به عنوان باگ در نظر گرفته شود. این موارد معمولاً ناشی از استفاده نادرست از کتابخانه است (مانند تلاش برای تجزیه تداخلی دو پرونده همزمان)، اما تلاش شده تا تمام این اشتباهات مهار شوند.

هرگونه نشت حافظه از کتابخانه نیز مهم است؛ تا زمانی که در فراخوانی توابع پاک‌سازی (bt_free_ast() و bt_cleanup()) دقت لازم را داشته باشید، کتابخانه نباید نشت حافظه داشته باشد.

برای خواندن و تجزیه پرونده‌های داده BibTeX، به bt_input مراجعه کنید.

برای پیمایش درخت نحو حاصل، به bt_traversal مراجعه فرمایید.

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

برای چگونگی مدیریت رشته‌ها در btparse، راهنمای bt_strings را مشاهده نمایید.

برای دستکاری و دسترسی به جدول ماکروهای btparse، به bt_macros مراجعه کنید.

برای تفکیک نام نویسندگان و فهرست‌ها به روش BibTeX با استفاده از btparse، به bt_split_names مراجعه فرمایید.

برای اتصال مجدد نام نویسندگان، به bt_format_names مراجعه کنید.

توابع متفرقه برای پردازش رشته‌ها به روش BibTeX: bt_misc.

تعریف نیمه‌رسمی زبان در bt_language قرار دارد.

Greg Ward <gward@python.net>

Copyright (c) 1996-97 by Gregory P. Ward.

این کتابخانه یک نرم‌افزار آزاد است؛ شما می‌توانید آن را تحت شرایط پروانه عمومی کلی کتابخانه گنو (GNU Library General Public License) طبق انتشار بنیاد نرم‌افزارهای آزاد؛ چه نسخه ۲ پروانه و چه (به انتخاب خودتان) هر نسخه پس از آن، بازتوزیع کرده یا تغییر دهید.

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

شما باید همراه با این کتابخانه نسخه‌ای از پروانه عمومی کلی کتابخانه گنو را دریافت کرده باشید؛ در غیر این صورت، به آدرس زیر مکاتبه فرمایید: Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

صفحه اصلی btOOL که می‌توانید اطلاعات به‌روز درباره btparse (و بارگیری آخرین نسخه) را در آن به دست آورید:

http://starship.python.net/~gward/btOOL

همچنین می‌توانید آخرین نسخه Text::BibTeX (کتابخانه پرل که یک رابط سطح بالا برای btparse ارائه می‌دهد) را در آنجا بیابید. برای ساخت Text::BibTeX به btparse نیاز است و باید به‌طور جداگانه بارگیری شود.

هر دو کتابخانه همچنین در CTAN (شبکه جامع آرشیو تک، http://www.ctan.org/tex-archive) و CPAN (شبکه جامع آرشیو پرل، http://www.cpan.org) موجود هستند. در CTAN مسیر biblio/bibtex/utils/btOOL و در CPAN مسیر authors/Greg_Ward را جستجو کنید. برای نمونه:

http://www.ctan.org/tex-archive/biblio/bibtex/utils/btOOL
http://www.cpan.org/authors/Greg_Ward

هر دو پیوند شما را به آخرین نسخه Text::BibTeX و btparse می‌رسانند -- اما همواره توصیه می‌شود از سایت‌های پربازدید مانند CTAN و CPAN از طریق آینه‌ها (mirrors) استفاده کنید.

2025-07-14 btparse, version 0.91