% \iffalse meta-comment % %% (C) 2008 Paul Ebermann %% %% Package exp-testopt - expandible testopt-Variante. %% %% Die Datei exp-testopt.dtx sowie die dazugehörige %% exp-testopt.ins sowie die damit generierte %% exp-testopt.sty stehen unter der %% "LaTeX Project Public License" (LPPL, zu finden %% unter http://www.latex-project.org/lppl/, sowie %% auch in den meisten TeX-Distributionen in %% texmf/docs/latex/base/lppl*.txt), Version 1.3b oder %% später (nach Wahl des Verwenders). %% %% Der 'maintenance-status' ist (zur Zeit) 'author-maintained'. %% %% Das heißt u.a., die Dateien dürfen frei vertrieben werden, %% bei Änderungen (durch andere Personen als Paul Ebermann) %% ist aber der Name der Datei zu ändern. % % \fi % % \iffalse % --------------------------------------------- %\NeedsTeXFormat{LaTeX2e}[2005/12/01]% % ----------------------------________________----------------- %\ProvidesPackage{exp-testopt}[2009/03/06 v0.3 (PE)] % ----------------------------________________----------------- % \fi % % \iffalse %<*driver> \PassOptionsToClass{draft}{scrartcl} \documentclass{scrartcl} % % Esperantajn tekstojn oni prefere entajpu per unikodaj literoj. \usepackage[utf8x]{inputenc} \usepackage[esperanto]{babel} \addto{\extrasesperanto}{% \renewcommand*{\generalname}{\^Generale}% \GlossaryPrologue{% \section{\^San\^goj}% }% \GlossaryMin=3\baselineskip \IndexPrologue{% \section{Indekso} Kurzivaj nombroj indikas la lokojn, kie la indeks-ero estas priskribita, substrekitaj nombroj indikas la lokon de la difino, la aliaj estas uzoj. } \IndexMin=5\baselineskip } \usepackage[svgnames]{xcolor} \usepackage{exp-testopt} \usepackage[bookmarks=false]{hyperref} \usepackage[countalllines, withmarginpar]{gmdoc} \usepackage[inline, visible]{gmdoc-enhance} \let\pack\textrm% \renewcommand*{\EOFMark}{} \newenvironment{kodo-citajho}[1][english]{% \par \addtolength{\CodeIndent}{1cm} \addtolength{\TextIndent}{1cm} \addtolength{\rightskip}{1cm} \renewcommand*{\printlinenumber}{% \leavevmode \llap{\rlap{% \hspace*{1cm}% \LineNumFont$\phantom{999}$\llap{% $(\thecodelinenum)$}}% \hskip\leftskip% % }% } %! \addmargin{5em} \csname otherlanguage*\endcsname{#1}% \slshape% \expandafter\addtomacro\csname ttverbatim@hook\endcsname{\slshape}% \MakeShortVerb\|\DeleteShortVerb\'% }{ \MakeShortVerb\'\DeleteShortVerb\|% \csname endotherlanguage*\endcsname% \endaddmargin } \addtomacro\LineNumFont{\normalcolor} \RecordChanges \begin{document} % ^ ne taŭgas kiel specialsigno, ĉar ni % bezonas ĝin por ^^B, ^^M ktp. \catcode`\^=7% \MakeShortVerb\' \DocInput{exp-testopt.dtx} \end{document} % % \fi % % \chschange{v0.1}{2009/03/03}{37} % \chschange{v0.2}{2009/03/03}{90} % \chschange{v0.3}{2009/03/06}{139} % \changes{v0.1}{2009/03/03}{Unua versio} % \changes{v0.2}{2009/03/03}{Preta por publikigo, mi kredas.} % \changes{v0.3}{2009/03/06}{Post pluraj cimkorektoj nun vere\ % preta \dots} % % \GetFileInfo{exp-testopt.sty} % % % \title{La \pack{exp-testopt}-Pakaĵo -- ekspandebla varianto de \ % \cs{@testopt}. \thanks{ Tiu dokumento rilatas al \ % \pack{exp-testopt}~\fileversion, de~\filedate.}} % \author{Paul Ebermann\thanks{\texttt{Paul-Ebermann@gmx.de}}} % % \maketitle % % % \begin{abstract} % Ekspandebla varianto de '\@testopt' el la \LaTeX-kerno, kaj iom % pli ĝenerala (ankaŭ ekspandebla) '\@expandable@ifopt', por rekoni % ekziston de opciaj argumentoj (sen tuj doni defaŭlton). % Ankaŭ '\newcommand'-varianto, kiu uzas tion. % \end{abstract} % % % \tableofcontents % % \section{Uzanta dokumentaĵo} % % Tiu ĉi pakaĵo enhavas unu makroon rekte uzebla de uzantoj, kvankam % ankaŭ ĝin verŝajne pli ofte uzos pakaĵo-kreantoj. % Krome ĝi enhavas du utilajn makroojn por pakaĵ-kreantoj % (ne por uzantoj). % % \subsection{Makrooj} % % \TextUsage{\expnewcommand}'*'\arg{nomo}\arg[paramnum]\ % \arg[defaŭlto]\arg{kodo} % -- % funkcias simile kiel '\newcommand': Kreas komandon kun \meta{num} parametroj % (ĝis 9), kaj se \meta{defaŭlto} estas donita, la unua parametro estos % opcia kun \meta{defaŭlto} kiel defaŭlta valoro. % Diferenco al '\newcommand' nur ekzistas, se \meta{defaŭlto} estas % donita -- tiam je voko de la makroo ni uzas ekspandeblan komparon % por ekscii, ĉu unua parametro estas donita. (Tio havas la avantaĝon % esti ekspandebla, sed la limigojn menciitajn sube.) % % % \TextUsage{\@expandable@testopt}\marg{ordono}\marg{defaŭlto} % -- % vokas \meta{ordono}n kun '[]'-parametro -- se neniu plia estas donata de % la uzanto, ni uzas \meta{defaŭlto} anstataŭe. % Pli detale: kontrolas, ĉu la sekva signo % estas '['. Se jes, iĝas \meta{ordono}, alikaze iĝas % \meta{ordono}\arg[defaŭlto]. % (Tio funkcias simile kiel '\@testopt' el la \LaTeX-kerno.) % % \TextUsage{\@expandable@ifopt}\marg{jes}\marg{ne} -- % kontrolas, ĉu la sekva signo estas '['. Se jes, vokas \meta{jes}, alikaze % \meta{ne}. % % \subsection{Limigoj} % % Fakte tiuj makrooj ne kontrolas la sekvan simbolon (kio igus ĝin % ne-ekspandebla pro uzo de '\futurelet', kiel '\@testopt'), % sed la sekvan makroo-argumenton ('#3', fakte). Krome estas malfacile % kompari ion, se oni ne povas difini/ŝanĝi ion. % % Tio havas la sekvajn konsekvencojn: % \begin{itemize} % \item % Ne eblas distingi '[' de '{[}' per nia algoritmo -- ambaŭ estas traktataj % kiel \meta{Jes}. % \item % La sekva argumento estu de la amika speco: Ĝi estu (se ĝi ne estas % simple '[') ĉeno el maksimume unu \emph{danĝera} simbolo (kontrolsekvenco % aŭ el danĝera kategorio) kaj poste simpla teksto (el kategorioj 10, 11, % 12). % % Se ĝi konsistas el nur unu simbolo, tio ne estas problemo. Se ĝi % konsistas el simpla teksto, tio ankaŭ ne estas problemo. % % En aliaj kazoj povas aperi strangaj erarmesaĝoj. % \item Apero de pluraj spaco-simboloj antaŭ la '[' povas konfuzigi la % programon, tiam ankaŭ aperos strangaj erarmesaĝoj. % \end{itemize} % % Do, antaŭ la uzo de tiuj makrooj bone pripensu, ĉu la limigoj vin % ĝenas. % % (Krome eblas trompi nian algoritmon per kreado de pliaj makrooj en la % nomspaco de '\exp-testopt@@'\meta{io}'@'. Ne faru tion, krom se vi certas % pri la konsekvencoj.) % % % \section{Ekzemplo} % % Jen ekzemplo de la uzo por krei komandon '\beispiel' kun opcia % argumento. % % \changes{v0.3}{2009/03/05}{Testo ankaŭ por \cs{expnewcommand}} % %<*test> \makeatletter \errorcontextlines = 20 \def\beispiel{% \@expandable@testopt\beispielImpl{Default}% } \def\beispielImpl[#1]{% \fbox{#1}% } \makeatother \expnewcommand*{\ekzemplo}[1][Defa\u ulto]{% \textbf{(#1)}% } \expnewcommand*{\ekzemploDu}[2][defa\u ulto]{% \ensuremath{\frac{\mbox{#1}}{\mbox{#2}}}% } \beispiel{egal} \beispiel[bla] \beispiel$ e=m c^2$ \beispiel[$ e=m c^2$] \ekzemplo\ekzemplo[Bla] \expandafter\ekzemplo\space[bla] \expandafter\expandafter\expandafter\ekzemplo\expandafter\space\space[dua bla] \ekzemplo [nova linio] \ekzemplo [du novaj linioj] \ekzemplo[blub] \ekzemploDu{testo} \ekzemploDu[bla]{testo} % % % Kontraŭe al kreado de tia komando per '\newcommand', la komando estas % tute ekspandebla (nu, krom la enhavo de '\beispielImpl'), anstataŭ % robustigita per malfruigita ekspandado. Tiel ekzemple eblas uzi valorojn % de variabloj kun ilia aktuala valoro, ankaŭ se la komando mem estos poste % skribota en dosieron. (Hmm, iom komplika, ĉu?) % % La supra kodo donas jenan rezulton: % % \begin{center}\StraightEOL % \fbox{\ % \begin{minipage}{0.8\linewidth} \ % \normalInput{\jobname.test} \ % \end{minipage}\ % } % \end{center} % % \StopEventually{\PrintChanges\PrintIndex} % % \section{Implementado} % % %<*package> % % \subsection{Ĉefaj makrooj} % % Niaj du ĉefaj makrooj nun aspektas tiom similaj, ke ni povas implementi % 'testopt' per 'ifopt'. % \newcommand*{\@expandable@testopt}[2]{% \@expandable@ifopt{#1}{#1[#2]}% } % '\@expandable@ifopt' nun faras la laboron. % \newcommand{\@expandable@ifopt}[3]{% \expandafter\ifx% '\ifx' komparas la difinojn de du makrooj, nome \dots \csname exp-testopt@@\string#3@\endcsname% \dots makronomo kreita el la % tria argumento (= la signo poste). \exp@testopt@opt@% \dots kaj tiu antaŭdifinita makroo. \afterfi{#1#3}% En la jes-kazo, vokas la unuan argumenton % (kun la tria), \dots \else% \dots en la ne-kazo la duan. % % Sed tiam ni ankoraŭ devos eltrovi, ĉu la tria konsistis el unu aŭ pluraj % tokenoj, por meti '{...}' ĉirkaŭ ĝin en la dua kazo. (Se ĝi nur estas % unu tokeno, meti '{...}' povas esti malhelpa, se ĝi fakte ne estas argumento % al '#2', sed ekzemple io kiel '$', aŭ sekva makroo.) \@expandable@ifOneToken#3\@expandable@ifOneToken% Tiu % ĉi makroo provas eltrovi tion. {\afterfi{#2#3}}% {\afterfi{#2{#3}}}% \fi% }% % La ideo por tia ekspandebla kontrolo de la sekva »signo« estas, ke ni % kreas el la »signo« makroonomon, kaj komparas la signifon de ĝi kun % signifo de konata makroo. % % \subsection{Komparendaj makrooj} % % Por tio ni kreas iujn nomojn, kiuj estas supozeble ne uzata de iu alia, % kun signifoj, kiuj ankaŭ supozeble ne erare aperas. % \def\exp@testopt@opt@{<<<[>>>}% tio estas la nomo, kies valoron ni % komparas kun aliaj kandidatoj. \@namedef{exp-testopt@@\string[@}{<<<[>>>}% Tio -- '\exp-testopt@@[@' -- estas % la makroo, kiu estos trovota en la \emph{jes}-kazo. % Ni ankoraŭ devas eltrovi, ĉu la argumento estas % nur unu tokeno aŭ pluraj, por povi meti '{...}' % en la dua kazo. Ni uzas similan trukon por tio. \long\def\@expandable@ifOneToken#1#2\@expandable@ifOneToken#3#4{% \expandafter\ifx% \csname exp-testopt@@\string#2@\endcsname% \exp@testopt@empty@% \afterfi{#3}% \else \afterfi{#4}% \fi } \def\exp@testopt@empty@{<<<>>>}% tio % estas la nomo, kies valoron ni komparas kun aliaj kandidatoj. \@namedef{exp-testopt@@@}{<<<>>>}% Tio -- % '\exp-testopt@@@' -- estas la makroo, kiu estos trovota en la kazo, % ke '#2' estas malplena. % \subsection{Komando-difinoj} % % \changes{v0.2}{2009/03/03}{Aldono de \cs{expnewcommand}.} % % Ni volas krei varianton de '\newcommand', kiu uzas % nian ekspandeblan metodon por opciaj argumentoj, anstataŭ % la robustan. % % Jen la originalo el latex.ltx (ltdefns.dtx, por esti % preciza, CTAN-versio de 2006-05-21). % \begin{kodo-citajho} %<*latex2e> % Handle the second optional argument. \long\def\@xargdef#1[#2][#3]#4{% \@ifdefinable#1{% % Define the actual command to be:\\ % |\def\foo{\@protected@testopt\foo\\foo{default}}|\\ % where |\\foo| is a csname generated from applying |\csname| and % |\string| to |\foo|, ie the actual name contains a backslash and % therefore can't clash easily with exisiting command names. % ``Default'' is the contents of the second optional argument of % |(re)newcommand|. {\color{red} \expandafter\def\expandafter#1\expandafter{% \expandafter \@protected@testopt \expandafter #1% \csname\string#1\endcsname {#3}}% % } Now we define the internal macro ie |\\foo| which is supposed to % pick up all arguments (optional and mandatory). \expandafter\@yargdef \csname\string#1\endcsname \tw@ {#2}% {#4}}} % % \end{kodo-citajho} % % Kaj ni nun devas ŝanĝi la markitan parton % por anstataŭe uzi nian metodon. Tio signifas, ke \meta{nomo} nun % estas difinita kiel % {\color{Green}'\@expandable@testopt\'\meta{nomo}\marg{defaŭlto}}, % anstataŭ % {\color{red}^^A % '\@protected@testopt'\meta{nomo}'\'\meta{nomo}\marg{defaŭlto}}. % % (Kompreneble ni ne redifinas '\@xargdef', sed difinas nian % propran varianton, por uzi anstataŭe -- ni ja ne volas ŝanĝi % la bazan funkcion de '\newcommand'.) \long\def\@exp@xargdef#1[#2][#3]#4{% \@ifdefinable#1{% { \color{Green} \expandafter\def\expandafter#1\expandafter{% \expandafter% \@expandable@testopt% \csname\string#1\endcsname% {#3}}% } \expandafter\@yargdef% \csname\string#1\endcsname% \tw@% {#2}% {#4}% }% } % Kaj nun kelkaj paralelaj difinoj al '\newcommand', '\new@command' kaj % '\@newcommand'. % % \changes{v0.3}{2009/03/03}{Cim-korekto: \cs{exp@new@command} renomita al \cs{expnew@command}} % % '\expnewcommand' estas la ĉefa komando. \def\expnewcommand{% \@star@or@long\expnew@command% } \def\expnew@command#1{% \@testopt{\exp@newcommand#1}0% } \def\exp@newcommand#1[#2]{% \@ifnextchar [{\@exp@xargdef#1[#2]}% Ĉi % tie ni vokas nian varianton anstataŭ '\@xargdef'. % ^^A ] {\@argdef#1[#2]}% Tiu estas la originalo. } % % \subsection{Helpaj makrooj} % % '\afterfi'\arg{kodo} -- saltas ĝis post la sekva '\fi', kaj % ekzekutas \meta{kodo}n tie. % % Kopiita el \pk{gmutils}. % \@ifundefined{afterfi}{% \def\afterfi#1#2\fi{% \fi#1% }% }{}% % % % % Jam fino :-) \endinput % % (Jes, vere fino.) % % \Finale %\endinput %%% Folgendes ist nur für meinen Editor. %%% %%% Local Variables: %%% mode: docTeX %%% TeX-master: t %%% End: