# Define new PSTricks object with arguments

Inspired by Clemens Niederberger's post about a possible new package, I have tried to create a similar figure using PSTricks.

Code

\documentclass{article}

\usepackage{chemmacros}

\pagestyle{empty}

\begin{document}

\begin{figure}[htbp]
% Parameters
\def\basinwidth{15 }
\def\basinheight{10 }
\def\waterheight{8}
\def\cathode{\ch{Zn}}
\def\cathodeColour{gray!30}
\def\anode{\ch{Cu}}
\def\anodeColour{red!50}
\centering
\psset{unit=0.7\psunit}
\begin{pspicture}(15,11.5)
% Basin
\psline(0,\basinheight)(0,\waterheight)
\pscustom[fillstyle=solid,fillcolor=cyan!70]{%
\psline(0,\waterheight)(\basinwidth,\waterheight)
\psline(0,\waterheight)(0,1)
\psarc(1,1){1}{180}{270}
\psline(1,0)(!\basinwidth 1 sub 0)
\psarc(!\basinwidth 1 sub 1){1}{270}{360}
\psline(\basinwidth,1)(\basinwidth,\waterheight)
\closepath
}
\psline(\basinwidth,\waterheight)(\basinwidth,\basinheight)
% Membrane
\psline[linestyle=dashed]%
(!\basinwidth 2 div 0)%
(!\basinwidth 2 div \waterheight)
% Cathode
\pspolygon[fillstyle=solid,fillcolor=\cathodeColour]%
(!\basinwidth 4 div 1 sub 1)%
(!\basinwidth 4 div 1 sub \basinheight 1 sub)%
(!\basinwidth 4 div 1 add \basinheight 1 sub)%
(!\basinwidth 4 div 1 add 1)
\rput(!\basinwidth 4 div \basinheight 2 div){\cathode}
% Anode
\pspolygon[fillstyle=solid,fillcolor=\anodeColour]%
(!3 \basinwidth mul 4 div 1 sub 1)%
(!3 \basinwidth mul 4 div 1 sub \basinheight 1 sub)%
(!3 \basinwidth mul 4 div 1 add \basinheight 1 sub)%
(!3 \basinwidth mul 4 div 1 add 1)
\rput(!3 \basinwidth mul 4 div \basinheight 2 div){\anode}
% Wires
\rput(!\basinwidth 4 div 1 add \basinheight){$+$}
\psline(!\basinwidth 4 div \basinheight 1 sub)%
(!\basinwidth 4 div \basinheight)
\psarc(!\basinwidth 4 div 1 add \basinheight){1}{90}{180}
(!\basinwidth 1 sub 2 div \basinheight 1 add)
\pscircle(!\basinwidth 2 div \basinheight 1 add){0.5}
\rput(!\basinwidth 2 div \basinheight 1 add){$U$}
\psline(!3 \basinwidth mul 4 div 1 sub \basinheight 1 add)%
\psarc(!3 \basinwidth mul 4 div 1 sub \basinheight){1}{0}{90}
\psline(!3 \basinwidth mul 4 div \basinheight 1 sub)%
(!3 \basinwidth mul 4 div \basinheight)
\rput(!3 \basinwidth mul 4 div 1 sub \basinheight){$-$}
% Electron movement
\rput(!3 \basinwidth mul 1 add 8 div \basinheight 3 2 div add)%
{\ch{->[ e- ]}}
\rput(!5 \basinwidth mul 2 sub 8 div \basinheight 3 2 div add)%
{\ch{->[ e- ]}}
\end{pspicture}
\end{figure}

\end{document}


The code should be compiled with xelatex.

Question

Is it possible to define a new object with argument that looks something like the following?

\cell[
cathode=Zn,
cathodeColour=grey!30,
anode=Cu,
anodeColour=red!50
]{"basinwidth"}{"basinheight"}{"waterheight"}


If it is possible, how do I do it?

Extra question

I have had a look at section 28.2 in the chemmacros manual in order to draw the arrows with electrons above but I couldn't make it work with \ch{ ->[\el] }. If someone can tell be how to draw this, that would be nice. (Solved)

-
About the extra question: have you tried \ch{->[ e- ]}? – clemens Feb 25 '13 at 17:03
@cgnieder I have now but the code still can't be compiled. I have updated my post with your suggestion commented out. (I have a fully updated TeX Live 2012 distribution.) – Svend Tveskæg Feb 25 '13 at 17:44
No idea why it isn't working. It works when compiled via latex, dvips and ps2pdf. Another remark: \large{\scrp} doesn't make sense since \scriptstyle is hard-coded into \scrp. I'd simply use $+$. chemmacros' charge macros only make sense if you want actually want $\scriptstyle+$ or want to be able to switch to formal charges eventually... – clemens Feb 25 '13 at 18:08
Thank you for the help with the extra question. Can anyone help with the main question? – Svend Tveskæg Feb 25 '13 at 18:20
I had a similar issues with xelatex. The problem is the conversion via the driver xdvipdfmx – Marco Daniel Feb 25 '13 at 18:47

I have no experience whatsoever with PSTricks so I don't know if there are preferred ways to what I am going to suggest. It seems to me that this is a straight-forward task: wrap the whole definition in a macro with an optional argument. PSTricks loads xkeyval so you can use this package to define keys which then can be set by the optional argument:

% default definitions:
\def\cathode{\ch{Zn}}
\def\cathodeColour{gray!30}
\def\anode{\ch{Cu}}
\def\anodeColour{red!50}

\makeatletter
% keys for the optional argument:
\define@key{cell}{cathode}{\def\cathode{\ch{#1}}}
\define@key{cell}{cathodeColour}{\def\cathodeColour{#1}}
\define@key{cell}{anode}{\def\anode{\ch{#1}}}
\define@key{cell}{anodeColour}{\def\anodeColour{#1}}
\makeatother

% \cell[<options>]{<basinwidth>}{<basinheight>}{<waterheight>}
\newcommand\cell[4][]{%
\begingroup
% set the keys:
\setkeys{cell}{#1}%
\def\basinwidth{#2 }%
\def\basinheight{#3 }%
\def\waterheight{#4 }%
% the rest of the definition:
...
\endgroup


The grouping is to keep the setting of the keys local. However, since they're going to be used in a pspicture it's probably not needed. If you want to be able to access coordinates of the cell it's probably even better to omit it, anyway. (As I said: I have no experience with PSTricks so I haven't tested this...)

Here's an entire example based on your example code:

\documentclass{article}

\usepackage{chemmacros}

\pagestyle{empty}

\def\cathode{\ch{Zn}}
\def\cathodeColour{gray!30}
\def\anode{\ch{Cu}}
\def\anodeColour{red!50}

\makeatletter
\define@key{cell}{cathode}{\def\cathode{\ch{#1}}}
\define@key{cell}{cathodeColour}{\def\cathodeColour{#1}}
\define@key{cell}{anode}{\def\anode{\ch{#1}}}
\define@key{cell}{anodeColour}{\def\anodeColour{#1}}
\makeatother

\newcommand\cell[4][]{%
\begingroup
\setkeys{cell}{#1}%
\def\basinwidth{#2 }%
\def\basinheight{#3 }%
\def\waterheight{#4 }%
% Basin
\psline(0,\basinheight)(0,\waterheight)
\pscustom[fillstyle=solid,fillcolor=cyan!70]{%
\psline(0,\waterheight)(\basinwidth,\waterheight)
\psline(0,\waterheight)(0,1)
\psarc(1,1){1}{180}{270}
\psline(1,0)(!\basinwidth 1 sub 0)
\psarc(!\basinwidth 1 sub 1){1}{270}{360}
\psline(\basinwidth,1)(\basinwidth,\waterheight)
\closepath
}
\psline(\basinwidth,\waterheight)(\basinwidth,\basinheight)
% Membrane
\psline[linestyle=dashed]%
(!\basinwidth 2 div 0)%
(!\basinwidth 2 div \waterheight)
% Cathode
\pspolygon[fillstyle=solid,fillcolor=\cathodeColour]%
(!\basinwidth 4 div 1 sub 1)%
(!\basinwidth 4 div 1 sub \basinheight 1 sub)%
(!\basinwidth 4 div 1 add \basinheight 1 sub)%
(!\basinwidth 4 div 1 add 1)
\rput(!\basinwidth 4 div \basinheight 2 div){\cathode}
% Anode
\pspolygon[fillstyle=solid,fillcolor=\anodeColour]%
(!3 \basinwidth mul 4 div 1 sub 1)%
(!3 \basinwidth mul 4 div 1 sub \basinheight 1 sub)%
(!3 \basinwidth mul 4 div 1 add \basinheight 1 sub)%
(!3 \basinwidth mul 4 div 1 add 1)
\rput(!3 \basinwidth mul 4 div \basinheight 2 div){\anode}
% Wires
\rput(!\basinwidth 4 div 1 add \basinheight){$+$}
\psline(!\basinwidth 4 div \basinheight 1 sub)%
(!\basinwidth 4 div \basinheight)
\psarc(!\basinwidth 4 div 1 add \basinheight){1}{90}{180}
(!\basinwidth 1 sub 2 div \basinheight 1 add)
\pscircle(!\basinwidth 2 div \basinheight 1 add){0.5}
\rput(!\basinwidth 2 div \basinheight 1 add){$U$}
\psline(!3 \basinwidth mul 4 div 1 sub \basinheight 1 add)%
\psarc(!3 \basinwidth mul 4 div 1 sub \basinheight){1}{0}{90}
\psline(!3 \basinwidth mul 4 div \basinheight 1 sub)%
(!3 \basinwidth mul 4 div \basinheight)
\rput(!3 \basinwidth mul 4 div 1 sub \basinheight){$-$}
% Electron movement
\rput(!3 \basinwidth mul 1 add 8 div \basinheight 3 2 div add)%
{\ch{->[ e- ]}}
\rput(!5 \basinwidth mul 2 sub 8 div \basinheight 3 2 div add)%
{\ch{->[ e- ]}}
\endgroup
}

\begin{document}

\begin{figure}[htbp]
\centering
\psset{unit=0.7\psunit}
\begin{pspicture}(15,11.5)
\cell{15}{10}{8}
\end{pspicture}
\end{figure}

\begin{figure}[htbp]
\centering
\psset{unit=0.7\psunit}
\begin{pspicture}(15,11.5)
\cell[
cathode=Cu,
cathodeColour=red!50,
anode=Ag,
anodeColour=gray!10
]{15}{10}{8}
\end{pspicture}
\end{figure}

\end{document}


-