3

When for example collecting terms in writing out an expression, it is often useful to indicate what terms are similar by drawing lines between them. Take for example

\documentclass{article}
\begin{document}
\[(a+b)(a+b)-(a+b)(a-b)=aa+ab+ba+bb-(aa-ab+ba-bb)=2ab+2bb.\]
\end{document}

enter image description here

This would be a lot easier to read with the following lines:

enter image description here

Is there a way of doing this in LaTeX (the only thing that comes to mind is editing the shape of \underbrace and \overbrace, but that doesn't seem best practice)?

Betohaku
  • 1,637

2 Answers2

4

You can use the tikzmark library from TikZ (compile twice so the lines reach their final position):

enter image description here

The code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\newcommand\JoinUp[4][10pt]{
\draw
  ([shift={#2}]pic cs:start#4) -- ++(0pt,#1) -| ([shift={(#3)}]pic cs:end#4);
}
\newcommand\JoinDown[4][10pt]{
\draw
  ([shift={#2}]pic cs:start#4) -- ++(0pt,-#1) -| ([shift={(#3)}]pic cs:end#4);
}

\begin{document}

\[
(a+b)(a+b)-(a+b)(a-b)=
\tikzmark{starta}aa+\tikzmark{startc}ab+\tikzmark{endc}ba+
\tikzmark{startd}bb-(\tikzmark{enda}aa-\tikzmark{startb}ab+
\tikzmark{endb}ba-\tikzmark{endd}bb)=2ab+2bb.
\]

\begin{tikzpicture}[remember picture,overlay,line width=1.5pt]
\JoinUp{(6pt,10pt)}{(6pt,10pt)}{a}
\JoinUp{(5pt,10pt)}{(5pt,10pt)}{b}
\JoinDown{(5pt,-2pt)}{(5pt,-2pt)}{c}
\JoinDown{(5pt,-2pt)}{(5pt,-2pt)}{d}
\end{tikzpicture}

\end{document}
Gonzalo Medina
  • 505,128
1

A small addition to Gonzalo's answer.

Just to cut down on the typing and making the whole thing scale with the font size of the document, I figured it would be nice to incorporate the answer to Get current font size as length and make every size scale accordingly:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{tikzmark}

\newlength{\mytextsize}
\makeatletter
      \setlength{\mytextsize}{\f@size pt}
\makeatother

\newcommand{\JoinUp}[5]{\begin{tikzpicture}[remember picture,overlay,line width=0.05\mytextsize]
    \draw([shift={(#1\mytextsize,#2\mytextsize)}]pic cs:start#5) -- ++(0pt,0.7\mytextsize) -| ([shift={(#3\mytextsize,#4\mytextsize)}]pic cs:end#5);
    \end{tikzpicture}}
\newcommand{\JoinDown}[5]{\begin{tikzpicture}[remember picture,overlay,line width=0.05\mytextsize]
    \draw([shift={(#1\mytextsize,#2\mytextsize)}]pic cs:start#5) -- ++(0pt,-0.7\mytextsize) -| ([shift={(#3\mytextsize,#4\mytextsize)}]pic cs:end#5);
    \end{tikzpicture}}

\begin{document}
\[(a+b)(a+b)-(a+b)(a-b)=\tikzmark{starta}aa+\tikzmark{startc}ab+\tikzmark{endc}ba+\tikzmark{startd}bb-(\tikzmark{enda}aa-\tikzmark{startb}ab+\tikzmark{endb}ba-\tikzmark{endd}bb)=2ab+2bb.\]
\JoinUp{0.5}{1}{0.5}{1}{a}
\JoinUp{0.5}{1}{0.5}{1}{b}
\JoinDown{0.5}{-0.4}{0.5}{-0.4}{c}
\JoinDown{0.5}{-0.4}{0.5}{-0.4}{d}
\end{document}

Output

This changes the \JoinUp and \JoinDown commands a little, as the displacements are now given in terms of the font size.

Note: this does not scale with the local font size, as the \mytextsize length is defined in the preamble.

Betohaku
  • 1,637