2009-11-28 39 views
88

Làm thế nào để bạn tạo một lệnh với các đối số tùy chọn trong LaTeX? Cái gì như:Đối số tùy chọn LaTeX

\newcommand{\sec}[2][]{ 
    \section*{#1 
     \ifsecondargument 
      and #2 
     \fi} 
    } 
} 

Sau đó, tôi có thể gọi nó như

\sec{Hello} 
%Output: Hello 
\sec{Hello}{Hi} 
%Output: Hello and Hi 
+5

câu hỏi liên quan: [định nghĩa lệnh khác nhau có và không có đối số tùy chọn] (http://tex.stackexchange.com/q/308/1347) . –

Trả lời

111

Ví dụ từ guide:

\newcommand{\example}[2][YYY]{Mandatory arg: #2; 
           Optional arg: #1.} 

This defines \example to be a command with two arguments, 
referred to as #1 and #2 in the {<definition>}--nothing new so far. 
But by adding a second optional argument to this \newcommand 
(the [YYY]) the first argument (#1) of the newly defined 
command \example is made optional with its default value being YYY. 

Thus the usage of \example is either: 

    \example{BBB} 
which prints: 
Mandatory arg: BBB; Optional arg: YYY. 
or: 
    \example[XXX]{AAA} 
which prints: 
Mandatory arg: AAA; Optional arg: XXX. 
+15

Tôi nghĩ rằng câu hỏi là về cách xác định * liệu * một đối số tùy chọn đã được đưa ra, không cung cấp mặc định. –

+28

Mặc dù đó là sự thật, tôi tìm thấy câu hỏi này trong khi tìm kiếm một cách để cung cấp một đối số mặc định, vì vậy câu trả lời này là một trong những hữu ích nhất cho tôi. –

18

Ý tưởng chung đằng sau việc tạo ra "đối số tùy chọn" là lần đầu tiên xác định một lệnh trung gian quét trước để phát hiện những ký tự nào sẽ xuất hiện tiếp theo trong luồng mã thông báo và sau đó chèn các macro có liên quan để xử lý (các) đối số sắp tới khi thích hợp. Điều này có thể khá tẻ nhạt (mặc dù không khó) bằng cách sử dụng lập trình TeX chung. \@ifnextchar của LaTeX khá hữu ích cho những thứ như vậy.

Câu trả lời hay nhất cho câu hỏi của bạn là sử dụng gói xparse mới. Nó là một phần của bộ lập trình LaTeX3 và chứa các tính năng mở rộng để xác định các lệnh với các đối số tùy chọn khá tùy ý.

Trong ví dụ của bạn, bạn có macro \sec có thể lấy một hoặc hai đối số được đặt nhanh. Điều này sẽ được thực hiện bằng xparse như sau:

 
\documentclass{article} 
\usepackage{xparse} 
\begin{document} 
\DeclareDocumentCommand\sec{ m g }{% 
    {#1% 
     \IfNoValueF {#2} { and #2}% 
    }% 
} 
(\sec{Hello}) 
(\sec{Hello}{Hi}) 
\end{document} 

Đối số { m g } định nghĩa các đối số của \sec; m có nghĩa là "đối số bắt buộc" và g là "đối số kết nối tùy chọn". \IfNoValue(T)(F) sau đó có thể được sử dụng để kiểm tra xem đối số thứ hai có thực sự hiện diện hay không. Xem tài liệu cho các loại đối số tùy chọn khác được cho phép.

+4

Sẽ! Nó không hoạt động. Đầu ra: '(Xin chào và) (Xin chào và chào)' –

+0

Cảm ơn bạn đã phản hồi, Alexey. Tôi nghi ngờ bạn đang sử dụng phiên bản xparse cũ hơn; đã có rất nhiều công việc được thực hiện trên nó gần đây. TeX Live 2009 vừa được phát hành :) –

12

Tất cả bạn cần là như sau:

\makeatletter 
\def\sec#1{\def\tempa{#1}\futurelet\next\[email protected]}% Save first argument 
\def\[email protected]{\ifx\next\bgroup\expandafter\[email protected]\else\expandafter\[email protected]\fi}%Check brace 
\def\[email protected]#1{\section*{\tempa\ and #1}}%Two args 
\def\[email protected]{\section*{\tempa}}%Single args 
\makeatother 

\sec{Hello} 
%Output: Hello 
\sec{Hello}{Hi} 
%Output: Hello and Hi 
+0

Tôi nghĩ TeX hiểu là thông số thích hợp của 'hộp' đầu tiên sau khi lệnh. 'chiếc hộp' này được viết bằng dấu ngoặc nhọn hoặc đó là một biểu tượng. I E. 'x^2 + 1' hoặc' x^{2 + 1} ' Vì vậy, tôi có câu hỏi, lệnh kiểm tra lệnh của bạn có hiện diện của niềng răng không? Có thể tạo lệnh LaTeX '\ sec' sản xuất: " A, b, c và d "cho lệnh' \ sec {A} [b, c, d] ', " A và b "cho' \ sec {A} [b] và "A" cho '\ sec {A}'? – Crowley

+0

Bạn có hai câu hỏi. 1) Có, kiểm tra lệnh của tôi hiện diện của niềng răng. 2) Có, có thể tạo macro cho '\ sec {A} [b, c, d]' hoặc '\ giây {A} [b]' hoặc '\ giây {A}'. –

-1

Đây là nỗ lực của tôi, nó không làm theo thông số kỹ thuật chính xác của bạn mặc dù. Không được kiểm tra đầy đủ, vì vậy hãy thận trọng.

\newcount\seccount 

\def\sec{% 
    \seccount0% 
    \let\go\secnext\go 
} 

\def\secnext#1{% 
    \def\last{#1}% 
    \futurelet\next\secparse 
} 

\def\secparse{% 
    \ifx\next\bgroup 
     \let\go\secparseii 
    \else 
     \let\go\seclast 
    \fi 
    \go 
} 

\def\secparseii#1{% 
    \ifnum\seccount>0, \fi 
    \advance\seccount1\relax 
    \last 
    \def\last{#1}% 
    \futurelet\next\secparse 
} 

\def\seclast{\ifnum\seccount>0{} and \fi\last}% 

\sec{a}{b}{c}{d}{e} 
% outputs "a, b, c, d and e" 

\sec{a} 
% outputs "a" 

\sec{a}{b} 
% outputs "a and b" 
17

Tất cả các chương trình trên đều khó có thể tạo chức năng đẹp, linh hoạt (hoặc bị quá tải) trong LaTeX !!! (Mã TeX trông giống như Hy Lạp với tôi)

tốt, chỉ để thêm phát triển gần đây (mặc dù không phải là linh hoạt) của tôi, đây là những gì tôi đã sử dụng gần đây trong luận án doc tôi, với

\usepackage{ifthen} % provides conditonals... 

Bắt đầu lệnh, với lệnh "tùy chọn" được đặt trống theo mặc định:

\newcommand {\figHoriz} [4] [] { 

Sau đó, macro đặt biến tạm thời, \ temp {}, khác nhau tùy thuộc vào tham số tùy chọn có trống hay không. Điều này có thể được mở rộng cho bất kỳ đối số nào được thông qua.

\ifthenelse { \equal {#1} {} } %if short caption not specified, use long caption (no slant) 
    { \def\temp {\caption[#4]{\textsl{#4}}} } % if #1 == blank 
    { \def\temp {\caption[#1]{\textsl{#4}}} } % else (not blank) 

Sau đó, tôi chạy macro bằng biến \ temp {} cho hai trường hợp. (Ở đây nó chỉ đặt chú thích ngắn bằng chú thích dài nếu nó không được người dùng chỉ định).

\begin{figure}[!] 
    \begin{center} 
     \includegraphics[width=350 pt]{#3} 
     \temp %see above for caption etc. 
     \label{#2} 
    \end{center} 
\end{figure} 
} 

Trong trường hợp này, tôi chỉ kiểm tra một đối số "tùy chọn" mà \ newcommand {} cung cấp. Nếu bạn đã thiết lập nó cho, nói rằng, 3 "tùy chọn" args, bạn vẫn phải gửi 3 args trống ... ví dụ.

\MyCommand {first arg} {} {} {} 

mà là khá ngớ ngẩn, tôi biết, nhưng đó là về như xa như tôi sẽ đi với LaTeX - nó chỉ là không phải là sensical một lần tôi bắt đầu nhìn vào mã TeX ... Tôi làm như ông Phương pháp xparse của Robertson, có lẽ tôi sẽ thử nó ...

+0

Tôi thích phương pháp này. Có nhiều "lập trình giống" và do đó dễ đọc hơn. Làm tốt lắm! –

1

Tôi có một vấn đề tương tự, khi tôi muốn tạo lệnh, \dx, viết tắt \;\mathrm{d}x (tức là đặt thêm một khoảng trống trước sự khác biệt của tích phân và có "d" thẳng đứng là tốt). Nhưng sau đó tôi cũng muốn làm cho nó đủ linh hoạt để bao gồm biến tích hợp như một đối số tùy chọn. Tôi đặt đoạn mã sau vào phần mở đầu.

\usepackage{ifthen} 

\newcommand{\dx}[1][]{% 
    \ifthenelse{ \equal{#1}{} } 
     {\ensuremath{\;\mathrm{d}x}} 
     {\ensuremath{\;\mathrm{d}#1}} 
} 

Sau đó

\begin{document} 
    $$\int x\dx$$ 
    $$\int t\dx[t]$$ 
\end{document} 

cho \dx with optional argument

Các vấn đề liên quan