3

I would like to change the default behaviour of limits to include \mathclap.

Rather than writing every time

\int\limits_{\mathclap{verylonglimit}} x \, dx

I would like to simply write

\int\limits_{verylonglimit} x \, dx

and to get the same behaviour.

I tried with (and similar forms) of:

\let\oldlimits\limits
\renewcommand{\limits_}[1]{\oldlimits_{\mathclap{#1}}}

The problem is that I do not know how to deal with the underscore.

Mico
  • 506,678
  • you should almost never need to use explicit \limits in a document – David Carlisle Jun 03 '15 at 16:49
  • 2
    If you redefine \limits you will redefine \stackrel, \buildrel, \doteq and any other command that uses \limits internally. – David Carlisle Jun 03 '15 at 16:52
  • 1
    What about \int_{\mathclap{verylonglimit}}\frac{1}{x}\,dx? – egreg Jun 03 '15 at 16:52
  • 1
    Two comments. (a) If you always need to place the lower (and upper) limits of integration above and below the integral symbol, you should load the amsmath (or mathtools) package with the option intlimits. (b) If typing \mathclap frequently is too tedious, just create a shortcut named, say, \mc to ease the job. – Mico Jun 03 '15 at 17:01
  • @Mico I know the intlimits option, but I still have to write every time the \mathclap part. Do you think the best option is to redefine and to use the shorthand? @DavidCarlisle do you mean the same as @Mico? And yes, that redefine could be a problem. @egreg still the same as @Mico? And in that case by using big integrands I could be in danger of an overlap between limits and integrands. In general, is it possible to redefine a command comprising the underscore? – Alex Pacini Jun 03 '15 at 17:08
  • 1
    Depending on just how "tall" the integrand is, you may want to use a "big" (more precisely, a bigger than normal) integral symbol as well. See the posting Big integral sign for more information on how to generate large integral symbols. – Mico Jun 03 '15 at 17:21
  • If you use xparse you can use the code from this answer to have \let\originalint\int \NewDocumentCommand\int{b}{\originalint\limits\IfValueT{#2}{_{\mathclap{#2}}}} and then use \int_{whatever} to act as \int\limits_{\mathclap{whatever}} (while you don't need to always input limits \int f(x) \, dt would also work. – Manuel Jun 03 '15 at 19:45

2 Answers2

3

Rather than redefine \limits -- which has the potential to cause lots of grief elsewhere in your document -- I'd like to suggest you define a new command called, say, \mclimits (short for "mathclap limits"...) as follows:

\def\mclimits_#1{\limits_{\mathclap{#1}}}

Note that with this definition, any use of \mclimits that doesn't employ the _ character will result in a syntax error, as TeX will be scanning the input material for this character in order to "know" what's supposed to be macro's argument (the "#1" part). This constraint shouldn't be a problem in practice, since you'll want to use the _ character in order to indicate the start of the material that should be placed in the lower-limit part of the full integral expression.

Here's the output of an MWE that uses the macro \mclimits:

enter image description here

\documentclass{article}
\usepackage{mathtools}

\def\mclimits_#1{\limits_{\mathclap{#1}}}

\begin{document}
\[
\int\mclimits_{\text{verylonglimit}}\! f(x)\,dx
\]
\end{document}
Mico
  • 506,678
  • Leaving the issues obtained by redefining limits, my problem was to deal with the underscore. I tried using def instead of renewcommand as in \let\oldlimits\limits \def\limits_#1{\oldlimits_{\mathclap{#1}}} and it works. What I am missing? Thinking to the possible side-effects, yes you are right, better to use a shorthand. – Alex Pacini Jun 03 '15 at 17:20
  • 1
    @Alex - With the TeX directive \def, it's possible to create a so-called "argument-delimited" macro, i.e., a macro whose argument is delimited by a specific symbol (such as _). Note that it's not possible (or, at least, not as easily possible) to do this with the LaTeX directives \newcommand and \renewcommand. – Mico Jun 03 '15 at 17:23
  • I was not aware of that "argument-delimited" macro. Good to know (I should learn some more TeX). Thank you! – Alex Pacini Jun 03 '15 at 17:26
  • 2
    yes, this is the sensible approach. but it could get you in big trouble if the expression with limits starts with two integral signs with separate lower limits. in other words, it's not a "technique for all seasons". – barbara beeton Jun 03 '15 at 17:30
  • @barbarabeeton - I didn't claim it was a "technique for all seasons", did I? :-) For sure, if either two consecutive integrals with lots of text in the lower limit or a very tall integrand occurs, the method will need to be adjusted. – Mico Jun 03 '15 at 17:31
  • 1
    @Mico -- no, you didn't claim that. (and i know that you wouldn't do it.) but too often i've seen techniques meant for a "local" fix be (mis)used in situations where they weren't appropriate. so i get rather touchy on the subject. – barbara beeton Jun 03 '15 at 18:08
  • 2
    @Alex after a definition such as \def\limits_#1{..} then any use of \limits (including existing commands that use it internally) that is not followed by _ is a syntax error. – David Carlisle Jun 03 '15 at 18:37
  • @DavidCarlisle - Nicely put! I will add a sentence in my answer to stress the importance of not omitting _ when using \mclimits. – Mico Jun 03 '15 at 18:40
  • @Mico yes although it's less of an issue for a new command of course, more of a danger if used with an existing one such as \limits – David Carlisle Jun 03 '15 at 18:47
  • @DavidCarlisle I do not know If I got it clearly: by doing \def\limits_#1{..} can I only use \limits_ while \limits has disappared? Thus, does redefining a macro using the same macro with the underscore make the original macro without the underscore disappear? – Alex Pacini Jun 03 '15 at 18:57
  • 1
    @Alex - The issue with redefining a macro (say, \limits, which doesn't take an argument by default) to take an argument and to include _ as an argument delimiter is not that the macro itself somehow "disappears". Instead, it's the redefinition itself that may cause trouble. There are some useful LaTeX macros out there -- e.g., \stackrel and \buildrel -- that use \limits internally but don't use _ -- and don't expect \limits to take an argument. If you redefine \limits, these macros will throw a syntax error, and it'll likely take you a long time to figure out the cause. – Mico Jun 03 '15 at 19:13
  • 2
    @Alex \def\limits_ does not define a macro with name limits_ it redefines the command with name limits such that it has to be followed by _ so \limits_{1} would be OK as would \limits _ {1} but \limits^{1} is an error. – David Carlisle Jun 03 '15 at 19:14
1

This might seem like an overkill… but that's how xparse works.

With the “complex code” what I do is define new type of xparse arguments, k, K, a, b, A, B. Being a and A the correspondent to subscripts. The others are explained here

\documentclass{scrartcl}
\usepackage{mathtools,amssymb,xparse}

\ExplSyntaxOn
\cs_new_protected:Npn \__xparse_count_type_k:w #1
 {
  \__xparse_single_token_check:n { #1 }
  \quark_if_recursion_tail_stop_do:Nn #1 { \__xparse_bad_arg_spec:wn }
  \__xparse_count_mandatory:N
 }
\cs_new_protected:Npn \__xparse_count_type_K:w #1 #2
 {
  \__xparse_single_token_check:n { #1 }
  \quark_if_recursion_tail_stop_do:nn { #2 } { \__xparse_bad_arg_spec:wn }
  \__xparse_count_mandatory:N
 }
\cs_new_protected:Npn \__xparse_add_type_k:w #1
 { \exp_args:NNo \__xparse_add_type_K:w #1 { \c__xparse_no_value_tl } }
\cs_new_protected:Npn \__xparse_add_type_K:w #1 #2
 {
  \__xparse_flush_m_args:
  \__xparse_add_grabber_optional:N K
  \tl_put_right:Nn \l__xparse_signature_tl { #1 { #2 } }
  \__xparse_prepare_signature:N
 }
\cs_new_protected:Npn \__xparse_add_expandable_type_k:w #1
 {
  \exp_args:NNo \__xparse_add_expandable_type_K:w #1 { \c__xparse_no_value_tl }
 }
\cs_new_protected_nopar:Npn \__xparse_add_expandable_type_K:w #1 #2
 {
  \__msg_kernel_error:nnx { xparse } { invalid-expandable-argument-type } { K }
  \__xparse_add_expandable_type_m:w % May be create this?
 }
\cs_new_protected:Npn \__xparse_grab_K:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected_nopar:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_long:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_trailing:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected_nopar:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_long_trailing:w #1 #2 #3 \l__xparse_args_tl
 {
  \__xparse_grab_K_aux:NnnNn #1 { #2 } { #3 } \cs_set_protected:Npn
   { _ignore_spaces }
 }
\cs_new_protected:Npn \__xparse_grab_K_aux:NnnNn #1 #2 #3 #4 #5
 {
  \exp_after:wN #4 \l__xparse_fn_tl ##1
   {
    \__xparse_add_arg:n { ##1 }
    #3 \l__xparse_args_tl
   }    
  \use:c { peek_meaning_remove #5 :NTF } #1
   { \l__xparse_fn_tl }
   {
    \__xparse_add_arg:n { #2 }
    #3 \l__xparse_args_tl
   }
 }

\prop_put:Nnn \c__xparse_shorthands_prop { a } { k \sb }
\prop_put:Nnn \c__xparse_shorthands_prop { b } { k \sp }
\prop_put:Nnn \c__xparse_shorthands_prop { A } { K \sb }
\prop_put:Nnn \c__xparse_shorthands_prop { B } { K \sp }
\ExplSyntaxOff

\let\originalint\int
\RenewDocumentCommand\int{ t\limits a }
 {\originalint\IfBooleanT{#1}{\limits}\IfValueT{#2}{_{\mathclap{#2}}}}

\begin{document}
\[
  \int\limits_{verylonglimit} x \, dx
\]
\end{document}

enter image description here

I redefine the \int command first to gobble (and use) any \limits following it (if you want a different behaviour it can be changed, for instance if you want all of them to have \limits so \int_a would equal \int\limits_{\mathclap{a}}) then the command checks if there's a subscript like _{whatever} then pases whatever as second argument, we then pass it through a _{\mathclap{#2}} automatically.

Manuel
  • 27,118