اولین بار است که به اینجا می‌آیید؟ راهنمای سایت را بخوانید!
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 شماره قسمت قسمت عنوان جدول
73 نفر آنلاین
0 عضو و 73 مهمان در سایت حاضرند
بازدید امروز: 62103
بازدید دیروز: 7936
بازدید کل: 25154055

چگونه دستوری با دو آرگومان اختیاری بنویسیم

+3 رای
2,630 بازدید

همانطور که می‌دانید دستور newcommand اجازه تعریف فقط یک آرگومان اختیاری می‌دهد. چگونه دستوری با دو آرگومان اختیاری تعریف کنیم؟

سوال شده خرداد 29, 1397 توسط مجتبی (587 امتیاز)

8 پاسخ

+6 رای
 
بهترین پاسخ

سلام
بنا به درخواست دوست بزرگوارم جناب رضویان عزیز و با اجازه‌ی جناب خلیقی عزیز حالتی را که ایشان فرمودند را با مثالی بیان می‌کنم. جالب بودن این روش در این است که این روش بدون هیچ بسته و یا دستور شرطی و فقط با دو \newcommand ایجاد می‌شود و قابل تعمیم نیز هست.
هدف این است که کاربر در این صفحه روش‌های متفاوتی را ببیند.
برای این‌کار دو ماکرو مطابق زیر ایجاد شده است:

\newcommand{\TCMD}[1][\textcolor{red}{Default1}]{%
\def\ArgI{{#1}}\textcolor{red}{#1}~%
\TCMDD}
\newcommand\TCMDD[1][\textcolor{blue}{Default2}]{%
\textcolor{blue}{#1}}

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


\documentclass[12pt]{article}
\usepackage{xcolor}
\begin{document}
\setlength{\parindent}{0pt}
\newcommand{\TCMD}[1][\textcolor{red}{Default1}]{%
\def\ArgI{{#1}}\textcolor{red}{#1}~%
\TCMDD
}
\newcommand\TCMDD[1][\textcolor{blue}{Default2}]{%
\textcolor{blue}{#1}}
\TCMD\\
\TCMD[][\hspace*{-.15cm}Two]\\
\TCMD[One][]\\
\TCMD[][]\\
\TCMD[One][Two]\\
\end{document}

خروجی زیر را نیز با نسخه‌های اولیه‌ی تکلایو 2018 دریافت می‌کنیم:



enter image description here

درود.

پاسخ داده شده خرداد 30, 1397 توسط شاپور مددپور (8,667 امتیاز)
انتخاب شده خرداد 30, 1397 توسط مجتبی
بسیار عالی
بین پاسخ‌های موجود این تنها پاسخی است که من آن را دوست دارم و به همین دلیل یک امتیاز مثبت به شما دادم. من به هر شخصی امتیاز مثبت نمی‌دهم و امتیاز مثبت گرفتن از من کار بسیار دشواری است.
@ وفای عزیزم
شما استاد و تاج سر بنده هستید. من این روز را هرگز فراموش‌نمی‌کنم؛ همان‌طور که اولین ایمیلی که به من دادید و مرا تشویق به کار با تک کرده بودید را همیشه به یاد دارم. بدون شک راهنمایی‌های ارزنده‌ی شما را مثل همیشه چراغ راه خود قرار می‌دهم. شما بر گردن جامعه‌ی فارسی‌زبان، در زمینه‌ی تک حق بزرگی دارید؛ زیراکه بدون هیچ چشمداشت و کمکی و صرفا از روی علاقه به زبان فارسی و فردوسی بزرگ این کارهای را به یادگار گذاشته‌اید. دستمریزاد. سلامتی و موفقیت شما را از خداوند بزرگ خواهانم.
ارادتمند همیشگی شما، مددپور
+۱ از زحمتی که کشیدید بسیار سپاسگزارم و نیز از لطف همیشگی‌تان.

شما با صبر و حوصله‌ای که دارید پاسخ‌های بسیار ارزشمندی را از خود در سایت باقی گذاشته و خواهید گذاشت.
@وفا
شما که استاد هستید و نظرتان صائب ولی شخصا در بسیاری موارد برای ایجاد انگیزش به کاربران در موارد بسیاری به پاسخ‌ها --در صورتی که خیلی بی‌ربط نباشد-- +۱ می‌دهم. :دی
@ سیدجواد عزیزم
بدون شک در محضر شما بزرگواران درس پس می‌دهم. سایت پارسی‌لاتک با تمام انسان‌های بزرگش مانند شما، کمک  بزرگی به پیشرفت لاتک در کشور عزیزمان انجام داده است. از شما و تمام بزرگواران این سایت سپاسگزارم.
دادن رای مثبت به تلاش دیگران چند فایده دارد:
۱. انگیزه تلاش و لذت بردن از لاتک را ایجاد می کند.
۲. در زمانی که اساتید زبردست فرصت پاسخگویی ندارند دیگران برای پاسخگویی تلاش می نمایند و به این صورت مشکلات کاربران حل می شود.
با تشکر از همه کسانی که تجربیات خود را در اختیار ما می گذارند و به ما انگیزه می دهند.
+5 رای

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


همان‌طور که جناب رضویان فرمودند بسته‌ی xparse نیز امکانات جالبی در این زمینه دارد. به خاطر معرفی بیشتر این بسته به کاربر من از امکانات این بسته استفاده می‌کنم.
در این بسته به کمک ساختار زیر می‌توان ماکرو‌هایی با تنوع زیادی ساخت:

\DeclareDocumentCommand

به صورت زیر می‌توان ماکرویی با دو آرگومان پیش‌فرض One و Two ساخت:

\DeclareDocumentCommand{\FCMD}{O{\textcolor{red}{One}\qquad} O{\textcolor{blue}{Two}}}{\textcolor{purple}{#1}~\textcolor{orange}{#2}}

در این ساختار O{default} عملیات ایجاد آرگومان پیش‌فرض را انجام می‌دهد
(optional argument). حال ماکروی \FCMD را به صورت‌های زیر به‌کار می‌بریم:

\FCMD \\
\FCMD[New One]\\
\FCMD[New One][]\\
\FCMD[][]\\
\FCMD[New One][New Two]

دریافتی ما به صورت زیر خواهد بود:



enter image description here

امکان ایجاد یک آرگومان استاندارد اجباری (mandatory) با درج m نیز مطابق زیر فراهم است که می‌تواند یک یا چند توکن باشد:

\DeclareDocumentCommand{\FFCMD}{O{\textcolor{red}{One}} m O{\textcolor{blue}{Two}}}{\textcolor{purple}{#1}~#2~\textcolor{orange}{#3}}

حال ماکروی \FFCMD را به صورت‌های زیر به‌کار می‌بریم:

\FFCMD{Next} \\
\FFCMD[New One]{Next}\\
\FFCMD[New One]{Next}[]\\
\FFCMD[]{}[]\\
\FFCMD[]{Alone}[]\\
\FFCMD[New One]{Next}[New Two]

دریافتی ما به صورت زیر خواهد بود:



enter image description here

راهنمای این بسته را می‌توانید از اینجا تهیه کنید.
از بسته‌ی xcolor صرفاً جهت ایجاد رنگ برای نمایان کردن بیشتر آرگومان‌ها بهره گرفته‌ام.

تمام دستورات بالا نیز مطابق زیر است:


\documentclass{article}
\usepackage{xcolor}
\usepackage{xparse}
\usepackage[logo=on,pdfinfo=on,
inlinemathdigits=persian,%
displaymathdigits=persian%
]{xepersian}
\settextfont[Scale=1.2]{IRZar}
\settextdigitfont[Scale=.9]{Yas}
\setmathdigitfont[Scale=.9]{PGaramond}
\DeclareDocumentCommand{\FCMD}{O{\textcolor{red}{One}\qquad} O{\textcolor{blue}{Two}}}{\textcolor{purple}{#1}~\textcolor{orange}{#2}}
\setlength{\parindent}{0pt}
\begin{document}\noindent
\null\vfill\latin
\FCMD \\
\FCMD[New One]\\
\FCMD[New One][]\\
\FCMD[][]\\
\FCMD[New One][New Two]
\DeclareDocumentCommand{\FFCMD}{O{\textcolor{red}{One}} m O{\textcolor{blue}{Two}}}{\textcolor{purple}{#1}~#2~\textcolor{orange}{#3}}

\FFCMD{Next} \\
\FFCMD[New One]{Next}\\
\FFCMD[New One]{Next}[]\\
\FFCMD[]{}[]\\
\FFCMD[]{Alone}[]\\
\FFCMD[New One]{Next}[New Two]
\end{document}

موفق باشید.

پاسخ داده شده خرداد 29, 1397 توسط شاپور مددپور (8,667 امتیاز)
ویرایش شده خرداد 29, 1397 توسط شاپور مددپور
+۱ سپاس از زحمات
+1 به این همه انرژی.
+4 رای

برای این منظور از دستور بدوی def و ماکروی @ifnextchar استفاده می‌کنیم.

\@ifnextchar<token>{<true>}{<false>}

این دستور چک می‌کند که اگر token بعدی با token ای که در دستور هست یکی باشد قسمت true و در غیر این‌صورت قسمت false را اجرا می‌کند. با این توضیحات به کد زیر دقت کنید

\documentclass{book}
\makeatletter
\def\mymacro{%
    \@ifnextchar[{\mymacroone}{without arguement}%
}
\def\mymacroone[#1]{%
    \@ifnextchar[{\mymacrotwo[#1]}{one arguement #1}%
}
\def\mymacrotwo[#1][#2]{%
    two arguments #1 and #2%
}
\makeatother
\begin{document}
    \mymacro\par
    \mymacro[Hi]\par
    \mymacro[Hi][Bye]
\end{document}

این کد خروجی زیر را تولید می‌کند
enter image description here

پاسخ داده شده خرداد 29, 1397 توسط مجتبی (587 امتیاز)
ویرایش شده خرداد 29, 1397 توسط سید جواد
+۱ بخاطر استفاده از \@ifnextchar

از آنجایی که این راه حل ممکن است برای مبتدیان کمی گیج کننده به نظر آید در ادامه با افزودن یک پاسخ دیگر یک راه حل لاتک ارائه می‌شود.
البته @ifnextchar از دستورات بدوی تک نیست و بلکه از ماکروهای هسته لاتک است.
با سپاس اصلاح گردید.
درود بر شما +1
یک راه‌حل ساده استفاده از دو `\newcommand` است. لینک زیر را ببینید: https://texfaq.org/FAQ-twooptarg
@وفا
ممنون از راهنمایی‌های همیشگی‌تان

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

همانطوری که در راه حل جناب @باغبان مشهود است این راه حل با استفاده از \@ifnextchar به درستی و خوبی جواب می‌دهد و براحتی می‌توان ان را برای حتی تعداد بیشتری آرگومان اختیاری توسعه داد.

اما از آنجایی که ممکن است برای کسانی که تازه با لاتک آشنا شده‌اند کمی گیج کننده به نظر آید راه حل زیر با کمک بسته twoopt ممکن است.

\documentclass{article}
\usepackage{twoopt}

\newcommandtwoopt{\bsp}[3][AA][BB]{#1,#2,#3}

\begin{document}

\bsp[aa][bb]{cc}

\bsp[aa]{cc}

\bsp{cc}

\end{document}

همانطور که مشاهده می‌نمایید فرم تعریف دستور بسیار شبیه \newcommand لاتک است با این تفاوت که بجای یک آرگومان اختیاری می‌تواند دو آرگومان را بپذیرد --ایده بکار رفته در طراحی بسته همانی است که جناب باغبان توضیح دادند--. ضمنا دستوراتی معادل برای \renewcommand و ‍\providecommand دارد.

خروجی کد فوق هم به صورت زیر خواهد بود.

enter image description here

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

پاسخ داده شده خرداد 29, 1397 توسط سید جواد (4,427 امتیاز)
ویرایش شده خرداد 29, 1397 توسط سید جواد
+۱ درود بر شما
درود بر شما +1
+1 رای

با تشکر از اساتید گرامی، یک روش با استفاده از pgfkeys به صورت زیر است:

\documentclass{article}
\usepackage{pgfkeys,xcolor}
\begin{document}
\pgfkeys{A/.store in=\A, B/.store in=\B}
\newcommand{\acommand}[1]{\pgfkeys{A,B,#1}%
\textcolor{blue}{\A} \textcolor{red}{\B}}
\newcommand{\bcommand}[2]{\acommand{A={#1},B={#2}}}

\noindent
\bcommand{Thank}{You}\\
\bcommand{Thank}\\
\bcommand{}{}\\
\end{document}

البته در اینجا آرگومان‌های اختیاری را به جای کروشه باید با آکولاد استفاده کنیم. خروجی به صورت زیر است:
enter image description here
این روش به سادگی قابل تعمیم به چند آرگومان اختیاری است.
از دوستان عزیز خواهش می‌کنم اگر نکته نظری در مورد این روش دارند بیان کنند تا از تجربیات ایشان بهره ببریم.

پاسخ داده شده خرداد 30, 1397 توسط rezaeian (735 امتیاز)
ویرایش شده خرداد 30, 1397 توسط rezaeian
+1 رای

بسته xargs نیز امکاناتی برای تعریف دستورات و محیط های جدید با تعداد آرگومان های اختیاری بیشتر از یک فراهم می کند. مثلا به صورت زیر با استفاده از دستور \newcommandx می توان دو آرگومان اختیاری در نظر گرفت.

\documentclass{article}
\usepackage{xargs,xcolor}
\begin{document}
\newcommandx{\mycommand}[3][1=red,2=\textit]{\textcolor{#1}{#2{#3}}}
\noindent
\mycommand{AAA}\\
\mycommand[blue]{AAA}\\
\mycommand[green][\textbf]{AAA}\\
\end{document}

که خروجی آن به صورت زیر است:
enter image description here

پاسخ داده شده خرداد 30, 1397 توسط rezaeian (735 امتیاز)
+1 رای

نزدیک به پنج سال از طرح پرسش و تقریبا چهار سال از ارائه آخرین پاسخ به این پرسش می‌گذرد. به اين پرسش، پاسخ‌های ابتکاری متعددی داده شده که بسیار جالب و آموزنده است و فهم بعضی از آن‌ها به سطح دانش بالایی از TeX نیاز دارد.

بنای این پاسخ بر این است که در قالب یک مثال کاربردی، یکی از امکانات LaTeX3 معرفی شود. در این مثال، یک دستور با دو آرگومان اختیاری، اولی با مقدار پیش‌فرض و دومی بدون مقدار پیش‌فرض تعریف و از آن استفاده شده است.

ویرایش: با تشکر از سید جواد بابت تذکر خوبشان، توجه داشته باشید که همان ساختار دستورات بسته xparse در LaTeX2e، به صورت درونی در LaTeX3 پیاده‌سازی شده است. بنابراین، همان‌طور که در مثال کمینه مشخص است، از این پس برای تعریف دستور جدید به فراخوانی هیچ بسته‌ای نیاز نیست؛ مگر این‌که درون بدنه دستور \NewDocumentCommand از دستوراتی استفاده شود که در بسته‌های LaTeX تعریف شده باشد.

تعریف دستور:

\NewDocumentCommand{\Section}{O{#2}mo}{%
  \section[#1]{#2}\IfValueT{#3}{\label{sec:#3}}
}

مثال کمینه:

\documentclass[11pt,a4paper]{article}
\title{Define a New \LaTeX3 Command with more than One Optional Argument}
\author{Abbas Shams}
\date{March 8, 2024}

\NewDocumentCommand{\Section}{O{#2}mo}{%
  \section[#1]{#2}\IfValueT{#3}{\label{sec:#3}}
}

\begin{document}
  \maketitle
  \tableofcontents
  % Use the both Optional Arguments:
  \Section[Short Title of Section One]{Long Title of Section One}[one]
  % Equivalent to: \section[Short Title of Section One]{Long Title of Section One}\label{sec:one}

  The both Optional Arguments used ($+$short title, $+$label).\\Also, see Sec.~\ref{sec:three}.

  % Only use the First Optional Argument:
  \Section[Short Title of Section Two]{Long Title of Section Two}
  % Equivalent to: \section[Short Title of Section Two]{Long Title of Section Two}

  Only the First Optional Argument used ($+$short title, $-$label).\\Also, see Sec.~\ref{sec:one} and Sec.~\ref{sec:three}.

  % Only use the Second Optional Argument:
  \Section{Long Title of Section Three}[three]
  % Equivalent to: \section{Long Title of Section Three}\label{sec:three}

  Only the Second Optional Argument used ($-$short title, $+$label).\\Also, see Sec.~\ref{sec:one}.

  % Use none of the Optional Arguments:
  \Section{Long Title of Section Four}
  % Equivalent to: \section{Long Title of Section Four}

  None of the Optional Arguments used ($-$short title, $-$label).\\Also, see Sec.~\ref{sec:one} and Sec.~\ref{sec:three}.
\end{document}

به توضیحات داخل مثال کمینه توجه فرمایید.

خروجی:

Define Command with Two Optional Argument

پاسخ داده شده 18 اسفند 1402 توسط عباس شمس (80 امتیاز)
ویرایش شده 19 اسفند 1402 توسط عباس شمس
+۱ این دستورات دقیقا همان بسته xparse در latex2e است که اینگار به صورت درونی در latex3 پیاده‌سازی شده است.

https://tex.stackexchange.com/questions/392649/what-is-the-relation-of-expl3-to-xparse
سپاس از تذکر شما. با اجازه شما این نکته را در متن پاسخ اضافه می‌کنم.
0 رای

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

\documentclass[a4paper]{article}

\usepackage{tikz}

\pgfkeys{
    /test/pgf/.cd,
    nom/.default = toto,
    nom/.store in = \nom,
    prenom/.store in = \prenom,
    prenom/.default = titi,
    nom, prenom
}

\newcommand{\qui}[1][]{
    \pgfkeys{/test/pgf/.cd, nom, prenom, #1}
    I am \prenom{} \nom{} !
}

\begin{document}
    \qui[prenom = toto, nom = titi]
\end{document}

دقت کنید در این روش هم تعداد آپشن‌ها دلخواه است. و چون از [] یا {} استفاده نمی‌شود شاید هنگام نوشتن کارمان راحت‌تر باشد. البته نظر اساتید اولویت دارد.

پاسخ داده شده خرداد 6, 1398 توسط محمد علی آزادنژاد (222 امتیاز)
...