Tag Info

Hot answers tagged

21

Not sure why ^^J is a problem, isn't it only special as \newlinechar when stuff is being used in \write ? \documentclass{article} \def\zz{aaa^^Jbbb \foo ccc} \def\patchzz#1\foo#2\zzz{\def\zz{#1\bar#2}} \show\zz \expandafter\patchzz\zz\zzz \show\zz \stop ah if \patchcmd uses \scantokens that is a write, so you probably just want to locally reset ...


19

The etoolbox manual states for \ifstrequal on page 17: (emphasis mine) Compares two strings and executes ⟨true⟩ if they are equal, and ⟨false⟩ otherwise. The strings are not expanded in the test and the comparison is category code agnostic. So you always compare the string “\ab{}” with “a” and “b”. If you want to allow macros as input you need to ...


19

You can get \\foo@ using \csname\string\foo@\endcsname. The space shown behind it with \show is not part of the macro name (but could be added using a \space before \endcsname). So you can use: \expandafter\patchcmd\csname\string\foo@\endcsname{hook}{\label{#1}hook}{success}{failure} Full example: \documentclass{article} \usepackage{etoolbox} ...


19

NOTE: There are some minor weaknesses in the code shown below, so it's best to use the corresponding package. The following macros define the commands \xpatchcmd, \xpretocmd and \xapptocmd that recognize robust commands (defined by \DeclareRobustCommand or \newrobustcmd) and also if they have an optional argument. \usepackage{etoolbox,xparse} ...


19

You can use the logical combination and and or in the test \ifboolexpr \ifboolexpr{% test {\ifnumless{a}{b}} and test{\ifnumgreater{x}{100}} }{YES}{NO} For more details see the documentation (section 3.6.5). I want to show an example. \documentclass{article} \usepackage{etoolbox} \newcounter{a}\newcounter{b}\newcounter{x} ...


19

For example something like this: \long\def\for#1in#2#3{\expandafter\def\csname b:\string#1\endcsname{#3}% \forinA#1#2,,} \def\forinA#1#2,{\ifx,#2,\else \def#1{#2}\csname b:\string#1\endcsname \expandafter\forinA\expandafter#1\fi} \for\i in{a, bc, d} {% \for\j in{A, B, C} {% i=\i, j=\j;\par } }


18

The answer to this is specified in the etoolbox documentation under section 3.5 Boolean Flags (p 12 onward): 3.5.1 TeX Flags Since the tools in this section are based on \newif internally, they may be used to test and alter the state of flags previously defined with \newif. They are also compatible with the boolean tests of the ifthen package and may ...


18

\ifodd is enough to do this \documentclass[]{scrartcl} \newcount\myint \def\IsFourMultiple#1{% \myint#1\relax \ifodd\myint false \else \divide\myint by2\relax \ifodd\myint false \else true \fi \fi}% \begin{document} \IsFourMultiple{4} \IsFourMultiple{32} \IsFourMultiple{15} \end{document}


17

If you need repeated access to arbitrary items then an "array" of command names \mylist1, \mylist2\ ... might be more suitable than a list. \documentclass{minimal} \usepackage{etoolbox} \newcounter{mylistcounter} \def\saveitem#1{% \stepcounter{mylistcounter}% \expandafter\def\csname mylist\themylistcounter\endcsname{#1}} \forcsvlist{\saveitem}{% ...


17

\newbool{mybool} is almost the same as \newif, but it checks whether \ifmybool is already defined, which LaTeX doesn't: \newrobustcmd*{\newbool}[1]{% \expandafter\@ifdefinable\csname if#1\endcsname{% \expandafter\newif\csname if#1\endcsname}} There's also \providebool which does nothing if the conditional is already defined. Similarly, \ifbool is a ...


15

With \def\myrelax{\relax} macro \myrelax is a parameterless macro with replacment text \relax. You get a command sequence with meaning \relax with \let: \let\myrelax\relax Also \def\myemptyempty{\myempty} defines a parameterless macro \myemptyempty that is not empty, whose replacement text is \myemptyempty. There is \edef that expands the replacement text ...


15

\makeatletter \def\act@on@bibmacro#1#2{% \expandafter#1\csname abx@macro@\detokenize{#2}\endcsname} \def\patchbibmacro{\act@on@bibmacro\patchcmd} \def\pretobibmacro{\act@on@bibmacro\pretocmd} \def\apptobibmacro{\act@on@bibmacro\apptocmd} \def\showbibmacro{\act@on@bibmacro\show} \makeatother Now you have available \patchbibmacro \pretobibmacro ...


15

You can use pgfmath for this: \documentclass{article} \usepackage{pgf} \begin{document} \newcommand\ifismultiple[4]{% \pgfmathparse{mod(#1,#2)==0} \ifnum \pgfmathresult=1 #3% \else #4% \fi } \ifismultiple{15}{4}{true}{false} \end{document}


15

A kind of "switchcase" can be easily programmes: \documentclass{article} \makeatletter \def\ifnumcase#1{% \edef\elseif@{\string\elseif}\edef\endif@{\string\endif}% \def\number@test{#1pt}\ifnumcase@i} \def\ifnumcase@i#1{% \def\ifnumcase@ii##1{% \csname @\ifdim\number@test#1pt first\else second\fi oftwo% ...


14

With eTeX's \numexpr, you can do that easily. \makeatletter \newcommand{\doifmultipleof}[2]{% \ifnum\numexpr((#2)/(#1))*(#1)-(#2)=0 \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi} \makeatother \documentclass{article} \begin{document} \doifmultipleof{4} {6}{true}{false} % => false \doifmultipleof{5}{10}{true}{false} % ...


14

Just for future reference, expl3 has nice switch/case statement constructs: \str_case:nnF {\doctype} { {SomeString1} {some~ text~ here} {SomeString2} {some~ different~ text~ here} } {else~ clause} Variations are also provided with integers, dimensions, and token lists; e.g., \int_case:nnF{2*5}{ {5}{Small} {4+6}{Medium} {-2*10}{Negative} ...


14

There are a few reasons why defining document commands has always been done using the control sequence for the command (\foo) rather than the control sequence name (foo). Of course, some of this comes down to 'you'd have to ask Leslie Lamport or Don Knuth', as it follows from the TeX basics. (For example, \newcommand\foo mirrors \def\foo, and ...


14

mathtools loads the calc package, which change the \setcounter command. You now have to protect it too: \addtocontents{toc}{\protect\ifbool{shorttoc}{\protect\setcounter{tocdepth}{0}}{}}


14

The evaluation is not lazy, revealed by scanning the .log when tracing the macro expansions: %\begingroup \tracingmacros1 \ifboolexpr{ bool{testA} or bool{testB} }{OK}{Something's wrong...} %\endgroup That is, a complete evaluation of bool{testA} is followed by an equivalent evaluation of bool{testB}, followed by an evaluation of or, to output ...


13

You have an end-of-line character after the opening { which causes a space. It might be better to check if the argument is a single space instead of being empty. You can add one space to the argument yourself to make sure the test is true for a real empty content. Also you should add % after any { or } at the end of a line inside the macro definition. ...


13

If you can use luatex, then the comparison can be easily done at the lua end. Here is a ConTeXt solution (using named macro arguments): % macros=mkvi \def\doifmultipleof#{mod}#{num}% {\ctxcommand{doifelse(math.mod(#{num}, #{mod}) == 0)}} \starttext \dorecurse{10} {\doifmultipleof{4}{\recurselevel}{yes}{no}} \stoptext


13

A lot of hyperref stuff is loaded a the start of the document. Our code compile on my system if I make this change to it \AtBeginDocument{\let\textlabel\label}% Then it seem to get the proper textual \label stored.


13

I replaced your if-if-if-if construct with a simple \ifcase test. \moon works just fine now. Though the actual problem was another one. The counter assignments \global\advance\<counter> by 1 should be finished with a \relax. This also applies to the \ifnum but in this instance, it is not needed as math-mode is introduces right away. Without the \relax ...


12

As always with (La)TeX: If you know what you are doing you are allowed to do it! Some local counter changes make perfectly sense, like in the example in the question. However I wouldn't call secnumdepth a real counter. After all it is never incremented. Here simply a counter register was used to store an integer because there is no other suitable type. Real ...


12

Thanks to egreg for pointing me to TeX by Topic. Here's the relevant quote (p. 275): Quantities that are assigned to inside a group must be restored after the end of that group. The save stack is where the values to be restored are kept; the size of the save stack limits the number of values that can be restored. Alternating global and local ...


12

From your description, I think you want \ifdefstring, as you need to compare one macro with one definition of a macro. \ifdefequal is for testing two macros for equivalence.


12

If you add \tracingpatches to the preamble you find the answer in the log: [debug] tracing \patchcmd on input line 14 [debug] analyzing '\abc' [debug] ++ control sequence is defined [debug] ++ control sequence is a macro [debug] -- nested patching command and parameters in patch [debug] -> the patching command seems to be nested in the [debug] ...


12

Some ideas with expl3: \documentclass{article} \usepackage{amsmath} \usepackage{xparse} \ExplSyntaxOn \NewDocumentCommand{\doublelist}{m+O{}mO{}m} {% #1 = first list, #2 = code to execute at the end of the inner cycle % #3 = second list, #4 = code to execute between elements in the inner cycle % #5 = two argument macro to which items are passed ...


11

This shows one way how to use a nested loop with etoolbox \forlistloop has two parameters: The second one is the list name, the first one is a list processor, i.e. what is to be done inside the loop. The best idea is to use a \newcommand macro which is expandable. This list processing macro can have a 'arbitrary' number of arguments, but the last one is ...


11

One of the last things the figure enviroment does is issuing the internal command \@floatboxreset whose definition is \def\@floatboxreset{% \reset@font \normalsize \@setminipage } and this is why the \smaller declaration has no effect, because the tokens in \AtBeginEnvironment are found earlier. You should instead change the meaning of ...



Only top voted, non community-wiki answers of a minimum length are eligible