2

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}
\let\MYequation\equation
\let\endMYequation\endequation
\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/1864679\relax cm + #1\baselineskip}%
    \setlength{\protectboxskip}{0.5\@temp@length}%
    \vspace{\protectboxskip}%
    \vspace{-0.3\baselineskip}%
    \par\noindent%
    \begin{minipage}[c][\baselineskip]{\linewidth}%
        \abovedisplayshortskip=0pt%
        \belowdisplayshortskip=0pt%
        \abovedisplayskip=0pt%
        \belowdisplayskip=0pt%
        #2%
    \end{minipage}%
    \vspace{\protectboxskip}%
    \vspace{0.3\baselineskip}%
}
\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.

3
  • It might help readers to know the definition of \protectbox Commented Jul 21, 2020 at 14:42
  • @Segletes Thanks for pointing this out, I've edited my question.
    – Jinwen
    Commented Jul 21, 2020 at 14:46
  • Since in your self-answer you make it clear that the purpose of this approach to alignment to a grid, you may want to add the term "grid" either in your explanation or as a tag, so this can be found by future searchers for that function. Commented Jul 19, 2022 at 19:04

1 Answer 1

1

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}
\NewDocumentCommand\protectbox{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/\baselineskip\relax\baselineskip + #1\baselineskip}%
  }%
  {% Height given
    \setlength{\@temp@length}{#2\baselineskip-\baselineskip}%
  }
  \setlength{\protectboxskip}{0.5\@temp@length}%
  % space above
  \vspace{\parskip}%
  \vspace{\baselineskip}%
  \vspace*{\protectboxskip}%
  \vspace*{-0.2\baselineskip}%
  \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.2\baselineskip}%
}

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

% Redefine equation and equation*
\let\equation\equation
\let\endequation\endequation
\RenewEnviron{equation}{%
\addtocounter{equation}{-1}
\protectbox<0>{%
\begin{equation}%
  \BODY%
\end{equation}}%
\par\noindent%
}
\RenewEnviron{equation*}{%
\protectbox<0>{%
\addtocounter{equation}{-1}
\begin{equation}%
  \st@rredtrue \global\@eqnswfalse%
  \BODY%
\end{equation}}%
\par\noindent%
}

then the \[...\]:

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

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

% Redefine table
% \setlength{\intextsep}{0cm}
\let\FCtable\table
\let\endFCtable\endtable
\RenewEnviron{table}[1][]{%
\addtocounter{table}{-1}%
\FCprotectbox{%
  \def\@captype{table}
  \BODY%
}%
\par\noindent%
}

% Redefine figure
\let\FCfigure\figure
\let\endFCfigure\endfigure
\RenewEnviron{figure}[1][]{%
\addtocounter{figure}{-1}%
\FCprotectbox{%
  \def\@captype{figure}
  \BODY%
}%
\par\noindent%
}

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@safemode\endinput\fi % This have to be pre-defined

% Redefine $$
\global\let\tikz@ensure@dollar@catcode=\relax
\catcode`\$=\active
\protected\def${\@ifnextchar$\@doubledollar\@singledollar}
\def\@doubledollar$#1$${\begin{equation*}#1\end{equation*}}
\def\@singledollar#1${\(#1\)}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .