3

The "equal" key from the tikz-cd package comes with rendering issues on the screen. In particular, they do not look the same on all zoom levels, and sometimes there are grey lines at the beginning or end of the arrow. This may not happen in all PDF readers.

In order to fix this, I would like to replace these arrows with two single arrows. This gets rid of the problem:

\documentclass{standalone}

\usepackage{tikz-cd}

\begin{document}

$
\begin{tikzcd}
    A \arrow[r,equals] & B
\end{tikzcd}
\begin{tikzcd}
    A \arrow[r,dash,shift left=.1em] \arrow[r,dash,shift right=.1em] & B
\end{tikzcd}
$

\end{document}

yielding

where the PNG file was obtained from the LaTeX'ed PDF by

convert -density 300 tikzcd-equals.pdf -quality 100 -background white \
-alpha off tikzcd-equals.png

Questions:

  1. Is this a reasonable approach to fix this problem?

  2. The distance between the two lines is 0.2 em which is just an educated guess. Is there a way to obtain the correct distance for shifting, i.e., half the distance between the two lines in a = in the current font? I know that tikz-cd internally uses the tikz key double equal sign distance, but I do not know how to extract the appropriate dimension for shifting.

  3. How can I make this into a tikz-cd style myequal such that I can simply use A \arrow[r,myequal] & B for the second diagram?

P.S.: This problem has been discussed, but not solved, in the comments of Equalities look “broken” with tikz-cd and “math font”.

3

Well I can answer point 3. It was surprisingly tricky to get this to work, so I may be missing something obvious that would make it easier. The way it works is I define a helper method that finds the source and target positions for an edge from the source node to the target node (this is normally done internally by tikz when you say \draw (nodea)--(nodeb); but tikz doesn't seem to expose this in a useful way). Then I rotate the coordinate system so that the line is drawn in the positive x direction and translate up and down by the appropriate offset.

\documentclass{standalone}

\usepackage{tikz-cd}
\makeatletter

\def\tikzcdequalsignoffset{0.1em}

% This helper macro finds the start and endpoints of a line between the source and target nodes and stores them in \sourcecoordinate and \targetcoordinate.
% #1 -- source node
% #2 -- target node
\def\findedgesourcetarget#1#2{
    \let\sourcecoordinate\pgfutil@empty
    \ifx\tikzcd@startanchor\pgfutil@empty % Check that the source doesn't have a specified anchor
        \def\tempa{\pgfpointanchor{#1}{center}}% if so, start by taking the center of that coordinate
    \else
        \edef\tempa{\noexpand\pgfpointanchor{#1}{\expandafter\@gobble\tikzcd@startanchor}} % If it has an anchor, use that
        \let\sourcecoordinate\tempa
    \fi
    \ifx\tikzcd@endanchor\pgfutil@empty % check that the target doesn't have a specified anchor
        \def\tempb{\pgfpointshapeborder{#2}{\tempa}}% if so, our end point is the point on the boundary of node b that is in the direction of our initial start coordinate
    \else
        \edef\tempb{\noexpand\pgfpointanchor{#2}{\expandafter\@gobble\tikzcd@endanchor}}% If it has a specified anchor, use that
    \fi
    \let\targetcoordinate\tempb
    \ifx\sourcecoordinate\pgfutil@empty%
        \def\sourcecoordinate{\pgfpointshapeborder{#1}{\tempb}}%
    \fi
}

\tikzset{myequal/.style = {
    -,
    to path={\pgfextra{
        \findedgesourcetarget{\tikzcd@ar@start}{\tikzcd@ar@target} % find endpoints
        % Rotate coordinate system so that line goes in x direction
        \ifx\tikzcd@startanchor\pgfutil@empty
            \def\tikzcd@startanchor{.center}
        \fi
        \ifx\tikzcd@endanchor\pgfutil@empty
            \def\tikzcd@endanchor{.center}
        \fi
        \pgfmathanglebetweenpoints{\pgfpointanchor{\tikzcd@ar@start}{\expandafter\@gobble\tikzcd@startanchor}}{\pgfpointanchor{\tikzcd@ar@target}{\expandafter\@gobble\tikzcd@endanchor}}
        \pgftransformrotate{\pgfmathresult}
        % Draw the two lines 
        \pgfpathmoveto{\pgfpointadd{\sourcecoordinate}{\pgfpoint{0}{\tikzcdequalsignoffset}}}
        \pgfpathlineto{\pgfpointadd{\targetcoordinate}{\pgfpoint{0}{\tikzcdequalsignoffset}}}
        \pgfpathmoveto{\pgfpointadd{\sourcecoordinate}{\pgfpoint{0}{-\tikzcdequalsignoffset}}}
        \pgfpathlineto{\pgfpointadd{\targetcoordinate}{\pgfpoint{0}{-\tikzcdequalsignoffset}}}
        \pgfusepath{draw}
}}}}

\makeatother

\begin{document}

\begin{tikzcd}
    A \drar[myequal]\rar[myequal] & B \dar[myequal]\\
    & C
\end{tikzcd}

\end{document}

The output:

enter image description here

3
  • I can confirm that this works as desired. Also, it gives the same result in print, and it compiles just as fast as the standard equal key. Jan 9 '18 at 16:57
  • Although this answers Question 3 only, I chose to accept it because Question 1 probably does not have an ultimate answer, and solving Question 2 would be some sort of bonus to this answer, but not that urgent to me. Jan 9 '18 at 17:00
  • I would argue that this also answers question 1 with a "yes". Jan 9 '18 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.