# Is it possible to exit from the PostScript expression and abort the drawing?

I just want to draw a dot if the condition is satisfied and otherwise cancel the drawing of the single dot. The following code is the simplified version of my real scenario. Please don't suggest other methods because the part I want to learn is to abort drawing.

The code below is intended to draw a dot for each point on the x-axis whenever its abscissa is an even number. More precisely, there is no dot for odd abscissa.

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\SpecialCoor
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\i=-5+1}{11}{\qdisk(!\i\space 2 mod 0 eq {\i\space 0} {<don't draw a dot and continue the loop>} ifelse){2pt}}
\end{pspicture}
\end{document}


Is it possible to exit from the PostScript expression and abort the drawing just for certain dots that do not match the condition?

## Edit

I want to get a solution that is useful not only for qdisk but also other graphic macros including the starred version.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\SpecialCoor

\begin{document}
% Herbert's method
\begin{pspicture}[showgrid](10,4)
\multido{\i=1+1}{9}
{
\pscircle*(!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if 1){5pt}
\pscircle(!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if 3){5pt}
}
\end{pspicture}

% modified Herbert's method
\begin{pspicture}[showgrid](10,4)
\multido{\i=1+1}{9}
{
\pscircle*(!\i\space dup 2 mod 0 ne {/SD {} def} if 1){5pt}
\pscircle(!\i\space dup 2 mod 0 ne {/SD {} def} if 3){5pt}
}
\end{pspicture}

% modified AlexG's method
\begin{pspicture}[showgrid](10,4)
\multido{\i=1+1}{9}
{
\pscircle*(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if 1){5pt}
\pscircle(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if 3){5pt}
}
\end{pspicture}

% my attempt with other macros
\begin{pspicture}[showgrid](10,4)
\multido{\i=1+1}{9}
{
% compilable but result in a wrong output
\psframe
(!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if .2 sub 2.8)
(!\i\space dup 2 mod 0 ne {/SD {pop pop pop} def} if .2 add 3.2)
%--------------------------------------------------------------------------------
% does not compile with  GhostScript
%\psframe
%(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if .2 sub 2.8)
%(!\i\space dup 2 mod 0 ne {mark Rand Rand /SD {cleartomark} def} if .2 add 3.2)
}
\end{pspicture}
\end{document}


Outputs in the same order.

-
So by "abort the drawing" do you mean you want to not draw the \qdisk, or not draw the entire drawing at all (and fail the process completely)? – Werner Jan 23 '14 at 5:43
@Werner: Just abort the single dot that does not match the condition. – kiss my armpit Jan 23 '14 at 6:52
I would imagine this is possible if you draw the disk directly in PS rather than using the interface provided by pstricks. That way you can condition on even/odd and draw something/not. – Werner Jan 23 '14 at 7:05

No, this is not possible due to the stack nature of Postscript.

In this specific situation, the verbatim Postscript argument (!...) simply puts the disk coordinates on the operand stack. The disk itself gets drawn later, when the PS procedure SD (it implements the disk drawing) is put on the stack and executed.

In order to not draw selected disks, the code in the else-clause of your example would have to jump into a future state of the operand stack, that is, on top of the SD procedure. This is impossible, since SD hasn't arrived there yet.

All you can do is to temporarily redefine SD to clear the operand stack up to a certain position defined with the mark keyword:

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\SpecialCoor
\begin{document}
\begin{pspicture}[showgrid](-5,-5)(5,5)
\multido{\i=-5+1}{11}{\qdisk(!
\i\space 2 mod 0 eq {\i\space 0} % put desired disk coordinates on the stack if condition is fulfilled
{ %else
mark  % mark stack position up to which the operand stack needs to be cleared
-1 -1 % put some dummy coords on the stack to satisfy operators that come in between them and SD
/SD {cleartomark} def % redefine SD to clear the stack upto the previously defined position
} ifelse){2pt}}
\end{pspicture}
\end{document}


UPDATE:

For any other PSTricks graphical command you will have to look into its implementation to figure out which bit requires modification. Here are the \pscircle and \psframe examples:

\documentclass[pstricks,border=12pt,12pt]{standalone}
\usepackage{multido}
\SpecialCoor

\begin{document}
\begin{pspicture}[showgrid](10,4)
\multido{\i=1+1}{9}
{
\pscircle*(!\i\space dup 2 mod 0 ne
{
mark  % mark stack position up to which the operand stack needs to be cleared
exch  % swap \i and mark
/arc {cleartomark} def % redefine arc to clear the stack upto the previously defined position
} if 1
){5pt}
\pscircle(!\i\space dup 2 mod 0 ne {mark exch /arc {cleartomark} def} if 3){5pt}
}
\end{pspicture}

\begin{pspicture}[showgrid](10,4)
\multido{\i=1+1}{9}
{
\psframe
(!\i\space dup 2 mod 0 ne { mark exch /Frame {cleartomark} def } if .2 sub 2.8)
%procedure Frame' executed around here.
}
\end{pspicture}
\end{document}

-
+1 Could you please explain what your code does such that I can reuse it as a template for my other projects in the future? – kiss my armpit Jan 23 '14 at 8:19
Do you have any idea about my other question here. – kiss my armpit Jan 23 '14 at 8:28
@CodeMocker: I edited a second time. The mark keyword is inserted only if the condition is false. – AlexG Jan 23 '14 at 8:52
@CodeMocker Ok. Herbert's answer is much shorter. He knows better how many operands to remove. Nevertheless, the essence is the same, SD needs to be redefined. – AlexG Jan 23 '14 at 9:21
See my updated question. Your solution does not seem to work with \pscircle (unstarred) and other graphics macros (such as \psframe). – kiss my armpit Jan 24 '14 at 8:14
\documentclass[pstricks,border=12pt,12pt]{standalone}
\SpecialCoor
\begin{document}

\begin{pspicture}[showgrid](-5,-5)(5,5)
\psforeach{\iA}{-5,-4,..,5}{\qdisk(!
\iA\space dup 2 mod 0 ne { /SD { pop pop pop } def } if 0 ){2pt}}
\end{pspicture}
\end{document}


or for any possible object:

\documentclass[pstricks,border=12pt,12pt]{standalone}
\makeatletter\let\Modulo\pst@mod\makeatother
\begin{document}

\begin{pspicture}[showgrid](-5,-5)(5,5)
\psforeach{\iA}{-5,-4,..,5}{%
\Modulo\iA2\Value
\ifnum\Value=0 \pscircle(\iA,0){5pt}\fi}
\end{pspicture}

\end{document}

-
Interesting. The original meaning of SD doesn't need to be restored. Why? – AlexG Jan 23 '14 at 9:04
it is used in an own dictionary – Herbert Jan 23 '14 at 9:13
I see. Within \qdisk the current dict is tx@Dict, and the original definition of SD was made outside of it. Thanks. – AlexG Jan 23 '14 at 9:19
Interesting: \qdisk(!\iA\space dup 2 mod 0 ne { /SD {} def } if 0 ){2pt} also works. I applied it to my answer here (click). – kiss my armpit Jan 24 '14 at 6:33
See my updated question. Your solution does not seem to work with \pscircle (unstarred) and other graphics macros (such as \psframe`). – kiss my armpit Jan 24 '14 at 8:13