%% %% \iffalse ^^A we skip the debug setting \IfFileExists{\string~/bin/gen_and_xela}{\errorcontextlines=1000 }{} %% \fi %% ^^A $Id: TheUltimateMaster.gmd,v 0.352 2011/10/12 15:19:42 natror Exp natror $ %% This is file “gmcommand.sty” generated with the DocStrip utility. %% %% %% The original source files were: %% %% gmutils/gmutils.gmd (with options: `command') %% %% %% Copyright © %% by Grzegorz ‘Natror’ Murzynowski %% natror (at) gmail (dot) com %% %% This program is subject to the LaTeX Project Public License. %% See http://www.ctan.org/tex-archive/help/Catalogue/licenses.lppl.html %% for the details of that license. %% %% LPPL status: "author-maintained". %% %% %% %% For documentation please refer to the file(s) %% gmutils.{gmd,pdf}. %% %% \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{gmcommand} [2011/10/12 v0.996 definition of \string \DeclareCommand \string &al. based on the ancient xparse (pre-expl3) (GM)] %% %% %% ^^A\typeout{\unexpanded{#4}}%% \RequirePackage{gmbase} % we require the low-level macros. \unless\ifcsname ifgmu@quiet\endcsname \Name\newif {ifgmu@quiet}% % it has to be at least (at highest) in % \CH{2010/09/06 v0.993 moved here from % % \pk{gmutils.sty} (a bug fix)} \fi \unless\ifdefined\@temptokenb \newtoks\@temptokenb \fi \newif\if@dc@alllong@ % for an option of all arguments long (it's % stronger than |GroteLang| defined later (the % latter is |\let| it). \newif\if@dc@quiet@ % for suppressing the message of using of \newif\ifDCMessages % a~global switch to suppress the message about \newtoks\@dc@arguments % the register for storing parsed % |\\command {#1}›…{⁄}|. \newcount\c@dc@catchernum \newcount\c@dc@argnum \newif\if@dc@ignore@ \newif\if@dc@GroteNegere@ % for “gross” ignoring \newif\if@dc@GroteLang@ % for “gross” longness \newif\if@dc@long@ \newif\if@dc@BareSpace@ \def\@dc@long@letter{% \if@dc@long@ P\fi } \newif\if@dc@xadefault \def\@nx@xa{\@nx\@xa} \def\@xa@nx{\@xa\@nx} \def\@xa@xa{\@xa\@xa} \newif\if@dc@xadefault@i@ \newif\if@dc@xadefault@ii@ \newif\if@dc@xaeacher@ \def\@dc@falsify@xadefaults{% \@dc@xadefaultfalse \@dc@xadefault@i@false \@dc@xadefault@ii@false } \lpdef\DeclareCommand#1#2#3{% ^^B It's the draft version just % ^^B~to declare the true one, which is defined in line % \ref{DC:final}. % % \begin{enumargs} % \item command to be defined, % \item arguments specification, % \item definition body. % \end{enumargs} % \chgs[\DeclareCommand]{2008/12/05 v0.98 added the \env{S}/\env{T} % spec parsing, the % \env{s} spec parsing rewritten to be a~shorthand for % \env{S\{*\}}, unused code removed} % \chgs{2010/04/15 v0.993 implemented the \cmd\SameAs feature} % % % \@dc@alllong@true \@dc@ResetParseAuxilia % \@dc@ParseNextSpecifier #2% \@dc@buckstopshere% it's the sentinel of parsing. Doesn't have to be % defined since the test performs a strings comparison. \protected\edef#1{% \@nx\@dc@ {\the\toks@}% \@xanxcs{\@dc@InnerName{#1}}% \@nx #1% }% \edef\gmu@DeclareCommand@resa{% \long\def\@xanxcs{\@dc@InnerName{#1}}% \@xau\@dc@innerhashes{% \unexpanded{#3}}% }% of resa \gmu@DeclareCommand@resa }% of the ‘draft’ |\DeclareCommand|. \long\def\@dc@ #1% the argument catchers in a~pair of braces (their arguments % may contain \incmd\par\ so the macro is long). #2% |\\thecommand\| #3% |\thecommand| {% \ifx\protect\@typeset@protect \@xa\@firstofone \else \protect#3\@xa\@gobble \fi {\@dc@arguments{#2}#1\the\@dc@arguments}% } \newtoks \@dc@ParsedSpecs \def\@dc@ResetParseAuxilia{% % \@dc@ParsedSpecs={}% % \c@dc@catchernum\z@ % the count of catchers \c@dc@argnum\z@ % the count of arguments (inner arity) (it may be % smaller than the above if we ignore some arguments) % \toks@{}% in this register we will store the created sequence of % argument catchers. % % And for the |M⁄m| specifiers: \@dc@Mmode@false % \emptify\@dc@innerhashes % in this macro we will store the sequence of % \inverb|#1#2…|. % \@dc@GroteNegere@false \let\if@dc@GroteLang@\if@dc@alllong@ } \newif \if@dc@Mmode@ \def\@dc@Ms@num {\z@}% \def\@dc@Ms@init{% \@dc@Mmode@true \def\@dc@Ms@num {\z@}% \edef\@dc@Ms@initial@listate{% \@dc@Ms@listate }% of edef } \def\@dc@Ms@listate{% \boolstobin{{@dc@long@}{@dc@ignore@}}% } \def\@dc@Ms@shipout {% \gmu@if {num} {\@dc@Ms@num>\z@}% {\@xa\dc@addtoParsed@\@xa{\@dc@Ms@num}% \def\@dc@Ms@num{\z@}% \@dc@Mmode@false }% {}% } \def\@dc@ResetStepAuxilia {% % We set the local ignorance switch to its “gross” value \let\if@dc@ignore@ =\if@dc@GroteNegere@ \let\if@dc@long@ = \if@dc@GroteLang@ % and reset the expandaftering switches \@dc@falsify@xadefaults \@dc@BareSpace@false } \def\@dc@argtypes{% =\gobblespace \loop \lostwax \SameAs \Scope AaBbCcDdGgKkMmOo% QqSs*TtUuWw% \drs } \def\@dc@drses{\drs} % decimal respecting space \@ifXeTeX {\addtomacro\@dc@argtypes{ďĎŤťǓǔÔô}% \addtomacro\@dc@drses{ďĎ}% } {} \def\@dc@ParseSpecifier #1{% The main inner macro parsing argument \gmu@CASE {stribs}{{#1}\@dc@buckstopshere}% {% \@dc@Ms@shipout \edef\@dc@innerhashes {% \gmu@hashes 1{\numexpr\c@dc@argnum +\@ne}% }% }% \gmu@CASE {stribs}{{#1}>}% {% \grab@prefix }% \@XA{% \gmu@CASEsbnone{#1}}\@xa{% \@dc@argtypes }% {\IgnInfo{gmcommand}{while parsing arg specifiers}{#1}% \@dc@ParseNextSpecifier }% \gmu@CASE {stribs}{{#1}\SameAs}% {\@dc@SameAs}% \gmu@ifsbnone {#1}{Mm}% {\@dc@Ms@shipout }% {}% \gmu@if {@dc@Mmode@}{}% {}% {% \gmu@ifsbany{#1}{=\gobblespace}{\@dc@ignore@true}{}% \gmu@ifsw {@dc@BareSpace@}% {\@dc@addtoparsed@BareSpace } {}% % % \gmu@ifsw {@dc@long@}% {\@dc@addtospecs@bare{>P}} {}% % \gmu@ifsw {@dc@ignore@}% {\@dc@addtoparsed@Ignore }% {}% % \@dc@addtospecs@bare {#1}% % \@xa\addtotoks\@xa\toks@\@xa{% \csname ArgumentCatcher@\@dc@long@letter \strip@bslash{#1}% \endcsname }% of toks' text. \advance\c@dc@catchernum\@ne }% of if not |M|-mode \gmu@notif {@dc@ignore@}{}% {\@dc@addinnerhash }% \label{@dc@addinnerhash} {}% (empty “not-else” branch of ignoring) \gmu@CASEsbany {#1}{Mm}% {\@dc@process@ms}% \gmu@CASEsbany {#1}{Kk}% {\@dc@define@K}% \gmu@CASEsbany {#1}{\gobblespace}% {\@dc@ParseNextSpecifier}% \gmu@CASEsbany{#1}{=\Scope AaBbCcDdOoSs*}% {\grab@optparam{#1}}% \@XA{\gmu@CASEsbany{#1}}\@xa{\@dc@drses}% {\grab@optparam{#1}}% \gmu@CASEsbany{#1}{UuǓǔWw\lostwax}% {\@dc@grab@Loop #1}% putting the specifier's letter as |#1| for the % grabber suppresses adding it to the parsed specifiers' list. \gmu@lastCASE {% \grab@twoparams{#1}}% \gmu@ESAC % }% of |\@dc@ParseSpecifier| \def\@dc@addtoparsed@Ignore{% \addtotoks\toks@{\@dc@ignorearg}% \@dc@addtospecs@bare{>i}% } \def\@dc@addinnerhash{% \advance\c@dc@argnum\@ne } \def\@dc@addtoparsed@BareSpace{% \addtotoks\toks@{\@dc@BareSpaceArg }% \@dc@addtospecs@bare{>\BareSpace }% } \def\@dc@process@ms{% \gmu@if {@dc@Mmode@}{}% {\gmu@if {num}{\@dc@Ms@initial@listate=\@dc@Ms@listate}% {\@dc@process@ms@grabnum }% of if the state has'nt been changed {\@dc@Ms@shipout % Remember however that we've increased number of arguments so now we % set it back: \advance\c@dc@argnum\m@ne \@dc@ParseSpecifier m% }% of if the state has been changed }% of if |M|-mode {\@dc@Ms@init \@dc@process@ms@grabnum }% of not if |M|-mode. }% of \@dc@process@ms \def \@dc@process@ms@grabnum {% \@ifnextanyIS {\bgroup \@ne \tw@ \thr@@ 123456789}% {% \@dc@process@ms@fin}% {% \@dc@process@ms@fin \@ne}% } \def \@dc@process@ms@fin #1{% \edef\@dc@processms@hash {\the\numexpr#1}% \edef\@dc@processms@left {\the\numexpr 9-\c@dc@argnum+\@ne}% % \gmu@AND {% {num} {\@dc@processms@hash >\z@} {num} {\@dc@processms@hash <\numexpr \@dc@processms@left+1 \relax }% }% {\stepnummacro \@dc@Ms@num \@dc@processms@hash \edef\@dc@hashgoal {% \the\numexpr\c@dc@argnum +% \@dc@processms@hash-1}% minus 1 because one \@whilenum \c@dc@argnum<\@dc@hashgoal \do{% \@dc@addinnerhash }% % \@dc@ParseNextSpecifier }% of if all conds.\ satisfied {% some of the conds.\ not satisfied \PackageError{gmcommand}{% The argument to the M or m specifier, if any, has to be ^^J% a number between 1 and \@dc@processms@left ^^J% (there is/are \the\c@dc@argnum\space arg(s) declared already).^^J% I ignore this m/M.}% {}% \gmu@passbraced \@dc@ParseNextSpecifier {#1}% }% }% of |\@dc@process@ms| \def\@dc@ParseNextSpecifier{% \@dc@ResetStepAuxilia \@dc@ParseSpecifier } \lpdef\@dc@AddAndParse#1{% \dc@addtoParsed@{#1}% \@dc@falsify@xadefaults \@dc@ParseNextSpecifier } \def\grab@optparam #1{% arg specifier \@ifnextchar\bgroup{\@dc@AddAndParse}% {% \edef\@dc@tempa{% \gmu@if {csname}% {@dc@optparam@deft@\strip@bslash{#1}\endcsname}% {\@xaucs {@dc@optparam@deft@\strip@bslash{#1}}}% {\@nx \NoValue}% }% \@xa\@dc@AddAndParse\@xa{\@dc@tempa}% }% } \long\def\@dc@DeclareDefault #1#2{% \uppercase{% \Name\edefU{\strip@bslash{\@dc@optparam@deft@}\strip@bslash{#1}}{#2}}% % \lowercase{% \Name\edefU{@dc@optparam@deft@\strip@bslash{#1}}{#2}}% } \@dc@DeclareDefault D{0} \@dc@DeclareDefault d{0} \@ifXeTeX {% \@dc@DeclareDefault Ď{0}% } {} \@xa\@dc@DeclareDefault \@xa\Scope\@xa{\all@stars} \@dc@DeclareDefault = {\@tempcnta} \@dc@DeclareDefault Q {\NoValue} \@ifXeTeX {% \@dc@DeclareDefault Ô{\NoValue}% } {} \@dc@DeclareDefault U {\NoValue} \long\def\@dc@maybe@expandafter #1{% \gmu@if {@dc@xadefault}{}% {\gmu@ifutokens{#1}{\NoValue}% {\@secondoftwo}{\@firstoftwo}% }% if we are to expandafter |#1|. {\@secondoftwo}% if we don't expandafter |#1| } \long\def\dc@addtotoks@ #1{% \@dc@maybe@expandafter {#1}% % {\toks@\@xa\@xa\@xa{\@xa\the\@xa\toks@\@xa{#1}}}% {\toks@\@xa{\the\toks@{#1}}}% } \long\def\@dc@addtospecs #1{% \@dc@maybe@expandafter {#1}% {\@xa \addtotoks \@xa\@dc@ParsedSpecs\@xa{\@xa{#1}}% }% {\addtotoks\@dc@ParsedSpecs{{#1}}}% } \long\def\dc@addtoParsed@ #1{% \dc@addtotoks@{#1}% \@dc@addtospecs{#1}% } \long\def\@dc@addtospecs@bare #1{% \addtotoks\@dc@ParsedSpecs{#1}% } \long\def\@dc@addtotoks@bare #1{% \addtotoks\toks@ {#1}% } \long\def\@dc@addtoParsed@bare #1{% \@dc@addtotoks@bare {#1}% \@dc@addtospecs@bare {#1}% } \long\def\grab@twoparams #1% the specifier #2% first parameter, which is mandatory {% default default (when default is absent) \if@dc@xadefault@i@\@dc@xadefaulttrue\fi \dc@addtoParsed@{#2}% \if@dc@xadefault@ii@ \@dc@falsify@xadefaults\@dc@xadefaulttrue \fi \grab@optparam{#1}% } \long\def\@dc@addargum#1{% \addtotoks\@dc@arguments{#1}% \@iwruif {@@@@@@ @dc@arguments: »\the\@dc@arguments«}% } \Store@Macro\@dc@addargum \pdef\@dc@ignorearg{% \long\def\@dc@addargum##1{% \Restore@Macro\@dc@addargum}% } \StoreMacro@nocat\gmu@passbraced \pdef\@dc@BareSpaceArg{% \let \gmu@passbraced \gmu@passbracedNotSp \def\@dc@addargum {% \Restore@Macro\@dc@addargum \Restore@Macro\gmu@passbraced \@dc@addargum }% } \def\grab@prefix@CASE{% just a shorthand \@xa\gmu@CASEsbany\gmu@forarg } \long\def\grab@prefix #1{% %% \CH{2010/07/26 v0.993 made for-eaching to make it behave as %% expected, i.e.\ that latter settings prævalent over the former} % \gmu@foreach#1\gmu@foreach@delim {% % \grab@prefix@CASE {\long!lL\par Pp}% {\@dc@long@true}% % \grab@prefix@CASE {Ii}% {\@dc@ignore@true}% % \grab@prefix@CASE {\@xa\expandafter}% {\@dc@xadefaulttrue}% % \grab@prefix@CASE {\@xa \@xa@nx \@xa@xa \expandafter \@xanx \xanx \xaxa}% {\@dc@xadefault@i@true}% % \grab@prefix@CASE {\@xa \@nx@xa \@xa@xa \expandafter \@nxxa \nxxa}% {\@dc@xadefault@ii@true}% % \grab@prefix@CASE {\@xaeacher \xaeacher \xaEacher \xaE }% {\@dc@xadefault@ii@true}% % \grab@prefix@CASE {\GroteNegere \GrossIgnore \GroteN \GrossI} {\@dc@GroteNegere@true \@dc@ignore@true}% % \grab@prefix@CASE {\GroteNegereStop\GrossIgnoreStop \GroteNStop\GrossIStop} {\@dc@GroteNegere@false \@dc@ignore@false}% % \grab@prefix@CASE {\GroteLang\GrossLong\GroteL\GrossL} {\@dc@GroteLang@true \@dc@long@true}% % \grab@prefix@CASE {\GroteLangStop\GrossLangStop \GroteLStop\GrossLStop}% {% \let\if@dc@GroteLang@=\if@dc@alllong@ \let\if@dc@long@=\if@dc@alllong@ }% % \grab@prefix@CASE {\BareSpace} {\@dc@BareSpace@true} % % \gmu@EatCases {\IgnInfo{gmcommand}{while parsing arg specifiers}{#1}}% \gmu@ESAC % }% of for each \@dc@ParseSpecifier % }% of |\grab@prefix| \long\def\dc@DefParseNext#1{% % This is to allow hashes in the defaults. \edefU\@dc@parse@next{#1}% } \def\@dc@Alias #1% |\lowercase| or |\firstofone| #2% left side of the assignment #3% right side of the assignment #4% |Lower| or empty {% \gmu@if {csname}% {ArgumentCatcher@\strip@bslash #3\endcsname}% {#1{% \@xa\let\csname\strip@bslash\ArgumentCatcher@ \strip@bslash #2\@xa\endcsname}% \csname ArgumentCatcher@\strip@bslash #3\endcsname }{\PackageError{gmutils/gmcommand}{% You're trying to #4Alias the »\unexpanded{#3}« catcher^^J% but it is not defined!}{}% }% } \def\@dc@LowerAliases #1{% % To provide lowercase aliases of the catchers: \@dc@Alias \lowercase {#1}{#1}{Lower}% \@dc@Alias \lowercase {\P#1}{\P#1}{Lower}% we provide »P« as a \CS % to avoid lowercase'ing it. } \def\@dc@AliasCatcher #1% left side of the assignment #2% right side of the assignment {% \@dc@Alias \firstofone {#1}{#2}{}% } \def\@dc@AliasPLower #1% specifier to alias {\@dc@AliasCatcher {P#1}{#1}% \@dc@LowerAliases{#1}% } \long\def\ArgumentCatcher@B #1% default value #2% tail of args catchers. \@dc@arguments % delimiter {% \@ifnextcat\bgroup {\dc@DefParseNext{#2}\ArgumentCatcher@m@i }% {\@dc@addargum {{#1}}#2\@dc@arguments }% } \long\def\ArgumentCatcher@PB #1% default value #2% tail of args catchers. \@dc@arguments % delimiter {\@ifnextcat\bgroup {\dc@DefParseNext{#2}\ArgumentCatcher@Pm@i }% {\@dc@addargum {{#1}}#2\@dc@arguments }% } \@dc@LowerAliases B \long\def\ArgumentCatcher@T@ % parsing of a~single \textbf Token % continued: #1% kind of test (|strings| or |StrX| so far (2010/12/28, 7.24)) #2% the list to search |#4| on, #3% the default value, #4% the tail of args parsers, #5% the token we search in |#1| (it's an unbraced {% #1 #5{#2}% {\@dc@addargum {{#5}}#4\@dc@arguments}% {\@dc@addargum {{#3}}#4\@dc@arguments#5}% } \long\def\ArgumentCatcher@T % parsing of a~ single \textbf Token. It's #1% the list we search optional token on, #2% the default value, #3% the tail of args parser. \@dc@arguments{% \@ifnextnotgroup % \label{dc@S:bgroup} {\ArgumentCatcher@T@ \gmu@ifStrXany {#1}{#2}{#3}}% {\@dc@addargum {{#2}}#3\@dc@arguments}% if we parse an % opening or closing brace, then we are sure it's not any expected % Single. } \@dc@AliasPLower T \long\def\ArgumentCatcher@Ť #1#2#3% as in |›…@T| {% one-token catcher that respects space. \ArgumentCatcher@Loop {StrX}{\any}{#1}{\any}{}{1}{#2}{% empty eacher }{#3}% } \@dc@AliasPLower Ť \edef\ArgumentCatcher@S #1% default value {% \@nx\ArgumentCatcher@T {\@xa\@nx\all@stars}{#1}}% the |s| arg spec is \@dc@AliasPLower S \@dc@AliasCatcher * S \newif\if@debugacro@ \long\def\ArgumentCatcher@Loop %^^A >>>>>>>loop #1% kind of test (|StrX| or |str| or anything else for what #2% “sign” of match for iteration: |\any| or |\none| #3% list of tokens |\@let@token| will be matched against with |#1| #4% test for “drainers” (allowed values as for |#1|) #5% list of “drainers”: if |\@let@token| satisfies the |#3| test, #6% upper bound of number of items (may be empty or negative to turn #7% default value (if empty sequence is parsed), |\NoValue| by default. #8% an “eacher”—stuff to be put before each token/text added to the #9% the tail of args parser \@dc@arguments % delimiter {% \dc@DefParseNext{#9}% \emptify\@dc@seQuence \c@dc@Loop@bound=\numexpr(\gmu@ifempty{#6}{-1}{#6})*1\relax \gmu@if {num}{\c@dc@Loop@bound<\z@}% {\c@dc@Loop@bound=-\c@dc@Loop@bound \let\@dc@Loop@countby\z@ }% {\let\@dc@Loop@countby\m@ne}% % \gmu@ifempty{#3}% {\gmu@if {strings}{\none #2}% {\@dc@Loop@iteralltrue}% it's an additional switch for better % performance in a special case: when we wish % only count the items and iterate over anything {% \Store@Macro\ArgumentCatcher@Loop@defcheck \def\ArgumentCatcher@Loop@defcheck{% \Restore@Macro\ArgumentCatcher@Loop@defcheck \ArgumentCatcher@Loop@shipout}% }% of if |#2| str-is |\any| }% of if |#3| empty {\@dc@Loop@iterallfalse}% when |#2| nonempty, we \emph{have} to % perform matching. \rrthis % \gmu@ifempty{#5}% {\gmu@if {strings} {\none #4}% {\@dc@Loop@addallfalse\@dc@Loop@drainalltrue}% {\@dc@Loop@addalltrue\@dc@Loop@drainallfalse}% }% of if |#5| empty {\@dc@Loop@addallfalse\@dc@Loop@drainallfalse}% when |#4| nonempty, % we \emph{have} to perform matching. \rrthis % \edef\ArgumentCatcher@Loop@afterpeep{% \gmu@if {@dc@Loop@iterall}{}% {\firstoftwo}% {\unexpanded{% \@dc@Loop@test {#1}#2{#3}% if the next token StrX-is/is not on |#2|, % then… \label{h1.@let@token.h2} }% of |\unexpanded| }% of if we don't iterate over all (of preparation of iteration test) {\gmu@if {@dc@Loop@addall}{}% {\@nx \ArgumentCatcher@Loop@add}% {\gmu@if {@dc@Loop@drainall}{}% {\@nx \ArgumentCatcher@Loop@drain}% {\unexpanded{% \@dc@Loop@test {#1}#4{#5}% if the next token satisfies |#4|-direction StrX/str % match against |#5|, then we discard it, % otherwise we add it. \ArgumentCatcher@Loop@drain \ArgumentCatcher@Loop@add }% of |\unexpanded| }% of not drain all }% of if not add all }% {\gmu@if {@dc@Loop@iterall}{}% {}% {\@nx \ArgumentCatcher@Loop@shipout}% }% \unexpanded{{#7}{#8}}% }% of |\ArgumentCatcher@Loop@afterpeep| % \ArgumentCatcher@Loop@defcheck {#7}{#8}% \ArgumentCatcher@Loop@check }% of |\ArgumentCatcher@Loop| \newcount\c@dc@Loop@bound \newif\if@dc@Loop@iterall \newif\if@dc@Loop@addall \newif\if@dc@Loop@drainall \long\def\@dc@Loop@test #1% kind of test (|StrX| or |str| so far (2010/12/28, 7.51)) #2% |\any| or |\none| #3% list of tokens to match against #4% what if \OK #5% what if not \OK. {% remember we are in the argument of |\gmu@peep@next| so we are after % peep. \gmu@if {defined}{\@def@token} {\csname gmu@if#1\strip@bslash #2\@xa\endcsname \@def@token }% {\csname gmu@if% \gmu@ifdetokens {#1}{str}% {NX}% {x}% \strip@bslash #2% \endcsname \@let@token }% {#3}{#4}{#5}% } \@dc@AliasCatcher {PLoop} {Loop} \long\def\ArgumentCatcher@Loop@defcheck #1% default, #2% “eacher” {% \edefU\ArgumentCatcher@Loop@check{% \gmu@if {num}{\c@dc@Loop@bound>\z@} {\advance \c@dc@Loop@bound \@dc@Loop@countby \gmu@peep@next \ArgumentCatcher@Loop@afterpeep } {\ArgumentCatcher@Loop@shipout {#1}{#2}}% of if num bound reached }% of |\ArgumentCatcher@Loop@check| }% of |\ArgumentCatcher@Loop@defcheck| \lpdef\@dc@Loop@CareOfSpace #1% a macro with all the arguments except last {\gmu@ifpeeped x \gmu@letspace {\edef\@dc@Loop@careofspace@aas{% \unexpanded{#1{ }}% }% edef unexpanded to allow |#| tokens in |#1| \afterassignment\@dc@Loop@careofspace@aas \let\gmu@drain= }% after |=| is a space. {#1}% next not space, so just |#1| and let it process the next token % its way. } \StoreMacro@nocat\@dc@Loop@CareOfSpace \lpdef\@dc@Loop@CareOfSpace@NoBraces #1% a macro with all the arguments except last {% \gmu@ifpeeped x \gmu@letspace {\edef\@dc@Loop@careofspace@aas{% \unexpanded{#1 }% note the space }% edef unexpanded to allow |#| tokens in |#1| \afterassignment\@dc@Loop@careofspace@aas \let\gmu@drain= }% after |=| is a space. {#1}% next not space, so just |#1| and let it process the next token % its way. } \lpdef\@dc@Loop@CareOfSpaceAndGroup #1% as in the previous macro {\@iwruif {Care of both: @let@token: »\meaning\@let@token«}% \@dc@Loop@CareOfSpace{% \gmu@passbraced{#1}% }% }% of “take care of both” \long\def\ArgumentCatcher@Loop@add #1% default #2% eacher {\@dc@Loop@CareOfSpaceAndGroup {\ArgumentCatcher@Loop@add@{#2}}% } \long\def\ArgumentCatcher@Loop@add@ #1% eacher #2% token/text to be added {\addtomacro\@dc@seQuence{#1#2}% \@iwruif {@@@@@@ Q-add: »\the\@dc@arguments«}% \ArgumentCatcher@Loop@check }% of |\ArgumentCatcher@Loop@add@| \long\def\ArgumentCatcher@Loop@drain #1% default #2% eacher {% \@iwruif{@@@@@@ Q-drain: »\the\@dc@arguments«}% \@dc@Loop@CareOfSpaceAndGroup {\@xa\ArgumentCatcher@Loop@check\@gobble}% } \long\def\ArgumentCatcher@Loop@shipout #1% default #2% eacher {% \gmu@if x{\@dc@seQuence\@empty}% {\def\@dc@seQuence{#1}% \gmu@if x{\@dc@seQuence\@empty}% {}{\prependtomacro\@dc@seQuence{#2}}% }% {}% if |\@dc@seQuence| is nonempty, we don't modify it. \@xa\@dc@addargum\@xa{\@xa{\@dc@seQuence}}% \@iwruif {@@@@@@ Q-finish: »\the\@dc@arguments«}% \@dc@parse@next\@dc@arguments }% of |\ArgumentCatcher@Loop@shipout| \long\def\ArgumentCatcher@Q #1% list #2% default (|\NoValue| by default, as in previous versions). {% \ArgumentCatcher@Loop {StrX}% \any { #1}% note the space before |#1|—settheory sum of |#1| and drainers. \any { }% we ignore spaces—it's a legacy setting, maybe we'll optionise % it in the future \m@ne % we allow any number of tokens {#2}% default, by default |\NoValue|, as defined in line \ref{Q-arg deft.} {}% empty eacher }% \@dc@AliasPLower Q \@ifXeTeX {% \long\def\ArgumentCatcher@Ô #1% list #2% default (|\NoValue| by default, as in previous versions). {% \@dc@BareSpaceArg \ArgumentCatcher@Loop {str}% \any { #1}% note the space before |#1|—settheory sum of |#1| and drainers. \any { }% we ignore spaces—it's a legacy setting, maybe we'll optionise % it in the future \m@ne % we allow any number of tokens {#2}% default, by default |\NoValue|, as defined in line \ref{Q-arg deft.} {}% empty eacher }% \@dc@AliasPLower Ô }{}% of if \XeTeX \def\ArgumentCatcher@D{% decimal argument (useful for dates e.g.) \ArgumentCatcher@Q {-+0123456789}% % the default value will be delivered by the defaults' catcher } \@dc@AliasPLower D \@ifXeTeX {% \def\ArgumentCatcher@Ď #1% default value, 0 by default {% decimal argument \ArgumentCatcher@Loop {StrX}% \any {-+0123456789}% \any {}% \m@ne {#1}% {}% }% \@dc@AliasPLower Ď }{}% of if \XeTeX \def\ArgumentCatcher@U {% \ArgumentCatcher@Loop {StrX}% } \@dc@AliasPLower U \@dc@AliasCatcher W {U} \@dc@AliasPLower W \@dc@AliasCatcher {lostwax} U % ^^A Catcher@lostwax \long\def\ArgumentCatcher@item #1% “sign” of matching #2% list to match against #3% default value #4% eacher (which in this case will be applied to \emph{the} (one) {% \ArgumentCatcher@Loop {StrX}% #1% {#2}% \none {}% we add all that matches 1 % at most one item {#3}% {#4}% } \if@XeTeX \def\ArgumentCatcher@Ǔ{% \@dc@BareSpaceArg \ArgumentCatcher@Loop {StrX}% } \@dc@AliasPLower Ǔ \fi \long\def\ArgumentCatcher@genM #1% the letter »P« (for long catcher) or nothing (for the short version) #2% number of undelimited parametrs to catch (arabic) #3% tail of parsers \@dc@arguments{% \dc@DefParseNext{#3}% \csname ArgumentCatcher@#1m@% \romannumeral#2% \endcsname } \def\ArgumentCatcher@M{\ArgumentCatcher@genM {}} \def\ArgumentCatcher@PM{\ArgumentCatcher@genM P} \@dc@AliasCatcher {m} {M} \@dc@AliasCatcher {Pm} {PM} \@dc@AliasCatcher {ms} {M} \@dc@AliasCatcher {Pms} {PM} \@tempcnta=\@ne \@whilenum\@tempcnta<9\do{% % \edef\gmu@tempa{% % % The short catchers of mandatories: \def\@xanxcs{% ArgumentCatcher@m@\romannumeral\@tempcnta}% \gmu@hashes1{\numexpr\@tempcnta+1}% {\@nx\@dc@addargum{% \gmu@hashesbraced 1{\numexpr\@tempcnta+1}}% \@nx\@dc@parse@next\@nx\@dc@arguments }% of \incs{ArgumentCatcher@m@\}. % % And the long ones: \long \def\@xanxcs{% ArgumentCatcher@Pm@\romannumeral\@tempcnta}% \gmu@hashes1{\numexpr\@tempcnta+1}% {\@nx\@dc@addargum{% \gmu@hashesbraced 1{\numexpr\@tempcnta+1}}% \@nx\@dc@parse@next\@nx\@dc@arguments }% of \incs{ArgumentCatcher@Pm@\}. % }% of |\edef|. \gmu@tempa \advance\@tempcnta1\relax }% of the loop. \if 1 1 \@tempcnta\@ne \@whilenum\@tempcnta<9\do{% \typeout{\bslash ArgumentCatcher@m@\romannumeral\@tempcnta: ^^J% \Name\meaning{ArgumentCatcher@m@\romannumeral\@tempcnta}^^J}% \typeout{\bslash ArgumentCatcher@Pm@\romannumeral\@tempcnta : ^^J% \Name\meaning {ArgumentCatcher@Pm@\romannumeral\@tempcnta}^^J^^J^^J% }% \advance\@tempcnta\@ne } \fi \def\ArgumentCatcher@m@ix #1#2#3#4#5#6#7#8#9{% \@dc@addargum{% {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}% \the \@dc@arguments } \long\def\ArgumentCatcher@Pm@ix #1#2#3#4#5#6#7#8#9{% \@dc@addargum{% {#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}% \the \@dc@arguments } \long\def\ArgumentCatcher@K % a~Knuthian delimited or undelimited #1% the particular Knuthian macro #2% the tail of args parser. \@dc@arguments % tail delimiter {\dc@DefParseNext{#2}#1} \@dc@AliasPLower K \long\def\gmu@twostring#1#2{\string#1\string#2} \long\def\ArgumentCatcher@G@longorshort #1% longness prefix (|\long| or nothing) #2% left and right delimiters #3% default value #4% the tail of args parser. \@dc@arguments % tail delimiter {% \edef\@dc@Gname{ArgumentCatcher@G\gmu@twostring#2}% \gmu@if {csname}{\@dc@Gname \endcsname}% {}% {#1\Name\def{\@dc@Gname \@xa}% \@dc@Gparams#2{\@dc@addargum{{##2}}##1\@dc@arguments}% }% \@xa\@ifEUnextchar\@firstoftwo#2% {\def\dc@parse@next{#4}% we hide possible |\par|s. \csname \@dc@Gname \endcsname\dc@parse@next}% {\@dc@addargum{{#3}}#4\@dc@arguments}% } \long\def\@dc@Gparams#1#2{##1#1##2#2} \lpdef\ArgumentCatcher@G % short general catcher #1% left and right delimiters #2% default value {\ArgumentCatcher@G@longorshort{}{#1}{#2}} \lpdef\ArgumentCatcher@PG % long general catcher #1% left and right delimiter #2% default value {\ArgumentCatcher@G@longorshort{\long}{#1}{#2}} \def\@dc@DefAsGeneral #1% specifier #2% delimiters {\Name\lpdef{ArgumentCatcher@\strip@bslash{#1}}% ##1% default value {\ArgumentCatcher@G{#2}{##1}}% \Name\lpdef{ArgumentCatcher@P\strip@bslash{#1}}% ##1% default value {\ArgumentCatcher@PG{#2}{##1}}% »P« was missing. Fixed 2011/03/22, 16.14. % \gmu@if {cat}{a\@nx#1}% {\@dc@LowerAliases #1}{}% } \@dc@DefAsGeneral A{<>} \@dc@DefAsGeneral O{[]} \def\DCnocoordinate{\@dc@DefAsGeneral C{()}} \DCnocoordinate \edefU\DCcoordinate{% % \long\def\ArgumentCatcher@C #1% default value #2% tail of parsers \@dc@arguments % tail's delimiter {% \@ifEUnextchar(%^^A) {\dc@DefParseNext{#2}\ArgumentCatcher@c@}% {\@dc@addargum{{#1}}#2\@dc@arguments}% }% % \let\ArgumentCatcher@c\ArgumentCatcher@C \let\ArgumentCatcher@Pc\ArgumentCatcher@PC % \long\def\ArgumentCatcher@PC#1#2\@dc@arguments{% \@ifEUnextchar(%^^A) {\dc@DefParseNext{#2}\ArgumentCatcher@Pc@}% {\@dc@addargum{{#1}}#2\@dc@arguments}% }% % \def\ArgumentCatcher@c@(#1){% \gmu@ifxany,{#1}% {\@xa\@dc@addargum\@dc@commasep#1\@dc@commasep}% {\@dc@addargum{{#1}}}\@dc@parse@next\@dc@arguments }% % \stanza \def\@dc@commasep#1,#2\@dc@commasep{{{{#1}{#2}}}}% % \stanza \long\def\ArgumentCatcher@Pc@(#1){% \gmu@ifxany,{#1}% {\@xa\@dc@addargum\@dc@commasep#1\@dc@commasep}% {\@dc@addargum{{#1}}}\@dc@parse@next\@dc@arguments }% } \def\@dc@Scope@shipout#1{% \ifx\@dc@seQuence\@empty\def\@dc@seQuence{#1}\fi \@xa \gmu@ifxany\@xa \global\@xa{\@dc@seQuence}% {\@dc@addargum{{\global}}}% {\@dc@addargum{{\relax}}}% \@dc@parse@next\@dc@arguments } \def\ArgumentCatcher@Scope #1% the separator(s) {\let\@dc@seQuence@shipout@@\@dc@seQuence@shipout \let\@dc@seQuence@shipout\@dc@Scope@shipout \ArgumentCatcher@Q{\global\relax}{\relax}% \let\@dc@seQuence@shipout\@dc@seQuence@shipout@@ \@dc@ignorearg \ArgumentCatcher@T{#1}{\NoValue}% } \@dc@AliasCatcher {PScope} \Scope \long\def\gmuIfNoValueTF#1{% % \chgs{2008/12/1 v0.98 the \pk{xparse} tests for % the presence of value redefined and much simplified (43 \CS'es % less). Moreover, they are now fully expandable: \cmd\gmuIfNoValueTF, % \cmd\gmuIfNoValueT, \cmd\gmuIfNoValueF, \cmd\gmuIfValueTF, \cmd\gmuIfValueT, % \cmd\gmuIfValueF} % % \chgs{2010/05/27 v0.993 bug fix: order of \cmd\NoValue and % \cs{@firstofmany} reversed after a catastrophal |{11}{11}| argument} \@xa\ifx\@xa\NoValue\@firstofmany#1\@empty\@nil \afterfi\@firstoftwo \else\afterfi\@secondoftwo \fi} \long\def\gmuIfNoValueT#1#2{\gmuIfNoValueTF{#1}{#2}\@empty} \long\def\gmuIfNoValueF#1#2{\gmuIfNoValueTF{#1}\@empty{#2}} \long\def\gmuIfValueTF#1#2#3{\gmuIfNoValueTF{#1}{#3}{#2}} \long\def\gmuPutIfValue#1{\gmuIfValueT{#1}{#1}} \let\gmuIfValueT\gmuIfNoValueF \let\gmuIfValueF\gmuIfNoValueT \long\pdef\IfLong#1{%\ % \begin{enumargs} % \item the argument to check for |\par|, % \item what if |\par| found, % \item what if |\par| not found. % \end{enumargs} % \edef\gmu@IfLong@resa{\detokenize{#1}}% \edef\gmu@IfLong@resa{% \IfAmong\string\par\@nx\among{\gmu@IfLong@resa}}% \gmu@IfLong@resa} \long\@namedef{ArgumentCatcher@=}% #1% register used in the assignment #2% the tail of args parser. \@dc@arguments{% \dc@DefParseNext{% \@dc@addargum\NoValue % to make ignoring mechanism work #2\@dc@arguments}% \afterassignment\@dc@parse@next #1}% optional space and |=| is left at user's discretion. In fact, \n@melet{ArgumentCatcher@P=}{ArgumentCatcher@=} \long\def\ArgumentCatcher@gobblespace {\ArgumentCatcher@T {\dc@gobblespace@dummy}{\NoValue}} \let\ArgumentCatcher@Pgobblespace\ArgumentCatcher@gobblespace \def\dc@gobblespace@dummy{\dc@gobblespace@dummy} \let\gobblespace\dc@gobblespace@dummy \errorcontextlines=100 \long\def\@dc@InnerName#1{% \bslash@or@ac{#1}% \bslash }% \long\def\@dc@InnerEndName #1{% version for the end-macros of environments \bslash end\strip@bslash{#1}% }% %% \CH{2010/07/26 v0.993 This strikingly simple idea of storing the %% specifiers' sequence in a macro came to my head only after some %% three years of developing \cmd\DeclareCommand} \long\edef\@dc@SpecsArName#1{% Specs \string& arity of \@nx\bslash@or@ac{#1}% }% \pdef\@dc@messages {% \gmu@notif {@dc@quiet@}{}% {% \gmu@if {DCMessages}{}% {\PackageInfo{gmcommand}{^^J% Parsing arguments for \dc@innername^^J% [specified as: \unexpanded \@xa\@xa\@xa \@xa\@xa\@xa \@xa{% \@xa\@xa\@xa\@secondofmany % % not |\@secondofthree| because first use of this definition is for % |\DeclareCommand| not having its specifiers' carrier. % \csname \@dc@specsname\endcsname {}{}\@nil }% \space ]^^J% [in file: \@currname.\@currext\space ]}% of info message }% of if \ac DC messages {}% of if not |DCMessages| }% of if not |@dc@quiet@| {}% of if not not |@dc@quiet@| }% of |\@dc@messages| \edefU\@dc@DCbody {% {% \label{DC:final} % % \chgs{2008/12/05 v0.98 added the \cs{@bsphack}---\cs{@esphack} option} % \chgs{2008/12/07 v0.98 added the \env{Q\arg{tokens}} argument type % (a~word over the alphabet \)} \edef\dc@innername {\@dc@InnerName #1}% we'll use it in |K|-type arg.\ catcher and \edef\@dc@specsname {\@dc@SpecsArName{#1}}% \gmu@ifCSdefined {#1}% {\gmu@if{DCMessages}{}% {\PackageWarning{gmcommand}{% ^^J% Redefining command \dc@innername\space with \string\DeclareCommand}% }% {}% }% {\gmu@if {DCMessages}{}% {\PackageInfo{gmcommand}{^^J% \string\DeclareCommand-ing \dc@innername\space (new)^^J}% }% {}% }% \@dc@alllong@false \@dc@quiet@false % \emptify\@dc@Specs@tempa % \gmu@ifsbintersect{#2}{\long!lL}{% \addtomacro\@dc@Specs@tempa{\long}% \@dc@alllong@true}% {}% % \gmu@ifsbintersect{#2}{.qQ\quiet}{% \addtomacro\@dc@Specs@tempa{\quiet}% \@dc@quiet@true}% {}% % \gmu@ifsbintersect{#2}{iIwW\sphack}% {% if `invisibility' is specified: \UnDef \addtomacro\@dc@Specs@tempa{\sphack}% \def\@dc@bsphack@{\@nx\@bsphack}% \UnDef \def\@dc@esphack@{\@nx\@esphack}% }% {\emptify\@dc@bsphack@ \emptify\@dc@esphack@}% if `invisibility' is not specified. % \gmu@ifsbany\envhack{#2}% {% but if we define an environment: \addtomacro\@dc@Specs@tempa{\envhack}% \emptify\@dc@bsphack@ \emptify\@dc@esphack@ \edef\@dc@setThrowArgs{% \dc@ThrowArgs{\string#1}}% if our command is used }% {% and if we don't define an environment: \emptify\@dc@setThrowArgs }% % \relaxen\@dc@global@ \relaxen\@dc@outer@ % \gmu@ifsbany\outer{#2}% {\addtomacro\@dc@Specs@tempa{\outer}% \let\@dc@outer@\outer}% {}% % \gmu@ifsbany\global{#2}{% \addtomacro\@dc@Specs@tempa {\IAmDeclaredGlobally}% \let\@dc@global@\global}% {}% % \@xa\Name \@xa\edefU \@xa\@dc@specsname \@xa{\@xa{\@dc@Specs@tempa}}% \@dc@ResetParseAuxilia % \@dc@ParseNextSpecifier #3% \@dc@buckstopshere % it's the sentinel of parsing. Since the test % \@xa \Name \@xa \addtomacro \@xa \@dc@specsname \@xa {\@xa{\the\@dc@ParsedSpecs}}% % \@xa\Name\@xa\addtomacro\@xa\@dc@specsname \@xa{\@xa{\the \c@dc@argnum}}% % \@dc@outer@\@dc@global@ % possibly the prefixes, %%%%% %%%%%% Here comes the definition of the coating macro, named the %%%%%% same as the command: \protected\edef#1{% always |\protected| \balsmiley( ;-) \@dc@bsphack@ % perhaps |\@bsphack| % \@dc@messages % \@nx\@dc@{\the\toks@}% in the braces appear the argument catchers. \@xanxcs{\dc@innername}% \ifx\@dc@outer@\outer \@xanxcs{\@xa\gobble\string#1 }% note the blank \else \@nx #1% \fi }% of main coating macro's |\edef|. \UnDef % \edef\gmu@DeclareCommand@resa{% \@dc@global@ % perhaps |\global| \long\def\@xanxcs{\@dc@InnerName{#1}}% for a~command \@xau\@dc@innerhashes % it's |#1#2#3…| {% the body of the inner ‘|\\⁄\|’ macro: \@dc@setThrowArgs \unexpanded{#4}% \@dc@esphack@}% }% of |\edef|. \gmu@DeclareCommand@resa }% of |\DeclareCommand|'s body. } \def\@dc@DCprefixQlist{\global\protected\outer\long \relax % for the somewhat perverse case when |\@dc@global| may be !lL.qQiIwW\sphack\envhack} \long\def\ShowCommand #1{% \@iwruJ \@iwru{»\string#1« is »\meaning#1«}% \@iwruJ \@iwru{»\Name\string{\@dc@InnerName{#1}}« is »\Name\meaning{\@dc@InnerName{#1}}«}% \@iwruJ \@iwru{»\Name\string{\@dc@SpecsArName{#1}}« is »\Name\meaning{\@dc@SpecsArName{#1}}«}% \@iwruJ \show\show } \@XA{\DeclareCommand\DeclareCommand % This is the final version by now.\ { #1 >Pm % command to be defined (may be even \incs{par} if you #2 >\@xa Q{\@dc@DCprefixQlist}{} %\ #3 >Pm % arguments specification (may contain \incmd\par), #4 >Pm % the definition body; may contain nearly anything including }}\@dc@DCbody \@XA{\DeclareCommand \DeclareCommand \long {m >\@xa Q{\@dc@DCprefixQlist}{} mm}}% \@dc@DCbody \long\def\dc@EAName#1{% Env.\ arguments' toks' name \if\bslash#1\else#1\fi's_args} \pdef\dc@ThrowArgs#1{% \gmu@if{csname}{\dc@EAName{#1}\endcsname} {}% if it's defined, we do nothing (we assume it's defined by us and % is toks register.) {% else we define it as a new toks % \label{'s args} \@xa\newtoks\csname\dc@EAName{#1}\endcsname }% \csname\dc@EAName{#1}\endcsname=% \@xa\@xa\@xa{\@xa\@gobble\the\@dc@arguments}% }% \def\@dc@K@defaultrepl{##1} \DeclareCommand\@dc@define@K \long {mb}{% \label{K@parse} % First we add the particular \CS to the toks register:\nostanza \edef\gmu@tempa{% \unexpanded{\toks@\@xa}% {\@nx\the\toks@{% \@xanxcs{\dc@innername @K\the\c@dc@catchernum}% }% }% % here we add to the parsers toks list a \CS\ named % |\⁄@K⁄| (the particular Knuthian catcher) }\gmu@tempa % and define this macro: \nostanza \edef\gmu@tempa{% % And now we define that particular Knuthian catcher. \def\@xanxcs{\dc@innername @K\the\c@dc@catchernum}% \gmu@if {@dc@xadefault@i@}{}% {\@xau{#1}}% {\unexpanded{#1}}% {% \@nx\@dc@addargum{{% \gmuIfValueTF{#2}{% \gmu@if{@dc@xadefault@ii@}{}% {\@xau{#2}}% {\unexpanded{#2}}% }{\@xau{\@dc@K@defaultrepl}}% }}% we add the Knuthian % replacement to the toks register as \inhash n. \@nx \@dc@parse@next \@dc@arguments }% and continue parsing. }% of |\edef|. Now we execute this temporary macro, which means we \incmd\def|\⁄@K⁄| \@dc@global@ % set properly before |\@dc@ParseNextSpecifier #3⁄|. \if P\@dc@long@letter\relax\long\fi \gmu@tempa % \@dc@addtospecs {#1}% % \gmuIfValueTF{#2}{% \gmu@if{@dc@xadefault@ii@}{}% {\@xa\@dc@addtospecs\@xa{#2}}% {\@dc@addtospecs{#2}}% } {\@xa\@dc@addtospecs\@xa{\@dc@K@defaultrepl}}% % % Now we clean up and continue construction of arguments parser. \nostanza \@dc@ParseNextSpecifier }% of |\@dc@define@K| \DeclareCommand\@dc@grab@Loop \long {% #1 T{\any \none Uu\U \u Ǔǔ\Ǔ \ǔ Ww\W \w \lostwax} % the “sign” of matching for adding; use of % the letters suppresses adding them to the % parsed specifiers' list, which is crucial for % |\SameAs| copying of specifiers: the “until” and “while” loops % don't shift their arguments. % #2 >Pm % list of tokens to match for/against iteration % >i T{\drain \drop \Drain \Drop \lost \Lost} #3 T{\any \none }{\any} % the “sign” of matching for draining % #4 b{} % list of drainers, empty by default % >i T{\count \ubound} #5 D{\m@ne} % upper bound of iterations % >i T{\default \Default} #6 b % default value (|\NoValue| by default) % #7 T{\eacher \Eacher \defEacher} % default is |\NoValue| and that's no % harm since we test if |#7| == |\defEacher|. #8 B{} % eacher, empty by default }{% % \@dc@process@matchsign {#1} {##1}% % \dc@addtoParsed@{#2}% % \gmu@if {strings}{\lostwax#1}% {\gmu@if {@dc@xadefault}{}% {\@xa\edefU\@xa\@dc@LostWaxList\@xa{#2}}% {\edefU\@dc@LostWaxList{#2}}% }% {}% % \@dc@process@matchsign {#3} {##3}% % \dc@addtoParsed@{#4}% % \@xa \@dc@addtospecs@bare \@xa{\the\numexpr #5}% \@dc@addtotoks@bare{{#5}}% to ignore possible expandafter. % \dc@addtoParsed@ {#6}% % \gmu@if {strings}{\defEacher#7} {% \Name\def{\dc@innername/defdEacher/\the\c@dc@argnum}% ##1{#8}% % \Name \dc@addtoParsed@ {\dc@innername/defdEacher/\the\c@dc@argnum}% } {\gmu@if {@dc@xaeacher@}{} {\@dc@xadefaulttrue}{\@dc@xadefaultfalse}% \dc@addtoParsed@ {#8}% }% % \gmu@if {strings}{\lostwax#1} {\grab@LostWax} {\@dc@ParseNextSpecifier}% } \DeclareCommand\grab@LostWax { >iT{\lost \Lost} #1 b{\lostwax@NoVal} >iT {\count \ubound} #2 D{1} >iT{\endlost \EndLost} }{% % We build an ignored “while” catcher. % \def\@dc@LostWaxA{>iw}% % \gmu@ifdetokens {\lostwax@NoVal}{#1} {% % if no particular value of the “lost wax” is provided, we assume % the same as the “until” delimiter(s). % \prependtomacro\@dc@LostWaxA{>\@xa}% \addtomacro\@dc@LostWaxA{\@dc@LostWaxList}% }% % % Otherwise first we check whether “lost wax” provided has nonempty % intersection with the “until” delimiters. {% \@xa\gmu@ifstrintersect \@xa{\@dc@LostWaxList}{#1} {\addtomacro\@dc@LostWaxA{{#1}}}% {\PackageError{gmutils/gmcommand}{^^J% You try to declare a "Lost Wax" catcher^^J% with the "Lost" list disjoint with the "Until" list.^^J% I assume sum of them}% {}% % \@xa \addtomacro\@xa\@dc@LostWaxA \@xa{\@xa{\@dc@LostWaxList #1}}% }% }% % \addtomacro\@dc@LostWaxA{ \count #2 \relax}% % \@xa\@dc@ParseNextSpecifier \@dc@LostWaxA }% of |\grab@LostWax|. \def\@dc@process@matchsign #1% the argument #2% its numeral in human language (for the error message) {% \gmu@CASE {strings} {{#1}\any } {\@dc@addtoParsed@bare {\any }}% % \gmu@CASEsbany {#1} {Ww} {\@dc@addtotoks@bare {\any}}% % \gmu@CASE {strings} {{#1}\none} {\@dc@addtoParsed@bare {\none }}% % \gmu@CASEsbany {#1} {UuǓǔ\lostwax } {\@dc@addtotoks@bare {\none }}% % \gmu@lastCASE {\PackageError{gmcommand}{% You *have* to declare »\string\any« or »\string\none« ^^J% as the #2 argument for the »\string\loop« catcher}{}% }% \gmu@ESAC } \long\pdef\UnDeclareCommand#1{% \let#1\@undefined \ifcsname\@dc@InnerName{#1}\endcsname \n@melet{\@dc@InnerName{#1}}{@undefined}% \fi \ifcsname\@dc@SpecsArName{#1}\endcsname \n@melet{\@dc@SpecsArName{#1}}{@undefined}% \fi } \edef\gmu@tempa{% \def\@nx\gmu@ifHashless@##1% \detokenize{macro:}##2->##3\@nx\@nil}% \gmu@tempa {\gmu@if {}{\gmu@ifempty{#2}{1}{0}\gmu@ifempty{#3}{2}{1}}} \long\edef\gmu@ifHashlessMacro #1% a \CS, name or active char {% \edef\@nx\gmu@WHL@arg{\@nx\@xanxtri{#1}}% \unexpanded{\@xa\@xa\@xa\gmu@ifHashless@ \@xa\meaning\gmu@WHL@arg}% \relax % to ensure that |#3| of |\gmu@ifHashless@| is nonempty % if match for the delimiters is found earlier \detokenize{macro:***->}\@nx\@nil % the sentinels } \long\def\gmu@ifDeclared#1{% % \begin{enumargs} % \item a \CS or csname or an active char, % \item true branch, % \item false branch % % \end{enumargs} \let\gmu@ifDe@next\@secondoftwo % % \gmu@CASEnot {csname} {\@dc@SpecsArName{#1}\endcsname}% {}% % \gmu@CASEnot {csname}{\@dc@InnerName{#1}\endcsname}% {}% % \gmu@EatCases {\gmu@ifHashlessMacro{#1}% {\edef\gmu@ifDe@resa{% \@nx\gmu@ifxany\@xanxcs{\@dc@InnerName{#1}}% {\unexpanded\@xa\@xa\@xa{\gmu@WHL@arg}}% % Above: to get the contents of the outer macro we use the macro % carrying conversion of possible name into a \CS and expand % it twice. Then we freeze it with |\unexpanded|. {\let\@nx\gmu@ifDe@next\@nx\@firstoftwo}% if the inner macro % is present in the % contents of |#1|, we take the first implicit argument {}% otherwise we do nothing (taking the second implicit is % already set) }% of edef \gmu@ifDe@resa }% of if a hashless macro {}% of if not a hasless macro }% % \gmu@ESAC \gmu@ifDe@next }% of |\gmu@ifDeclared| \long\def\@dc@SameAs#1{% \gmu@ifDeclared {#1}% {% \@xa\@xa\@xa \@xa\@xa\@xa \@xa \@dc@ParseNextSpecifier \@xa\@xa\@xa \@secondofthree \csname \@dc@SpecsArName{#1}\endcsname }% {% \PackageError{gmcommand}{% Command \@nx#1 ^^J% is not declared with \DeclareCommand. ^^J% I can't repeat its parameters in current command declaration}% {}% }% }% of |\@dc@SameAs| \DeclareCommand\DCUse{ #1 >Pm % the command }{% ^^A with star we automatically pass the \gmu@ifDeclared{#1}% {% \@dc@arguments\@xa{\@xa \csname \@dc@InnerName{#1}\endcsname }% % \csname ArgumentCatcher@Pm@\romannumeral \@xa \@xa \@xa \@thirdofthree \csname \@dc@SpecsArName{#1}\endcsname % of arity carrier \endcsname % of the catcher }% {\DC@EndNotDeclaredErr{#1}}% }% \pdef \DC@EndNotDeclaredErr #1{% \PackageError{gmcommand}{% Command \bslash end\strip@bslash{#1} ^^J% is not declared with \DeclareCommand. ^^J% Therefore I can't use its DC-inner macro (because of its nonexistence).^^J}% {}% } \DeclareCommand\DCUseEnd{ #1 >Pm % the command (without “end”) }{% \gmu@ifDeclared{end\strip@bslash{#1}}% {% \@dc@arguments\@xa{\@xa \csname \@dc@InnerEndName{#1}\endcsname }% % \csname ArgumentCatcher@Pm@\romannumeral \@xa \@xa \@xa \@thirdofthree \csname \@dc@SpecsArName{#1}\endcsname % of arity carrier \endcsname % of the catcher }% {\DC@EndNotDeclaredErr{#1}}% }% \DeclareCommand\DeclareEnvironment \long { #1--#4 \SameAs \DeclareCommand % We repeat the specifiers, but the role of |#4| is slightly % different here: here it's the |\begin| part definition. % #5 m % the end definition; it \emph{can} contain any % \inverb|#|\---the arguments of the environment are passed % to it, too. }{% \def\gmu@DeclareEnvironment@resa{\envhack}% we add the information we define an % environment. \gmuIfValueT{#2}% {\addtomacro\gmu@DeclareEnvironment@resa{#2}}% we pass all the ‘prefixes’ to % \incs{Decl\+are\+Comm\+and} % \stanza \@xa\DeclareCommand\csname#1\@xa\endcsname \gmu@DeclareEnvironment@resa{#3}{#4}% % %\nostanza Now the begin definition is done. Let's get down to the %end definition. \nostanza % \let\@dc@env@endglobal=\@dc@global@ % note this \CS was for sure redefined by the last % \incs{Decl\+are\+Com\+m\+and} (and by nothing else) and that's % exactly what we want. \edef\gmu@DeclareEnvironment@resb{% \@nx\@xa \@xanxcs{\bslash end#1}% \@nx\the \@xanxcs{\dc@EAName{#1}}% }% of |\edef|. It reuslts in % \[|\@xa \\end⁄ \the\\⁄'s_args|\] % which does not collide with the inner macro of the |\end›…| % command, since the latter is |\\end›…\|. \gmu@if{csname}{\dc@EAName{#1}\endcsname}{\gmu@namelet\global{\dc@EAName{#1}}{@undefined}}{}% \edef\gmu@DeclareEnvironment@resa{% \UnDef \@dc@global@\long\def % the inner end macro is always \incmd\long\ % and perhaps defined \incmd\global ly. \@xanxcs{\bslash end#1}% \@xau\@dc@innerhashes % it's |#1#2#3›…|---the inner end macro takes the % same number of parameters as the begin macro. {% the definition body \unexpanded{#5}}% }% of |\edef›…@resa|. \gmu@DeclareEnvironment@resa \edef\gmu@DeclareEnvironment@resc{% \DeclareCommand\@xanxcs{end#1}% \@dc@env@endglobal {}% no parameters {\@xau {\gmu@DeclareEnvironment@resb \@ignoretrue}% }% }% \gmu@DeclareEnvironment@resc % % }% of |\DeclareEnvironment| \DeclareCommand\NewCommand {\SameAs\DeclareCommand} {% \gmu@ifCSdefined {#1} {\DCUse\DeclareCommand#1{#2}{#3}{#4}}% {\PackageError{gmcommand}% {Command \@nx#1 already defined \on@line!}% {}% }% } \DeclareCommand\RenewCommand {\SameAs\DeclareCommand} {% \gmu@ifCSdefined {#1} {\DCUse\DeclareCommand#1{#2}{#3}{#4}}% {\PackageError{gmcommand}% {Command \@nx#1 not yet defined \on@line!}% {}% }% } \DeclareCommand\ProvideCommand {\SameAs\DeclareCommand} {% \gmu@ifCSdefined {#1} {} {\DCUse\DeclareCommand#1{#2}{#3}{#4}}% } \DeclareCommand\NewEnvironment {\SameAs\DeclareEnvironment} {% \gmu@ifdefined{#1} {\DCUse\DeclareEnvironment{#1}{#2}{#3}{#4}{#5}}% {\PackageError{gmcommand} {Environment #1 already defined \on@line!}{}% }% } \DeclareCommand\RenewEnvironment {\SameAs\DeclareEnvironment} {% \gmu@ifdefined {#1} {\DCUse\DeclareEnvironment{#1}{#2}{#3}{#4}{#5}}% {\PackageError{gmcommand} {Environment #1 not yet defined \on@line!}{}% }% } \DeclareCommand\XeTeXthree{o}{% \ % \changes{v0.90}{2008/8/4}{adjusted % to the redefinition of % \cs{verb} in \pk{xlxtra} 2008/07/29} \@ifXeTeX{% \gmuIfValueT{#1}{\PassOptionsToPackage{#1}{fontspec}}% \@ifpackageloaded{gmverb}% {% \Store@Macro\verb \StoreEnvironment{verbatim}% \StoreEnvironment{verbatim*}% }{}% \RequirePackage{xltxtra}% since v 0.4 (2008/07/29) this package % redefines |\verb| and \env{verbatim*}, % and quite elegantly provides an option % to suppress the redefinitions, but % unfortunately that option excludes also % a~nice definition of |\xxt@visiblespace| % which I~fancy. \@ifpackageloaded{gmverb}% {% \Restore@Macro\verb \RestoreEnvironment{verbatim}% \RestoreEnvironment{verbatim*}% }{}% % \AtBeginDocument{% \@ifpackageloaded{gmlogos}{% \Restore@Macro\LaTeX\Restore@MacroSt{LaTeX }% my version of the % \LaTeX\ logo has been stored just % after defining, in line \ref{SMLaTeX}. \ilrr \Restore@Macro\eTeX}% {}% }% % \stanza \pdef\adddefaultfontfeatures##1{% \addtomacro\zf@default@options{#1,}} }% of |\@ifXeTeX|'s first argument, {}% |\@ifXeTeX|'s second argument, }% of |\XeTeXthree|'s body. \DeclareCommand\setspaceskip{% A{1}% optional factor for all three components O{\fontdimen2\font}% >is O{\fontdimen3\font}% >is O{\fontdimen4\font}} {\spaceskip=\glueexpr\dimexpr#2*#1\relax plus\dimexpr #3*#1\relax minus\dimexpr#4*#1\relax\relax} \pdef\unsetspaceskip{% \spaceskip=\z@skip } \def\makestarlow{% \begingroup\lccode`\~=`\*\lowercase{%% \Define** \endgroup\def~{\gmu@lowstar}}% 2009/10/19 |\let| changed to % \inverb|\def| to allow redefinitions of \incmd\gmu@lowstar. \catcode`\*=\active \defLowStarFake } \DeclareCommand\defLowStarFake{% Q{+-0123456789,.}{0,5}% fraction of fontchar depth of the star glyph }% {% \def\gmu@lowstarfake{% \leavevmode\vbox{\hbox{*}\kern#1\fontchardp\font`*}% }% } \def\gmu@lowstarfake{*} % useful for next command where normal star is \DeclareCommand\enoughpage{% #1 D{\NoValue} % (optional short version (number of % |\baselineskip|s)) Before 2010/9/10 the default % value was the |D|-default, i.e., 0, which lead to % improper working of this command. #2 B{2\baselineskip}% (2) optional (formerly mandatory) long version of % required room on a page >is #3 >PB{} % (3) what if the room is enough >is #4 >PB{\newpage} % (4) what if there's to little room on a page }{% % \chgs{2009/03/18 v0.98 made \eTeX-ish} % \chgs{2009/05/25 v0.98 made ifthenelse-like with ‘then’ and ‘else’ % optional default \ and \cmd\newpage resp.} % \chgs{2009/10/21 v0.98 \cmd\par\ removed since to let it be used % for \cmd\pagebreak\ inside a paragraph} \gmu@if {num} {\numexpr \ifdim % if the space left is less than we wish then 1, otherwise 0. \gmu@pageremain <% \dimexpr (\gmuIfValueTF{#1}{#1\baselineskip}{#2})*1% \endexpr % % \CH{2010/06/28 v0.993 I added |(›…)*1| to assure that |\relax| % really delimits the dimexpr} % 1\else 0% \fi *% \ifdim \gmu@pageremain >-1sp 1% if the room left on current page is nonnegative, % then we indeed are on current page so “enough” and % “not enough” does make sense: Enough is enough. \else 0% otherwise we are on next page (or further) and assume % there is enough room for our purpose. \fi *% \ifdim \pagegoal <\maxdimen 1 % if there are some boxes on current page, so checking room % does make sense. \else 0% otherwise (no boxes on current page) assume there's % enough room \fi >\z@ }% of condition {\typeout{@@@@@ not enough page \on@line}% #4% }% {#3}% } \long\def\gmu@LC@LetInners #1% scope prefix (|\global| or |\relax| #2% left side #3% right side of the assignment {% \edef\gmu@LC@InnerLeft{\@dc@InnerName{#2}}% \edef\gmu@LC@InnerRight{\@dc@InnerName{#3}}% % \gmu@namelet{#1}{\gmu@LC@InnerLeft}{\gmu@LC@InnerRight}% \edef\gmu@LC@InnerLeft{\@dc@SpecsArName{#2}}% \edef\gmu@LC@InnerRight{\@dc@SpecsArName{#3}}% % \gmu@namelet{#1}{\gmu@LC@InnerLeft}{\gmu@LC@InnerRight}% } \long\def\gmu@CL@PrepareArg #1% left/right #2% |\@xa| or |\edef|, maybe sth.\ more in the future #3% a \CS, text of a name or an active char {% \Name\let{gmu@CL@#1}\@undefined \ifx\@xa#2\Name\edef{gmu@CL@#1}{\@xau{#3}}\fi \ifx\edef#2\Name\edef{gmu@CL@#1}{#3}\fi \unless\ifcsname gmu@CL@#1\endcsname \Name\edef{gmu@CL@#1}{% \gmu@if{cat}{\@nx~\@nx#3}% {\@nx#3}{\strip@bslash{#3}}% }% \fi } \DeclareCommand\CommandLet \long {% \Scope % (1) T{\@xa\edef} % (2) whether left side should be |\expandaftered| m % (3) left side of assignment >iT{=} % pro forma T{\@xa\edef} % (4) whether right side should be |\expandaftered| m % (5) right side of the asssignment }{% % \gmu@CL@PrepareArg{left}#2{#3}% \gmu@CL@PrepareArg{right}#4{#5}% % \@xa\gmu@ifDeclared\@xa{\gmu@CL@right}{% \edef\gmu@LC@resa{% \DeclareCommand % \@xa\@xanxtri\@xa{\gmu@CL@left}% #1% scope prefix {\@nx\SameAs\@xa\@xanxtri\@xa{\gmu@CL@right}}% args. spec {}% the body of the command will be |\let| via letting inners. }% % \gmu@LC@resa \@XA{\@xa\gmu@LC@LetInners\@xa#1% \@xa{\gmu@CL@left}}\@xa{\gmu@CL@right}% }% of if Declared {% if not Declared, we just |\let|: \if\@nx#3ѥ\typeout{@@@@@ »\@xa\@dc@InnerName\@xa{\gmu@CL@right}« is not Declared?: \Name\meaning{\@xa\@dc@InnerName\@xa{\gmu@CL@right}}% }% \show\NotDeclared \fi \@XA{\@xa\tri@let\@xa#1% \@xa{\gmu@CL@left}}\@xa{\gmu@CL@right}% }% } \DeclareCommand\envirlet \long{\Scope mm}{% for |\let|ting environments. \CommandLet #1{#2}{#3}% \CommandLet #1{end#2}{end#3}% } \DeclareCommand\@fornum{% m% (1) initial (least) num. value m% (2) limit (last iterated over) num. value O{1}% (3) step of iteration m% (4) body of the loop }% {\edef\gmu@fornum@min{\the\numexpr #1}% \edef\gmu@fornum@lim{\the\numexpr #2}% \let\gmu@fornum@curr\gmu@fornum@min \@whilenum\gmu@fornum@curr<\gmu@fornum@lim \do{#4% \edef\gmu@fornum@curr{% \the\numexpr\gmu@fornum@curr+#3}% }% of |\@whilenum|'s body. }% of |\@fornum|. \pdef\StoreCommand{% \begingroup %\label{SC begr} \MakePrivateLetters \@StoreCommand } \long\def\gmu@SC@StorageName #1% a \CS, name or active char #2% group level {% \gmu@storeprefix/% \ifnum\numexpr#2>-1 \the\numexpr(#2)*1\relax\fi \bslash@or@ac {#1}% }% \def\gmu@SC@setgrouplevel #1% |+›⁄|-⁄|\NoValue| #2% a decimal number {\edef\gmu@SC@grouplevel{% \the\numexpr \gmuIfValueTF{#1}% {\currentgrouplevel#1#2+1}{#2}% }% of the grouplevel-carrying macro } \DeclareCommand\@StoreCommand {% #1 T{+-}% grouplevel shift indicator #2 d % group level or shift (the latter relative to the current g.l.) #3 >Pm% name or \CS }{% \endgroup %we close the group opened in line \ref{SC begr}. \gmu@SC@setgrouplevel{#1}{#2}% % \edef\gmu@SC@resa{% \gmu@SC@StorageName{#3}{\gmu@SC@grouplevel}}% % \let\gmu@SC@scope\relax \ifnum\gmu@SC@grouplevel>\currentgrouplevel \let\gmu@SC@scope\global \fi \@xa\CommandLet\@xa\gmu@SC@scope\@xa{\gmu@SC@resa}{#3}% } \pdef\StoreEnvironment{% \begingroup \MakePrivateLetters \@StoreEnvironment } \def\@StoreEnvironment#1{% \@StoreCommand{#1}% \begingroup \@StoreCommand{end#1}% } \pdef\RestoreEnvironment{% \begingroup \MakePrivateLetters \@RestoreEnvironment } \def\@RestoreEnvironment#1{% \endgroup \RestoreCommand{#1}% \RestoreCommand{end#1}% } \pdef\UseStored{% \begingroup \MakePrivateLetters \@UseStored} \DeclareCommand\@UseStored \long{% #1 T{+-}% (1) indicator of grouplevel shift (in distiction from an absolute % group level) #2 d % (2) optional grouplevel or shift (0 by default) #3 O{\@gobble}% (3) stuff to be put before the |#4| \CS, e.g., an #4 m % (4) a \CS or csname to be taken from the storage liquid }{% \chgs{2010/06/23 v0.993 added} \endgroup \gmu@SC@setgrouplevel{#1}{#2}% \edef\gmu@SC@grouplevel{% \the\numexpr\gmu@SC@grouplevel+1}% for the first turn of loop % \loop \edef\gmu@SC@grouplevel{% % we decrease the group level number \the\numexpr\gmu@SC@grouplevel-1}% % \edef\gmu@SC@currname{% % define the cs' storage name for that level \gmu@SC@StorageName{#4}{\gmu@SC@grouplevel}}% \ifnum % and check the conjunction of conditions: the group level is >=-1… \unless\ifnum\gmu@SC@grouplevel<-1 1\else 0\fi % and the csname remains not defined. \unless\ifcsname \gmu@SC@currname \endcsname 1\else 0\fi =11 \repeat \gmu@if{csname}{\gmu@SC@currname\endcsname}% {% % ^^A \s how\ExecutingTrueBranch \@XA{#3{#4}}\csname \gmu@SC@currname\endcsname}% first {% % ^^A \s how\ExecutingFalseBranch #3{#4}\@undefined}% second }% of |\@UseStored| \DeclareCommand\RestoreCommand{\Scope d}{% \UseStored #2[\CommandLet #1*]% } \newbox\gmu@smashbox \DeclareCommand\set@smashbox{% \Scope T{hv}{h} }{#1\setbox\gmu@smashbox =\csname #2box\endcsname }% \def\smash@box{\smash{\box\gmu@smashbox}} \newbox\gmu@boxA \newbox\gmu@boxB \newdimen\gmu@dima \newdimen\gmu@dimb \DeclareCommand\gmu@extremebox { #1 m % a dimen register (will be assigned the extr.\ value) or a % \CS (will be defined as |\the| extreme value) #2 T {\min\max}{\max} % kind of extreme #3 T {\wd\ht\dp\totalheight}{\wd} % dimension to compare, the last two for total |\ht|+|\dp|. #4 \lostwax {\global\relax} \eacher{\gmu@dimextreme@step} \lost{\relax} #5 T{\global}{} % scope of assignment }{% \gmu@if x {\max#2} {\gmu@dimb=-\maxdimen \def\gmu@dimextreme@comp{<}% } {\gmu@dimb=\maxdimen \def\gmu@dimextreme@comp{>}% }% % \long \def\gmu@dimextreme@step ##1{% \setbox\gmu@boxA=\hbox{##1}% % \gmu@dima= \gmu@if x {\totalheight#3} {\dimexpr \ht\gmu@boxA +\dp\gmu@boxA\relax} {#3\gmu@boxA}% \relax % \gmu@if {dim} {\gmu@dimb\gmu@dimextreme@comp \gmu@dima } {\gmu@if {dim} {\gmu@dima>\z@} {\gmu@dimb=\gmu@dima } {}% } {}% % }% % #4% \IfIs #1\dimen {#5#1=\gmu@dimb} {#5\edef #1{\the\gmu@dimb }}% }% \pdef\gmu@getht #1% box register #2% dimen (or glue) register to assign the (substitute) height to {% \setbox\gmu@boxA=\copy#1\relax \ifvbox\gmu@boxA \vbadness@M \setbox\gmu@boxB=\vsplit\gmu@boxA to \maxdimen \vbadness@Restore % % chcemy rzeczywiście pomierzyć, a nie być może odrzucić odstępy, % kerny i grzywny. \setbox\gmu@boxB=\vbox{\splitdiscards }% \ifdim \ht\gmu@boxB >\z@ \setbox \gmu@boxA=\vbox{ \unvbox\gmu@boxB \unvbox\gmu@boxA }% \fi \else \setbox\gmu@boxA=\box\voidb@x \fi % \ifvoid\gmu@boxA #2=\ht#1\relax \else #2=\maxdimen \fi }% of |\gmu@getht| \DeclareCommand\enlargefsize{ #1 m % enlargement (dim(expr)) for font size #2 b % enlargement (dim(expr)) for baselineskip (if absent, |#1| is used) }{\edef\gmu@tempa{% \@nx\fontsize{\the\dimexpr\f@size pt+#1}% {\the\dimexpr 1\baselineskip+ \gmuIfValueTF{#2}{#2}{#1}}% }\gmu@tempa\selectfont } \DeclareCommand\scalefsize { #1 m % scale for font size #2 b % scale for baselineskip (if absent, |#1| is used) \gobblespace }{\edef\gmu@tempa{% \@nx\fontsize{\the\dimexpr #1\dimexpr\f@size pt\relax}% {\the\dimexpr \gmuIfValueTF{#2}{#2}{#1}\baselineskip}% }\gmu@tempa\selectfont } \let\gmu@discretionaryhyphen\- % for the cases when we don't redefine % \incs\- but use \incs\UrlFix \DeclareCommand\bihyphen{ O{*} % token that'll make the discretionary hyphen |\-| allow other break-points }{% \DeclareCommand\gmu@discretionaryhyphen{% T{#1}% G{&&}% a }{% \gmuIfValueT{##2}{% \gmu@ifempty{##2}{}{% \def\gmu@bihyphen@char{##2}}% }% \gmuIfValueT{##3}{% \gmu@ifempty{##3}{}{% \def\gmu@bihyphen@corr{##3}}% }% % % Depending on |#1| we allow (if present, then we take |\discre|) % hyphenation of the word's before- and % after-parts or forbid it (if absent, then we take % |\discretionary|). \gmuIfValueTF{##1}\discre\discretionary {% before break \gmuIfValueTF{##2} {% \gmu@ifempty{##2}{\gmu@bihyphen@char}{##2}% }% {% \ifnum\hyphenchar\font>\z@ \char\hyphenchar\font \fi}% }% end of before break {%after break \gmuIfValueT{##3}{% \gmu@ifempty{##3}{\gmu@bihyphen@corr}{##3}% }% }% {% without break }% almost as in \TB: unlike \TB, we allow hyphenchars % $\ge255$ as we are \XeTeX. }% of |\DeclareCommand\-| \gmu@storeifnotyet\-% original |\-| is a~\TeX's % primitive, therefore we should store it. \CommandLet\-\gmu@discretionaryhyphen \CommandLet\@dischyph\gmu@discretionaryhyphen % to override % \pk{framed.sty} \pdef\gmu@flexhyphen{\gmu@discretionaryhyphen#1\relax}% }% of |\bihyphen| \relaxen\gmu@bihyphen@corr \@ifXeTeX{% \DeclareCommand\gmshowlists { >iT{\depth} Ď{1}% >iT{\breadth} Ď{10000000} }% }{% not in \XeTeX\ we use legacy |D| arg.\ specifiers: \DeclareCommand\gmshowlists { >iT{\depth} D{1}% >iT{\breadth} D{10000000} }% } {\tracingonline=\@ne \showboxdepth=#1\relax % how many levels of % box nesting should be shown \showboxbreadth=#2\relax % after how many elements »etc.« will be put \showlists } \DeclareCommand\gmtracingoutput { \SameAs\gmshowlists } {\tracingonline=\@ne \tracingoutput=\@ne \showboxdepth=#1\relax % how many levels of % box nesting should be shown \showboxbreadth=#2\relax % after how many elements »etc.« will be put } \newcount\c@FiBreakPenalty \DeclareCommand \AllowFiBreak {% % The defaults are as in DEK's |\filbreak|. Q{l}{l} = {\c@FiBreakPenalty } } {% \penalty\@M \csname vfi#1\endcsname \penalty \c@FiBreakPenalty \csname vfi#1neg\endcsname } \DeclareCommand \IgnorePars {m Q{\par}} {#1} \DeclareCommand\putpenalty {=} {% \gmu@iflastglue {\@tempskipa=\lastskip \mode@skip -\@tempskipa \penalty \@tempcnta \mode@skip \@tempskipa }% {\gmu@iflastkern {\@temdima=\lastkern \kern-\@temdima \penalty \@tempcnta \kern \@temdima } {% \penalty\@tempcnta }% }% } \newskip \gmu@TrashSkip \pdef \mode@skip {% \ifvmode \vskip \else \ifhmode \hskip \else \ifmmode \mskip \else \gmu@TrashSkip \fi \fi \fi } \endinput %% %% End of file `gmcommand.sty'.