اولین بار است که به اینجا می‌آیید؟ راهنمای سایت را بخوانید!
Close Sidebar
وب‌سایت پرسش و پاسخ پارسی‌لاتک جایی برای پرسش و پاسخ درباره سیستم حروف‌چینی لاتک و بسته زی‌پرشین است. در اینجا می‌توانید سوال‌های خود را بپرسید و به سوال‌های دیگران پاسخ دهید.

محبوب‌ترین برچسب‌ها

رفع خطا جدول مراجع xepersian ریاضی‌نویسی شکل فونت فهرست مطالب شماره‌گذاری منابع bidi پانویس بیب‌تک tikz تک‌لایو parsilatex بیمر اسلاید زی‌پرشین پاورقی bibtex سربرگ نماد رسم شکل فرمول‌نویسی قالب ارجاع‌دهی biditexmaker هدر ویرایشگر beamer واژه‌نامه اندازه فونت texstudio عنوان فصل ماتریس اعمال نشدن تغییرات در پی‌دی‌اف رسم جدول bidipresentation شماره صفحه حاشیه رنگ عنوان شکل اسلاید فارسی محیط قضیه گراف مکان شکل tikzpicture حروف‌چینی کد شماره فصل enumerate tabriz_thesis نمایه align زیرنویس شکل کادر itemize فهرست اشکال الگوریتم listings عدم اجرا نیم‌فاصله متن لاتین و فارسی بسته فاصله بین خطوط قالب پایان‌نامه فرمول نصب تک‌لایو فارسی‌تک hyperref شماره فرمول glossaries کپشن نمودار خروجی لاتک حروف‌چینی چندستونی فونت فارسی و انگلیسی ماکرونویسی biditools شماره پاورقی پیوست‌ سوال امتحانی فاصله‌گذاری فرمول چندضابطه‌ای subfigure extrafootnotefeatures header texmaker pdf tex biditufte-book longtable تصویر شمارنده texlive2015 زیرنویس خطا رسم نمودار شماره‌گذاری صفحات پایان نامه دیاگرام فهرست جداول میک‌تک texlive2016 تنظیم جدول آکولاد kashida texworks caption اندیس lollipop iust-thesis multicol فصل‌نویسی شعر سوال چهارگزینه‌ای بولد تورفتگی اعداد فارسی فاصله عمودی xindy چپ‌چینی اوبونتو میکروسافت ورد قاب geometry texlive fancyhdr وسط‌چینی تک لایو 2015 عنوان بخش شماره گذاری به‌روزرسانی بسته aimc46 صفر توخالی فرمول طولانی بیرون‌زدگی xelatex کاما tcolorbox پوستر فاصله سطرها نوشتافت شکست خط tex-programming فونت اعداد pgfplots قرآن tabriz-thesis ایتالیک winedt جستجوی معکوس فلش جایابی تصویر قالب کتاب پاراگراف‌بندی بازیابی اطلاعات هایپرلینک فهرست نمادها شمارنده فصل font محیط ریاضی رسم کادر جداکننده جدول طولانی فهرست تصاویر شماره‌گذاری فرمول algorithm2e فونت بولد proof equation bidipoem eps جدول افقی عکس به‌روزرسانی پانویس چندستونی کمک مالی فاصله خطوط حروف‌چینی شعر زیرشکل minipage قلم پانویس پاراگرافی ltrfootnote پیوست computeautoilg متن فارسی و انگلیسی فرمول چندخطی neveshtuft غلط‌گیری املایی تک‌پارسی پیکان لاتکس tabular baselineskip شماره قسمت قسمت عنوان جدول
13 نفر آنلاین
0 عضو و 13 مهمان در سایت حاضرند
بازدید امروز: 65401
بازدید دیروز: 7936
بازدید کل: 25157351

چگونه تشخیص دهیم که ورودی یک ماکرو، یک length است؟

0 رای
658 بازدید

من ماکرویی دارم که می‌خوام بررسی کند که ورودی یک length معتبر است یا نه و اگر نامعتبر است یه عملیات دیگری انجام بده
کد کمینه

\documentclass[]{article}

\newcommand{\islength}[1]{if #1 is length print true else print false}
\begin{document}
\islength{1cm}
\islength{Hi}
\end{document}
سوال شده بهمن 21, 1397 توسط مجتبی (587 امتیاز)

3 پاسخ

+2 رای

length واژه درستی نیست. توی تک ما به این بعد یا dimen می‌گوییم.

هدف پاسخ زیر یک تجزیه و تحلیل است و ارائه راه‌حل نیست. نویسنده پاسخ وظیفه ارائه پاسخ ندارد. برنامه‌نویسی راه‌حل بر دوش پرسش‌کننده است.

وقتی داریم در مورد بعد صحبت می‌کنیم و می‌خواهیم به یک dimen register یک بعد بدهیم سه حالت زیر بصورت کلی پیش میاد.

حالت نخست

بعدی که ما می‌دهیم از عدد و واحد تشکیل شده باشه. اعداد ‍decimal می‌تونند باشند و واحد می‌تونه یکی از واحد‌هایی که تک می‌فهمه باشه (در حالت دوم این واحد‌ها ذکر شدند). در این حالت تک خطایی نمی‌ده.

بنابرین چیزی همانند \dimen0=4.01pt برای تک قابل فهمه.

حالت دوم

برای بعد ما عدد قرار می‌دهیم اما واحدی قرار نمی‌دهیم یا اگر واحدی وجود داره، واحدی نیست که تک اون رو می‌فهمه همانند \dimen0=1.2. در این صورت تک خطای

Illegal unit of measure (pt inserted).

می‌دهد. واحدهایی که برای تک قابل فهم هستند بصورت زیر هست.

em, ex, in, pt, pc, cm, mm, dd, cc, bp, or sp

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

@<Scan for \(a)all other units and adjust |cur_val| and |f|...@>=
if scan_keyword("in") then set_conversion(7227)(100)
@.in@>
else if scan_keyword("pc") then set_conversion(12)(1)
@.pc@>
else if scan_keyword("cm") then set_conversion(7227)(254)
@.cm@>
else if scan_keyword("mm") then set_conversion(7227)(2540)
@.mm@>
else if scan_keyword("bp") then set_conversion(7227)(7200)
@.bp@>
else if scan_keyword("dd") then set_conversion(1238)(1157)
@.dd@>
else if scan_keyword("cc") then set_conversion(14856)(1157)
@.cc@>
else if scan_keyword("sp") then goto done
@.sp@>
else @<Complain about unknown unit and |goto done2|@>;
cur_val:=xn_over_d(cur_val,num,denom);
f:=(num*f+@'200000*remainder) div denom;@/
cur_val:=cur_val+(f div @'200000); f:=f mod @'200000;
done2:

@ @<Complain about unknown unit...@>=
begin print_err("Illegal unit of measure ("); print("pt inserted)");
@.Illegal unit of measure@>
help6("Dimensions can be in units of em, ex, in, pt, pc,")@/
  ("cm, mm, dd, cc, bp, or sp; but yours is a new one!")@/
  ("I'll assume that you meant to say pt, for printer's points.")@/
  ("To recover gracefully from this error, it's best to")@/
  ("delete the erroneous units; e.g., type `2' to delete")@/
  ("two letters. (See Chapter 27 of The TeXbook.)");
@:TeXbook}{\sl The \TeX book@>
error; goto done2;
end

بنابراین کاری که در این حالت می‌خواهی انجام بدی این هست که tokenهای آخر آرگومانت که حرف هستند رو با واحد‌های مورد قبول تک مقایسه کنی و در صورتی که تفاوت داره نتیجه می‌گیری که آرگومانت بعد نیست.

حالت سوم

مقدار بعد با چیزی غیر از یک عدد شروع می‌شه همانند \dimen0=pt1. در این‌صورت تک خطای

Missing number, treated as zero.

می‌ده. بنابراین در این حالت باید چک کنی که آرگومانت با یک عدد یا . شروع میشه چونکه .5pt هم برای تک قابل درکه.

پاسخ داده شده بهمن 23, 1397 توسط وفا (24,432 امتیاز)
سپاس از پاسخگوییتون
با راهنمایی شما نتیجه کاری که تا حالا کردم رو اینجا میزارم که از امکانات بسته xstring برای کار روی رشته‌ها استفاده کردم. البته خط 7 باعث بروز خطا میشه. اگه این روش به نتیجه میرسه تا من در یک پرسش دیگر مطرح کنم.
\documentclass[]{article}
\usepackage{xstring}
\def\units{em,ex,in,pt,pc,cm,mm,dd,cc,bp,sp}
\def\isdimen#1{
\def\numpart{\StrRight{#1}{2}}   
\def\unitpart{\StrGobbleRight{#1}{2}}
\IfSubStr{\units}{\unit}{true}{false}
}
\begin{document}
\isdimen{12pt}
\end{document}
سپاس از شما
من آشنایی با بسته xstring ندارم و در حال حاضر هم دسترسی به تک ندارم چون در مسافرت هستم. اگر عجله ندارید، وقتی برگشتم کد شما را آزمایش می‌کنم. ولی بصورت کلی آزمایش اینکه یک آرگومان بعد است به این سادگی نیست. آزمایش اینکه آیا یک آرگومان عدد صحیح است به اندازه کافی مشکل است و آزمایش اینکه یک آرگومان بعد هست باید پیچیده‌تر باشد. ایده من این است که در سورس تک نگاه کنم و کد پاسکال را با کد تک بازنویسی کنم تا بتوانم آزمایش کنیم که آیا یک آرگومان بعد هست یا نیست.
سپاس از پاسخگویی شما.
عجله‌ای نیست
سفرتون سلامت
+1 رای

تنها کاری که در ادامه انجام شده است اصلاح کدی است خودتان در کامنت‌ها قرار داده‌اید.

\documentclass[]{article}
\usepackage{xstring}
\def\units{em,ex,in,pt,pc,cm,mm,dd,cc,bp,sp}
\def\isdimen#1{%
    \StrRight{#1}{2}[\unitpart]
    \StrGobbleRight{#1}{2}[\numpart]
    \IfSubStr{\units}{\unitpart}{true}{false}
}
\begin{document}
    \isdimen{12pt}
\end{document}

نکته‌ اینجاست که خروجی باید باز شده در یک ماکرو ذخیره شود همانطوری که خودتان انجام دادید لکن از آنجایی که در بخش ۳.۲ راهنمای بسته xstring توضیح داده شده است ماکروهای این بسته به طور خالص قابلیت گسترش ندارند و باید بهمان شیوه‌ای که خود بسته ارائه داده است بکار روند.

پاسخ داده شده بهمن 27, 1397 توسط سید جواد (4,427 امتیاز)
سپاس از شما. هر چقدر سعی می‌کردم خروجی StrRight رو با دستور edef در یک ماکرو ذخیره کنم خطا می‌داد که شما نحوه ذخیره کردن آن را گفتید.
 سپاس فراوان از شما.
0 رای

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

\documentclass[]{article}
\usepackage{xstring}
\def\units{em,ex,in,pt,pc,cm,mm,dd,cc,bp,sp}
\def\res{true}
\def\isdimen#1{%
    \StrRight{#1}{2}[\unitpart]
    \StrGobbleRight{#1}{2}[\numpart]
    \IfSubStr{\units}{\unitpart}{}{\def\res{false}}
    \IfDecimal{\numpart}{}{\def\res{false}}
    \res
}
\begin{document}
    \isdimen{12.4cm}
    \isdimen{wecm}
    \isdimen{12cd}
\end{document}
پاسخ داده شده بهمن 27, 1397 توسط مجتبی (587 امتیاز)
...