TransWikia.com

Integrate some macro into math environment

TeX - LaTeX Asked on November 9, 2021

For alignment, I write a macro called protectbox, the core part of it is a minipage environment. And now every time I write a displayed equation, I have to type:

protectbox{%
    [ ... ]
}

However, sometimes I would like to typeset other .tex file using my .cls style, and I don’t want to manually add protectbox to each equation. Thus I begin to think of integrate this macro into the math macro. For equation and equation*, it really worked:

RequirePackage{amsmath}
RequirePackage{environ}
letMYequationequation
letendMYequationendequation
RenewEnviron{equation}{%
protectbox[-1]{%
begin{MYequation}%
    BODY%
end{MYequation}}%
}
makeatletter
RenewEnviron{equation*}{%
protectbox[-1]{%
begin{MYequation}%
    st@rredtrue global@eqnswfalse% this is copied from amsmath.sty
    BODY%
end{MYequation}}%
}
makeatother

Unfortunately, this will cause an error for [ ...] (the .log file says it’s an "emergency stop" without further detail).

Also, since many equations come from markdown quick notes, formatting in $$ ... $$, I would like to integrate protectbox into $$ ... $$. But if I do so unproperly, tikz will throw an error:

Package tikz: Sorry, some package has redefined the meaning of the math-mode dollar sign. This is incompatible with tikz and its calc library and might cause unrecoverable errors.

Thus I’m here to ask you. I know it is kind of ugly and dangerous, but for sure, is there any way to realize this kind of integration, i.e. plug the protectbox macro into [...], $$...$$, equation, equation* without causing serious error?


P.S. Here is the current definition of protectbox:

RequirePackage{calc}
makeatletter
newlength{@temp@length}
newcommand{protectbox}[2][0]{% the first parameter is an offset of length, the second is the content
    % measure the height of contents
    setbox0=vbox{%
        abovedisplayshortskip=0pt%
        belowdisplayshortskip=0pt%
        abovedisplayskip=0pt%
        belowdisplayskip=0pt%
        #2}%
    @temp@length=ht0 advance@temp@length by dp0%
    % calculate the number of lines needed to place the content
    setlength{@temp@length}{numexpr@temp@length/1864679relax cm + #1baselineskip}%
    setlength{protectboxskip}{0.5@temp@length}%
    vspace{protectboxskip}%
    vspace{-0.3baselineskip}%
    parnoindent%
    begin{minipage}[c][baselineskip]{linewidth}%
        abovedisplayshortskip=0pt%
        belowdisplayshortskip=0pt%
        abovedisplayskip=0pt%
        belowdisplayskip=0pt%
        #2%
    end{minipage}%
    vspace{protectboxskip}%
    vspace{0.3baselineskip}%
}
makeatother

I’ve actually asked this question in my original question, but the original one focused on line spacing, and the problem on mathematical environment was submerged in the long text, thus was not very clearly presented.

One Answer

Well, I can answer my own question now.

Recall that the meaning of this question is to achieve the following notepaper effect: enter image description here


Here's how it works.

First, define a protectbox to calculate the height of content (or manually given the height) and make it into a integer multiple of baselineskip, so that the text follows stay right on the line.

% protectbox<optional, space ajust>{optional, height}{content}
newlength{protectboxskip}
NewDocumentCommandprotectbox{D<>{0}om}
{
  IfNoValueTF{#2}%
  {% Height not given
    % measure the height
    setbox0=vbox{%
    abovedisplayshortskip=0pt%
    belowdisplayshortskip=0pt%
    abovedisplayskip=0pt%
    belowdisplayskip=0pt%
    #3}%
    @temp@length=ht0 advance@temp@length by dp0%
    % assign the height
    setlength{@temp@length}{numexpr@temp@length/baselineskiprelaxbaselineskip + #1baselineskip}%
  }%
  {% Height given
    setlength{@temp@length}{#2baselineskip-baselineskip}%
  }
  setlength{protectboxskip}{0.5@temp@length}%
  % space above
  vspace{parskip}%
  vspace{baselineskip}%
  vspace*{protectboxskip}%
  vspace*{-0.2baselineskip}%
  vspace{-parskip}%
  vspace{-baselineskip}%
  par%
  noindent%
  % the content
  begin{minipage}[c][baselineskip]{linewidth}%
  abovedisplayshortskip=0pt%
  belowdisplayshortskip=0pt%
  abovedisplayskip=0pt%
  belowdisplayskip=0pt%
  #3%
  end{minipage}%
  % space after
  vspace{protectboxskip}%
  vspace{0.2baselineskip}%
}

The next step is integrate this macro into other command or environment, such as equation, table, figure... Begin with equation

% Redefine equation and equation*
letequationequation
letendequationendequation
RenewEnviron{equation}{%
addtocounter{equation}{-1}
protectbox<0>{%
begin{equation}%
  BODY%
end{equation}}%
parnoindent%
}
RenewEnviron{equation*}{%
protectbox<0>{%
addtocounter{equation}{-1}
begin{equation}%
  st@rredtrue global@eqnswfalse%
  BODY%
end{equation}}%
parnoindent%
}

then the [...]:

% Redefine [...]
def[#1]{begin{equation*}#1end{equation*}}

and also table and figure (for the alignment, we would have to make it non-float):

% Redefine table
% setlength{intextsep}{0cm}
letFCtabletable
letendFCtableendtable
RenewEnviron{table}[1][]{%
addtocounter{table}{-1}%
FCprotectbox{%
  def@captype{table}
  BODY%
}%
parnoindent%
}

% Redefine figure
letFCfigurefigure
letendFCfigureendfigure
RenewEnviron{figure}[1][]{%
addtocounter{figure}{-1}%
FCprotectbox{%
  def@captype{figure}
  BODY%
}%
parnoindent%
}

Finally, it is posible to redefine $$, but it is not safe to de so as it may cause error when using tikz and its calc library. I personally defined an option safemode and leave this re-definition below:

if@safemodeendinputfi % This have to be pre-defined

% Redefine $$
globallettikz@ensure@dollar@catcode=relax
catcode`$=active
protecteddef${@ifnextchar$@doubledollar@singledollar}
def@doubledollar$#1$${begin{equation*}#1end{equation*}}
def@singledollar#1${(#1)}

Answered by Jinwen on November 9, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP