4

At first I thought this was a problem of my pdf viewer. For example, with the code

\documentclass{article}
\usepackage{tikz-cd}
\begin{document}

\begin{tikzcd} A & B \arrow[Rightarrow, from=1-1, to=1-2] \end{tikzcd}

\end{document}

The resulting Rightarrow seems to contain two small extra gray lines:

enter image description here

The problem has been addressed in this question a few months ago, where the author provided a complicated new style nRightarrow which appears to fix the problem (Rightarrow above, nRightarrow below):

enter image description here

However, the need for this new style nRightarrow mainly seems to come from other more complicated issues. Thus I would like to know that just for the problem of these two extra gray lines, is there an existing simpler solution by now?

Below is a MWE, in which I have copied the code of nRightarrow from the linked question.

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{calc}

\newlength{\eqoffset} \makeatletter % relative coordinates: (0,0) is the arrow's tail, x points towards the head, % y points perpendicular, unit distance is \eqoffset \newcommand{\relptstart}[2]{($($(k0)!#1\eqoffset+\pgf@shorten@start@additional!0:(k1)$)!#2\eqoffset!90:(k1)$)} % (0,0) is the arrow's tip, rest is the same \newcommand{\relptend}[2]{($($(k1)!#1\eqoffset-\pgf@shorten@end@additional -2\eqoffset-.5\pgflinewidth!180:(k0)$)!#2\eqoffset!-90:(k0)$)} \tikzcdset{ nRightarrow/.style={line join=round, no head, /tikz/commutative diagrams/@shiftabletopath, execute at begin to = { % Do not use tikzcd@noda or tikzcd@x here, it causes interference. % Use new names instead \path (\tikztostart) -- (\tikztotarget) coordinate[pos=0] (k0) coordinate[pos=1] (k1); \pgfpointnormalised{\pgfpointdiff{\pgfpointanchor{k1}{center}}{\pgfpointanchor{k0}{center}}} \pgfgetlastxy{\kdx}{\kdy} \tikzset{ to path={ % arrow body % the .06 is from \pgftransformxshift{.06\pgfutil@tempdima} \relptstart{0}{1} -- \relptend{-.06}{1} { % correct vertical position, more central horizontal position % [xshift=-\kdy\eqoffset, yshift=\kdx\eqoffset] % matches original Rightarrow more closely [xshift=-\kdy\eqoffset-\kdx(\eqoffset+.25\pgflinewidth), yshift=\kdx\eqoffset-\kdy(\eqoffset+.25\pgflinewidth)] \tikztonodes} \relptstart{0}{-1} -- \relptend{-.06}{-1} % arrow tip % fake the round cap by using round joins and drawing the path twice with a turnaround at the caps \relptend{2}{0} % tip to top end .. controls \relptend{1}{0.05} and \relptend{-0.75}{1.25} .. \relptend{-1.4}{2.65} % top end back to tip .. controls \relptend{-0.75}{1.25} and \relptend{1}{0.05} .. \relptend{2}{0} % tip to bottom end .. controls \relptend{1}{-0.05} and \relptend{-0.75}{-1.25} .. \relptend{-1.4}{-2.65} % bottom end back to tip .. controls \relptend{-0.75}{-1.25} and \relptend{1}{-0.05} .. \relptend{2}{0} % Add a degenerate path segment at the end so shorten < and shorten > are not applied again (k1) }} }} } \setlength{\eqoffset}{.225ex} \makeatother

\begin{document}

\begin{tikzcd}[column sep=large] A & B \arrow[Rightarrow, from=1-1, to=1-2] \end{tikzcd}

\begin{tikzcd}[column sep=large] A & B \arrow[nRightarrow, from=1-1, to=1-2] \end{tikzcd}

\end{document}

Jinwen
  • 8,518

3 Answers3

6

The linked question spanwed off a lengthy discussion with the author of TikZ-CD on how to re-implement parallel lines. The code seems to be almost finished on a PGF level.

Short of reimplementing the way PGF draws double lines here is a proof of concept on how to slightly alter the way PGF draws the double lines

  • either by lengthening the inner line
  • or by shortening the outer line.

This is far from perfect but works best for

  • straight lines
  • that consists of one segment (only one move to at the start),
  • aren't dashed and use the normal rect line cap.

In addition it'd be best if the arrows don't touch drawn nodes.

The spath3 library could help in making the (un)shortening not distort the curve and could also help in applying this to paths that have more than one segment.

Code

\documentclass[tikz]{standalone}
\usepackage{tikz-cd}
\makeatletter
\def\pgf@double@cheat#1{%
  \let\pgf@tips@mode\pgf@tips@mode@false
  \pgfsetarrowsstart{}\pgfsetarrowsend{}%
  \pgfsetshortenstart{#1}\pgfsetshortenend{#1}%
  \pgf@prepare@end@of@path\pgf@prepare@start@of@path}
\pgfset{
  shorten outer/.code=%
    \pgfmathsetlength\pgfutil@tempdima{#1}%
    \pgfkeyssetevalue{/pgf/shorten outer}{\the\pgfutil@tempdima},
  shorten outer=+0pt,
  unshorten inner/.code=%
    \pgfmathsetlength\pgfutil@tempdima{#1}%
    \pgfkeyssetevalue{/pgf/unshorten inner}{\the\pgfutil@tempdima},
  unshorten inner=+0pt}
\usepackage{etoolbox}
\patchcmd{\pgf@stroke@inner@line}{\pgfsyssoftpath@invokecurrentpath}{%
    \ifdim\pgfkeysvalueof{/pgf/unshorten inner}>0pt
      \pgf@double@cheat{-\pgfkeysvalueof{/pgf/unshorten inner}}%
    \fi\pgfsyssoftpath@invokecurrentpath}{}{\PatchFailed}

\patchcmd{\pgfusepath}{\fi\pgfsyssoftpath@invokecurrentpath\pgf@up@action}{% \fi \ifdim\pgfinnerlinewidth>0pt \ifdim\pgfkeysvalueof{/pgf/shorten outer}>0pt \pgfgetpath\pgf@temppath \pgf@double@cheat{\pgfkeysvalueof{/pgf/shorten outer}}\fi\fi \pgfsyssoftpath@invokecurrentpath% \ifdim\pgfinnerlinewidth>0pt \ifdim\pgfkeysvalueof{/pgf/shorten outer}>0pt \pgfsetpath\pgf@temppath\fi\fi\pgf@up@action}{}{\PatchFailed} \makeatother \newcommand*\everycell[1]{% \draw[cd=Rightarrow,#1]node(A){$A$}node(B)at(2,0){$B$}(A)to(B);} \begin{document} \tikz[ cd/.code=\tikzcdset{#1}, anchor=base, cd dbl/.style={cd={background color=green}}, cells={nodes={behind path, help lines, draw, shape=asymmetrical rectangle}}, column 1/.append style={anchor=base west, nodes=path only}, rows/.style args={#1 => #2}{row #1/.append style={#2}}, rows/.list={2 => unshorten inner = .05pt, 3 => shorten outer = .05pt, 4 => {cd dbl=green, unshorten inner = 2pt}, 5 => {cd dbl=green, shorten outer = 2pt}} ]\matrix[column sep=\tabcolsep]{ \node{normal:}; & \everycell{} & \everycell{bend left} \ \node{inner:}; & \everycell{} & \everycell{bend left} \ \node{outer:}; & \everycell{} & \everycell{bend left} \ \node{extreme inner:}; & \everycell{} & \everycell{bend left} \ \node{extreme outer:}; & \everycell{} & \everycell{bend left} \};

\begin{tikzcd}[unshorten inner=+0.01pt] A & B \arrow[Rightarrow, from=1-1, to=1-2] \end{tikzcd} \end{document}

Output

In this case, it is best to compile yourself and look at the output in various zoom levels and with different PDF viewers/renderers. Still, you can click in the first two images to view a bigger version of it.

enter image description hereas above but with drawn nodes

enter image description here

Qrrbrbirlbel
  • 119,821
5

I wrote tikz-nfold specifically to solve this problem:

\documentclass{article}

\usepackage{tikz} \usetikzlibrary{cd} \usetikzlibrary{nfold}

\begin{document}

\begin{tikzcd} A & B \arrow[Rightarrow, from=1-1, to=1-2, nfold] \end{tikzcd}

\end{document}

On a side note, the author of tikz-cd recently informed me that \usepackage{tikz-cd} is a legacy feature, though there is nothing wrong with using it.

Jonathan
  • 409
1

If you use xy package for commutative diagram there is not vertical line or parallel line in the tail of the arrow.

\documentclass[a4paper,12pt]{article}
\usepackage[all,cmtip]{xy}

\begin{document} \xymatrix@C=3pc{A \ar@{=>}[r]& B} \end{document}

enter image description here

Sebastiano
  • 54,118