3

The following MCE below points out that, for a tikz' struck out node, the line width causes both horizontal and vertical shifts. Is it possible to

  • avoid them?
  • Or, at least, to know exactly the dimensions of these shifts in order to compensate them (the struck out text to be at the same place as would be the "normal" one)?

This question is in the same spirit as How to avoid shifts for content which is "strike out" (from tikz shapes.misc library)? but the other way round: here, I want the "normal" text to not be shifted as is the struck out one but the struck out text to not be shifted and being at the same place as would be the "normal" one.

\documentclass{article}
\usepackage[arrows=false]{pagegrid}
\usepackage[margin=0cm,papersize=2cm]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes}
%
\setlength{\parindent}{0pt}
%
\newcommand{\test}[1][]{%
  \tikz \node [draw,inner sep=0pt,outer sep=0pt,strike out,draw=red,#1] {%
    test%
  };%
}
%
\begin{document}
test \test{} \test[line width=.5ex]

\test{} \test[line width=.5ex] test

\test[line width=.5ex] test \test{}
\end{document}

enter image description here

Denis Bitouzé
  • 9,652
  • 4
  • 27
  • 85

3 Answers3

6

If I understand you correctly you could perhaps draw the strike out as a separate node (using the fit library to get the correct size), and add the overlay option to that node, so that it isn't considered for the calculation of the bounding box.

output of cod

\documentclass{article}
\usepackage[arrows=false]{pagegrid}
\usepackage[margin=0cm,papersize=2cm]{geometry}
\usepackage{tikz}
\usetikzlibrary{shapes,fit} % <-- added fit
%
\setlength{\parindent}{0pt}
%
\newcommand{\test}[1][]{%
\begin{tikzpicture}
% first add text
\node [inner sep=0pt,outer sep=0pt] (foo) {test};
% draw strike out in separate node, with overlay option
\node [overlay,inner sep=0pt,fit=(foo),strike out,draw=red,#1] {};
\end{tikzpicture}%
}
%
\begin{document}
test \test{} \test[line width=.5ex]

\test{} \test[line width=.5ex] test

\test[line width=.5ex] test \test{}
\end{document} 
Torbjørn T.
  • 206,688
1

It is quite easy to create your own strike out command using tikz. Just use [remember picture,overlay] option for the tikz environment to avoid interfering with the text.

\documentclass{article}
\usepackage[arrows=false]{pagegrid}
\usepackage[margin=0cm,papersize=2cm]{geometry}
\usepackage{tikz,calc}
\usetikzlibrary{shapes}
%
\setlength{\parindent}{0pt}
%
\newlength\teht
\settoheight\teht{t}
\newcommand\tikzmark[1]{\tikz[remember picture,overlay]\coordinate(#1);}

\newcommand{\test}[2][]{%
  \tikzmark{o}#2\tikzmark{a}%
  \tikz[remember picture, overlay]{\draw[red,#1](o)--([yshift=\teht]a);}%
} 
\begin{document}    
test \test{test} \test[line width=.5ex]{test}

\test{test} \test[line width=.5ex]{test} test

\test{test} test \test[line width=.5ex]{test}    
\end{document}

enter image description here

AboAmmar
  • 46,352
  • 4
  • 58
  • 127
1

An almost identical question has been asked here, and I am just recycling this answer.

\documentclass{article}
\usepackage[arrows=false]{pagegrid}
\usepackage[margin=0cm,papersize=2cm]{geometry}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{tikzpagenodes}

\tikzset{StrikeOut/.style={-,red}}


\makeatletter
\newcommand{\gettikzxy}[3]{% from https://tex.stackexchange.com/a/58590/121799
  \tikz@scan@one@point\pgfutil@firstofone#1\relax
  \global\edef#2{\the\pgf@x}%
  \global\edef#3{\the\pgf@y}%
}
\makeatother
\newcommand{\StrikeOut}[2][]{%
\tikz[remember picture,overlay, baseline=(Begin.base)]{%
\node[anchor=base,inner sep=0pt,outer sep=0pt] (Begin) {\strut};}#2%
\tikz[remember picture,overlay, baseline=(End.base)]{%
\node[anchor=base,inner sep=0pt,outer sep=0pt] (End) {\strut};}%
\begin{tikzpicture}[overlay,remember picture]
\gettikzxy{($(Begin.north)-(current page.south west)$)}{\BeginxN}{\BeginyN}
\gettikzxy{($(End.north)-(current page.south west)$)}{\EndxN}{\EndyN}%\typeout{\BeginyN\space\EndyN}
\pgfmathtruncatemacro{\mytest}{\EndyN-\BeginyN}
\ifnum\mytest=0\relax% begin and and in the same line %\typeout{begin and end in the same line}
\draw[StrikeOut,#1] (Begin.north) -- (End.south);
\draw[StrikeOut,#1] (Begin.south) -- (End.north);
\else% \typeout{end below begin}
\path (current page text area.north west) -- (current page text area.south west)
node(WestLine)[left]{};
\path (current page text area.north east) -- (current page text area.south east)
node(EastLine)[right]{};
\gettikzxy{($(End.north)-(current page.south west)$)}{\EndxN}{\EndyN}
\gettikzxy{($(Begin.south)-(current page.south west)$)}{\BeginxS}{\BeginyS}
\pgfmathtruncatemacro{\mytest}{\BeginyS-\EndyN+1pt}% \typeout{\mytest}
\ifnum\mytest<2\relax% \typeout{end in the next line after begin}%
\pgfmathtruncatemacro{\mytest}{\BeginxS-\EndxN}% \typeout{\mytest}
\ifnum\mytest>0\relax
\draw[StrikeOut,#1] (Begin.north) -- (Begin.south -| EastLine);
\draw[StrikeOut,#1] (Begin.south) -- (Begin.north -| EastLine);
\draw[StrikeOut,#1] (End.north -| WestLine) -- (End.south);
\draw[StrikeOut,#1] (End.south -| WestLine) -- (End.north);
\else
\draw[StrikeOut,#1] (Begin.south) -- (Begin.north -| EastLine);
\draw[StrikeOut,#1] (Begin.north) -- (Begin.south -| EastLine);
\draw[StrikeOut,#1] (End.north -| WestLine) -- (End.south);
\draw[StrikeOut,#1] (End.south -| WestLine) -- (End.north);
\fi
\else
\pgfmathsetmacro{\LineHeight}{\the\baselineskip}
\pgfmathtruncatemacro{\NumLines}{-1+(\BeginyN-\EndyN)/\LineHeight}
\typeout{\NumLines}
\foreach \X in {1,...,\NumLines}
{
\draw[StrikeOut,#1] ($(Begin.north -| WestLine)+(0,-\X*\LineHeight pt)$) -- 
($(Begin.south -|EastLine)+(0,-\X*\LineHeight pt)$);
\draw[StrikeOut,#1] ($(Begin.south -| WestLine)+(0,-\X*\LineHeight pt)$) -- 
($(Begin.north -|EastLine)+(0,-\X*\LineHeight pt)$);
}
\draw[StrikeOut,#1] (Begin.north) -- (Begin.south -| EastLine);
\draw[StrikeOut,#1] (Begin.south) -- (Begin.north -| EastLine);
\draw[StrikeOut,#1] (End.north -| WestLine) -- (End.south);
\draw[StrikeOut,#1] (End.south -| WestLine) -- (End.north);
\fi
\fi
\end{tikzpicture}}
\begin{document}
\noindent
test \StrikeOut{test} \StrikeOut[line width=.5ex]{test}\\
\StrikeOut{test} \StrikeOut[line width=.5ex]{test} test\\
\StrikeOut[line width=.5ex]{test} test \StrikeOut{test}\\
\end{document}

enter image description here

  • Works well, but much more complicated than the fit method. – Denis Bitouzé Mar 04 '18 at 09:43
  • 1
    @DenisBitouzé The method is not too different. The reason why it looks more complicated is that this macro works also when the text runs over more than one lines. –  Mar 04 '18 at 10:48
  • Indeed but, in such a case, maybe a unique cross over the whole paragraph would be expected (instead of a each line of the paragraph to be crossed). Anyway, this would be matter of another question :) – Denis Bitouzé Mar 04 '18 at 12:08
  • 1
    @DenisBitouzé If you look at this answer, you'll see that the crossed out text has in general not a box shape, so I wonder how you would put a big cross on it. However, if you have a clear prescription, then the above may be the basis for a macro since it already recognizes the three situation: (1) all in one line, (2) two lines and (3) more than three lines. (Notice that this answer can be the basis for a macro that also works with page breaks.) –  Mar 04 '18 at 20:08