| BT_SPLIT_NAMES(1) | btparse | BT_SPLIT_NAMES(1) |
نام (NAME)
bt_split_names - تفکیک نامها و فهرستهای نام در BibTeX
خلاصه دستور (SYNOPSIS)
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);
هنگامی که پروندههای BibTeX برای هدف اصلی خود---مدخلهای کتابشناختی که انتشارات علمی را توصیف میکنند---استفاده میشوند، پردازش فهرستهایی از نامها (بیشتر نویسندگان و ویراستاران) اهمیت مییابد. اگرچه چنین پردازش نامی خارج از حوزهٔ پایگاهدادهٔ چندمنظورهٔ بیشتر بخشهای کتابخانهٔ btparse است، این توابع تفکیک به عنوان سازشی با واقعیت ارائه شدهاند: بیشتر پروندههای دادهٔ BibTeX از قراردادهای BibTeX برای نامهای نویسندگان استفاده میکنند، و کتابخانهای که آن دادهها را پردازش میکند باید توانایی پردازش نامها را نیز داشته باشد.
پردازش نام در دو مرحله صورت میگیرد: نخست، تقسیم یک فهرست از نامها به رشتههای مجزا؛ دوم، تقسیم هر نام به «بخشها» (first، von، last، و jr). مرحلهٔ اول در واقع کاملاً عمومی است: میتوانید یک جداکننده (مانند 'and'، که برای فهرستهای نام به کار میرود) را برگزینید و از آن برای تقسیم هر رشتهای به زیررشتهها بهره ببرید. سپس میتوان bt_split_list() را برای شکستن رشتهٔ اصلی و استخراج زیررشتهها فراخوانی کرد. با این حال، bt_split_name() کاملاً مختص به نامهای چهاربخشی نویسندگان است که با استفاده از قراردادهای BibTeX نوشته شدهاند. (این قراردادها به طور غیررسمی در هر مستندات BibTeX شرح داده شدهاند؛ توصیفی که در اینجا خواهید یافت رسمیتر و الگوریتمیتر---و در نتیجه درکش دشوارتر است.)
برای اطلاعات دربارهٔ تبدیل دوبارهٔ نامهای تفکیکشده به رشتهها به روشهای گوناگون، bt_format_names را ببینید.
توابع (FUNCTIONS)
- bt_split_list()
-
bt_stringlist * bt_split_list (char * string, char * delim, char * filename, int line, char * description)رشتهٔ "string" را به زیررشتههایی که با "delim" (یک رشتهٔ ثابت) از هم جدا شدهاند تفکیک میکند. این تفکیک بر پایهٔ قواعدی انجام میگیرد که BibTeX برای تفکیک فهرست نامها استفاده میکند، بهویژه:
- جداکنندهها در ابتدا یا انتهای رشته نادیده گرفته میشوند
- جداکنندهها باید با فاصلهٔ خالی (whitespace) احاطه شده باشند
- تطابق جداکنندهها بدون حساسیت به بزرگی و کوچکی حروف است
- جداکنندهها در عمق غیرصفر آکولادها نادیده گرفته میشوند
برای نمونه، اگر جداکننده "and" باشد، آنگاه رشتهٔ
Candy and Apples AnD {Green Eggs and Ham}
به سه زیررشته تفکیک میشود: "Candy"، "Apples"، و "{Green Eggs and Ham}".
اگر جداکنندههای اضافی در دو انتهای رشته باشند---برای نمونه، یک "and" در ابتدای رشته---در این صورت در اولین/آخرین رشته لحاظ میشوند؛ در حال حاضر هیچ هشداری چاپ نمیشود، اما ممکن است این رفتار تغییر کند. جداکنندههای متوالی ("and and") به صدور هشدار و افزوده شدن یک رشتهٔ NULL به فهرست زیررشتهها منجر میشوند. برای نمونه، رشتهٔ
and Joe Q. Blow and and Smith, Jr., John
به سه زیررشته تفکیک خواهد شد: "and Joe Q. Blow"، "NULL"، و "Smith, Jr., John".
(اگر این قواعد تا اندازهای عجیب به نظر میرسند، مرا سرزنش نکنید: من فقط رفتار مشاهدهشده در BibTeX را پیادهسازی کردهام و پیامهای هشداری را برای یکی از خطاهای واضحتر و آسانتر برای شناسایی افزودهام.)
زیررشتهها در قالب یک ساختار "bt_stringlist" بازگردانده میشوند:
typedef struct
{
char * string;
int num_items;
char ** items;
} bt_stringlist;
در حال حاضر هیچ رابط تمیز و سادهای برای این ساختار وجود ندارد: فقط باید خودتان درون آن به جستجو بپردازید. فیلدها عبارتند از:
- "string"
- یک رونوشت از پارامتر "string" که به bt_split_list() ارسال شده است، اما با نویسههای NUL که جایگزین فاصلهٔ پس از هر زیررشته شدهاند. (این امر ایمن است، زیرا جداکنندهها باید با فاصلههای خالی احاطه شده باشند، یعنی پس از هر زیررشته یک فاصلهٔ خالی وجود دارد که بخشی از زیررشته نیست.) احتمالاً نباید با "string" دستکاری انجام دهید؛ این فیلد فقط به این دلیل وجود دارد تا bt_free_list() چیزی برای free() کردن در اختیار داشته باشد.
- "num_items"
- تعداد زیررشتههای یافتشده در رشتهٔ ارسالشده به bt_split_list().
- "items"
- آرایهای
از
اشارهگرهای
"num_items" به
درون
"string".
برای
نمونه،
"items[1]" به
زیررشتهٔ
دوم اشاره
دارد. از
آنجا که
"string" با
نویسههای
NUL تغییر
یافته است،
رفتار با
"items[i]" به
عنوان یک
رشتهٔ عادی
C ایمن است.
پارامترهای "filename"، "line"، و "description" همگی برای تولید پیامهای هشدار استفاده میشوند. "filename" و "line" صرفاً نشان میدهند که رشته از کجا آمده است، و "description" شرحی کوتاه (یک کلمهای) از زیررشتهها است. برای نمونه، اگر فهرستی از نامها را تفکیک میکنید، مقدار "name" را برای "description" وارد کنید---به این ترتیب، هشدارها به جای «substring x» به «name X» اشاره خواهند کرد.
- bt_free_list()
-
void bt_free_list (bt_stringlist *list)
یک ساختار "bt_stringlist" بازگرداندهشده توسط bt_split_list() را آزاد میکند. یعنی، رونوشت رشتهای را که به bt_split_list() داده بودید آزاد کرده، و سپس خود ساختار را آزاد مینماید.
- bt_split_name()
-
bt_name * bt_split_name (char * name, char * filename, int line, int name_num)یک نام نویسنده با سبک BibTeX را به چهار بخش تفکیک میکند: first، von، last، و jr. این تابع میتواند تقریباً تمام نامها به سبک زبانهای عمدهٔ اروپای غربی را پردازش کند، اما نه بهطور کامل. (افسوس!)
تفکیک یک نام نخست با تقسیم آن به نشانهها (tokens) انجام میگیرد؛ نشانهها با فاصلهٔ خالی یا کاما در سطح آکولاد صفر از یکدیگر جدا میشوند. بنابراین نام
van der Graaf, Horace Q.
پنج نشانه دارد، در حالی که نام
{Foo, Bar, and Sons}تنها شامل یک نشانه است.
نحوهٔ تقسیم نشانهها به بخشها به ساختار و قالب نام بستگی دارد. اگر نام فاقد هرگونه کاما در سطح آکولاد صفر باشد (مانند مثال دوم)، آنگاه فرض میشود که در یکی از دو قالب «first last» یا «first von last» است. اگر هیچ نشانهای وجود نداشته باشد که با حرف کوچک آغاز شود، آنگاه قالب «first last» فرض میشود: نشانهٔ پایانی نام خانوادگی (last) است، و تمام نشانههای دیگر نام کوچک (first) را تشکیل میدهند. در غیر این صورت، نخستین توالی پیوسته از نشانهها که با حروف کوچک شروع میشوند به عنوان بخش `von' در نظر گرفته میشود؛ اگر این توالی شامل نشانهٔ پایانی باشد، آنگاه هشداری چاپ شده و نشانهٔ پایانی به اجبار بخش `last' تعیین میشود.
اگر نام دارای یک کاما باشد، فرض میشود که در قالب «von last, first» است. توالی آغازین از نشانهها با حروف ابتدایی کوچک، در صورت وجود، بخش `von' را میسازد؛ نشانههای میان `von' و کاما بخش `last' را تشکیل میدهند؛ نشانههای پس از کاما بخش `first' را میسازند. باز هم، اگر هیچ نشانهای پس از توالی آغازین نشانههای با حروف کوچک وجود نداشته باشد، هشداری چاپ میشود و نشانهای که بلافاصله پیش از کاما قرار دارد به عنوان بخش `last' در نظر گرفته میشود.
اگر نام دارای بیش از دو کاما باشد، هشداری چاپ شده و با نام چنان رفتار میشود که گویی تنها دو کامای نخست وجود داشتهاند.
در نهایت، اگر نام دارای دو کاما باشد، فرض میشود در قالب «von last, jr, first» است. (این تنها روش برای نمایش نامی است که بخش `jr' دارد.) تجزیهٔ نام همانند نام دارای یک کاما است، با این تفاوت که نشانههای میان دو کاما به عنوان بخش `jr' در نظر گرفته میشوند.
تنها موردی که قراردادهای نام BibTeX بهدرستی از عهدهٔ آن برنمیآیند، نامی دارای بخش 'jr' است که با کاما از نام خانوادگی جدا نشده باشد؛ برای نمونه: Henry Ford Jr. George Herbert Walker Bush III
هر دوی این موارد هم توسط BibTeX و هم bt_split_name() بهصورت نادرست تفسیر خواهند شد: نشانهٔ "Jr." یا "III" به عنوان نام خانوادگی در نظر گرفته میشود، و سایر نشانهها به عنوان یک نام کوچک دو یا چهاربخشی قلمداد میشوند. راهکار دور زدن مشکل این است که 'jr' را در نام خانوادگی بگنجانید:
Henry {Ford Jr.} George Herbert Walker {Bush III}اما این کار استخراج نام خانوادگی به تنهایی را غیرممکن میسازد، برای مثال جهت تولید ارجاعهای سبک «نویسنده-سال» ("author-year"). این نقص طراحی ممکن است در نسخههای آیندهٔ btparse برطرف شود.
نام تفکیکشده به عنوان یک ساختار "bt_name" بازگردانده میشود:
typedef struct { bt_stringlist * tokens; char ** parts[BT_MAX_NAMEPARTS]; int part_len[BT_MAX_NAMEPARTS]; } bt_name;باز هم، هیچ رابط مناسبی برای این ساختار وجود ندارد؛ شما صرفاً باید به فیلدها بهصورت جداگانه دسترسی داشته باشید. آنها عبارتند از:
- "tokens"
- نام، تفکیکشده به یک فهرست تخت از نشانهها. برای شرح ساختار "bt_stringlist" به موارد بالا مراجعه کنید.
- "parts"
- آرایهای از آرایههایی از اشارهگرها به فهرست نشانهها. بُعد اصلی این ساختار، «بخش نام» است؛ شما باید این بُعد را با استفاده از شمارشگر "bt_namepart" اندیسگذاری کنید. برای نمونه، "parts[BTN_LAST]" آرایهای از اشارهگرها به نشانههای تشکیلدهندهٔ نام خانوادگی است؛ "parts[BTN_LAST][1]" یک "char *" است: دومین نشانه از بخش 'last'؛ و "parts[BTN_LAST][1][0]" اولین نویسه از دومین نشانه از بخش 'last' است.
- "part_len"
- طول هر بخش،
بر حسب
نشانه. برای
نمونه،
میتوانید
روی تمام
نشانهها
در بخش 'first' به
صورت زیر
پیمایش
کنید (با
این فرض که
"name" یک
"bt_name *"
بازگرداندهشده
توسط bt_split_name()
باشد):
for (i = 0; i < name->part_len[BTN_FIRST]; i++) { printf ("token %d of first name: %s\n", i, name->parts[BTN_FIRST][i]); }
- bt_free_name()
-
void bt_free_name (bt_name * name)
ساختار "bt_name" ایجادشده توسط bt_split_name() (شامل ساختار "bt_stringlist" درون "bt_name") را آزاد میکند.
همچنین ببینید (SEE ALSO)
btparse, bt_format_names
نویسنده (AUTHOR)
Greg Ward <gward@python.net>
| 2025-07-14 | btparse, version 0.91 |