Diagonal strikeout starting too low and ending too high

I want to strikeout an equation with diagonal line but I've not managed to get the diagonal line to draw as I want. The closest I've gotten is via the first example in Frédéric's answer of \cancel draws under thing being canceled:

\documentclass{minimal}

\usepackage{tikz}

\newcommand{\hcancel}[1]{%
\tikz[baseline=(tocancel.base)]{
\node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
\draw[red] (tocancel.south west) -- (tocancel.north east);
}%
}%

\begin{document}

$$\label{eq:2} \hcancel{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}$$

\end{document}


This produces:

But the line starts too low and ends too high. The following is what I want:

I'd be happy for an option to make the line start slightly earlier and end slightly later too.

You can modify Frédéric's code so that \hcancel receives four more mandatory arguments controlling the vertical and horizontal shifting for the starting and ending points:

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{calc}
\newcommand{\hcancel}[5]{%
\tikz[baseline=(tocancel.base)]{
\node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
\draw[red] ($(tocancel.south west)+(#2,#3)$) -- ($(tocancel.north east)+(#4,#5)$);
}%
}%

\begin{document}

$$\label{eq:1} \hcancel{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}{0pt}{0pt}{0pt}{0pt}$$

$$\label{eq:2} \hcancel{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}{-3pt}{3pt}{3pt}{-2pt}$$

\end{document}


The new syntax:

\hcancel{<text>}{<start. point horiz. shifting>}{<start. point vertical shifting>}{<end. point horiz. shifting>}{<end. point vertical shifting>}


EDIT: using the xparse package, the definition of the new command is much more flexible; using something like

\usepackage{xparse}
\DeclareDocumentCommand{\hcancel}{mO{0pt}O{0pt}O{0pt}O{0pt}}{%
\tikz[baseline=(tocancel.base)]{
\node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
\draw[red] ($(tocancel.south west)+(#2,#3)$) -- ($(tocancel.north east)+(#4,#5)$);
}%
}%


allows the use of \hcancel{<text>} for the standard behaviour of the command as defined by Frédéric and to use the four (now optional) arguments to control the horizontal/vertical shifting:

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc}

\DeclareDocumentCommand{\hcancel}{mO{0pt}O{0pt}O{0pt}O{0pt}}{%
\tikz[baseline=(tocancel.base)]{
\node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
\draw[red] ($(tocancel.south west)+(#2,#3)$) -- ($(tocancel.north east)+(#4,#5)$);
}%
}%

\begin{document}

$$\label{eq:1} \hcancel{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}$$

$$\label{eq:2} \hcancel{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}[-3pt][3pt][3pt][-2pt]$$

\end{document}


You can create nodes at the beginning and the end of the line, and shift them vertically:

\tikzstyle{nosep}=[inner sep=0pt, outer sep=0pt]
\newcommand{\hcancel}[1]{%
\tikz[baseline=(tocancel.base)]{
\node[nosep] (tocancel) {#1};
\node[nosep, yshift=.5ex]  (from) at (tocancel.south west) {};
\node[nosep, yshift=-.5ex] (to)   at (tocancel.north east) {};
\draw[red] (from) -- (to);
}%
}%


You can find the best shifts by trial and error. I chose .5ex and -.5ex arbitrarily.

• @N.N. And to make the line slightly longer, add xshift=-1ex to the from node (+1ex for the to node). Jun 13, 2011 at 21:05

Another possibility is to create a style.

\documentclass[]{scrartcl}
\usepackage{tikz}
\usetikzlibrary{calc}

\begin{document}

\begin{tikzpicture}[cancel/.style={path picture={ \draw[#1]
($(path picture bounding box.south west)+(-3pt,6pt)$) -- ($(path picture bounding box.north east)+(3pt,-6pt)$);
}}]
\node   [inner sep=3pt,cancel=red] {$2x+3=y$};
\end{tikzpicture}

\end{document}


• It's possible to place the code in a macro with arguments. Jun 13, 2011 at 21:53
• When I try to compile this I get: ! Package pgfkeys Error: I do not know the key '/tikz/path picture' and I am going to ignore it. Perhaps you misspelled it.
– N.N.
Jun 14, 2011 at 7:33
• @N.N. I use pgf 2.1. and perhaps 'path picture' is defined since the 2.1 but I don't know :( I use this option in several examples and in some answers without problem. Jun 14, 2011 at 8:03
• OK, you're probably right. I've got pgf 2.0 from TeX Live 2009 on my system.
– N.N.
Jun 14, 2011 at 8:07

This is thought as enhancement of Gonzalo’s answer. The more arguments a command gets, the easier one can lose track of them. Here comes the key-value approach to aid.

Therefore I want to show a definition using the package keycommand. It could also be done with xparse and l3keys, but I am used to keycommand; in my eyes it is also more suited for end users, at least for cases like this. Note, though, that there is a bug in, and you must include the patch provided by Joseph Wright in his answer to the question How do I use \ifcommandkey , or how do I check if a key was given? after the package was loaded (actually you would need this only in cases, when you use the command \ifcommandkey).

Note, that I additionally added a key to change the line color, used in third example.

\documentclass{article}
\usepackage{keycommand}
% Patch by Joseph Wright ("bug in the definition of \ifcommandkey (2010/04/27 v3.1415)"),
% https://tex.stackexchange.com/a/35794
\begingroup
\makeatletter
\catcode\/=8 %
\@firstofone
{
\endgroup
\renewcommand{\ifcommandkey}[1]{%
\csname @\expandafter \expandafter \expandafter
\expandafter \expandafter \expandafter \expandafter
\kcmd@nbk \commandkey {#1}//{first}{second}//oftwo\endcsname
}
}
%--------%
\usepackage{tikz}
\usetikzlibrary{calc}
\newkeycommand{\hcancel}[hshiftstart=0pt,vshiftstart=0pt,hshiftend=0pt,vshiftend=0pt,color=red][1]{%
\tikz[baseline=(tocancel.base)]{
\node[inner sep=0pt,outer sep=0pt] (tocancel) {#1};
\draw[\commandkey{color}] ($(tocancel.south west)+(\commandkey{hshiftstart},\commandkey{vshiftstart})$) --
($(tocancel.north east)+(\commandkey{hshiftend},\commandkey{vshiftend})$);
}%
}%

\begin{document}

$$\label{eq:1} \hcancel{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}$$

$$\label{eq:2} \hcancel[hshiftstart=-3pt,vshiftstart=0.5em,hshiftend=3pt,vshiftend=-0.5em] {h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}$$

$$\label{eq:3} \hcancel[hshiftstart=-3pt,vshiftstart=1em,hshiftend=3pt,vshiftend=-1em,color=blue] {h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}$$

\end{document}


I use PSTricks in this answer. Please adjust the parameters until they suit your preference best. The parameters given in the code below are self-explanatory.

\documentclass{minimal}

\psset{linecolor=red}
\def\myeq{\psDefBoxNodes{A}{h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}}
\begin{document}

\centering

$$\myeq \ncline[nodesep=3pt,offsetA=-1pt,offsetB=3pt]{A:bl}{A:tr}$$
\\[5mm]

Controlling the length:
$$\myeq \ncline[nodesep=10pt,offsetA=-1pt,offsetB=3pt]{A:bl}{A:tr}$$
\\[5mm]

Controlling the left node:
$$\myeq \ncline[nodesep=3pt,offsetA=-1pt,offsetB=-10pt]{A:bl}{A:tr}$$
\\[5mm]

Controlling the right node:
$$\myeq \ncline[nodesep=3pt,offsetA=10pt,offsetB=3pt]{A:bl}{A:tr}$$

\end{document}


Coming late to the game.

Here is a picture based solution, which compiles of course faster as it does not need load all the tikz libraries. With the help of the pict2e package.

\documentclass{article}

\usepackage{pict2e}
\usepackage{color}

\makeatletter
% in our modern era, you should redefine this using xparse facilities
% so that you can add all parameters you wish more easily
% for example the linethickness which I hardcode here.
% Also, the \@firstoffour etc... is just because LaTeX's \newcommand
% admits only defining 1 optional parameter. With xparse, you can
% provide possibly more convenient user interface.
\newcommand\@firstoffour[4]{#1}
\newcommand\@secondoffour[4]{#2}
\newcommand\@thirdoffour[4]{#3}
\newcommand\@fourthoffour[4]{#4}

\newcommand\MyCancel[2][{0pt}{0pt}{0pt}{0pt}]{%
\begingroup
\sbox0{#2}%
\edef\MyCancel@xoffsetleft {\number\dimexpr\@firstoffour#1}%
\edef\MyCancel@yoffsetleft {\number\dimexpr\@secondoffour#1}%
\edef\MyCancel@xoffsetright{\number\dimexpr\@thirdoffour#1}%
\edef\MyCancel@yoffsetright{\number\dimexpr\@fourthoffour#1}%
\edef\MyCancel@width {\number\wd0}%
\edef\MyCancel@height{\number\ht0}%
\setlength{\unitlength}{1sp}%
\begin{picture}(\MyCancel@width,\MyCancel@height)
\linethickness{1pt}% this may be made another parameter
\put(0,0){\box0}
\color{red}%         also this one
\Line(\MyCancel@xoffsetleft,\MyCancel@yoffsetleft)% \Line does not like space here!
(\numexpr\MyCancel@xoffsetright+\MyCancel@width\relax,
\numexpr\MyCancel@yoffsetright+\MyCancel@height\relax)
\end{picture}%
\endgroup
}
\makeatother

\begin{document}

$$\MyCancel[{-1pt}{+1pt}{+0.5pt}{-1.5pt}]{\displaystyle h_1 \land h_2 \land h_3 \land h_4 \land h_5 \land h_6 \land h_7 \land h_8 \land h_9 \land h_{10}}$$

\end{document}


• I should have used \providecommand for the \@firstoffour` etc... in case some package define them. Hopefully with same definition..
– user4686
Oct 3, 2017 at 8:36