From 59161ce421c69ad679d1c22d540f51b9e68a2497 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Sun, 13 Jul 2014 21:30:08 +0000
Subject: pst-optexp

git-svn-id: svn://tug.org/texlive/trunk@34592 c570f23f-e606-0410-a88d-b1316a301751
---
 .../source/latex/pst-optexp/pst-optexp.dtx         | 883 +++++++++++++++------
 1 file changed, 626 insertions(+), 257 deletions(-)

(limited to 'Master/texmf-dist/source/latex/pst-optexp/pst-optexp.dtx')

diff --git a/Master/texmf-dist/source/latex/pst-optexp/pst-optexp.dtx b/Master/texmf-dist/source/latex/pst-optexp/pst-optexp.dtx
index 43723b2c978..7e3c035baa5 100644
--- a/Master/texmf-dist/source/latex/pst-optexp/pst-optexp.dtx
+++ b/Master/texmf-dist/source/latex/pst-optexp/pst-optexp.dtx
@@ -18,7 +18,7 @@
 %<stylefile>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
 %<stylefile>\ProvidesPackage{pst-optexp}
 %<*stylefile>
-    [2014/02/28 v4.8 Optical experimental setups with PSTricks]
+    [2014/06/04 v4.10 Optical experimental setups with PSTricks]
 %</stylefile>
 %
 %<*driver>
@@ -111,7 +111,7 @@
     oeBeamCenter, optplate, optretplate, pinhole, crystal, optdetector,
     optdiode, doveprism, glanthompson, polarization, mirror,
     beamsplitter, optgrating, optprism, rightangleprism, pentaprism, optaom,
-    optdipole, opttripole, optfiber, optamp, optmzm, optfilter,
+    optdipole, opttripole, optfiber, optamp, optmzm, optfilter, optsource,
     polcontrol, optisolator, optswitch, fiberdelayline,
     optfiberpolarizer, fibercollimator, optcoupler, wdmcoupler,
     wdmsplitter, optcirculator, fiberbox, eleccoupler, elecsynthesizer,
@@ -3127,6 +3127,84 @@
 % \fi
 % \end{stylelist}
 %
+% \ifGERMAN\section{Optische Quelle}\fi
+% \ifENGLISH\section{Optical source}\fi
+% 
+% \begin{ltxsyntax}
+% \dipoledesc{optsource}
+% \iffalse
+%<*ignore>
+% \fi
+\begin{LTXexample}
+\begin{pspicture}(3,2)
+  \optsource(1.5,1)(3,1){Laser}
+\end{pspicture}
+\end{LTXexample}
+% \iffalse
+%</ignore>
+% \fi
+%
+% \ifENGLISH 
+% An optical source predefines some properties of any outgoing beam, if
+% it is the first component in a beam path. The definable beam
+% properties are \Lkeyword{beamangle}, \Lkeyword{beamwidth},
+% \Lkeyword{beamdiv} and \Lkeyword{beamalign}. The properties defined by
+% the optical source cannot be overwritten by the beam properties. If a
+% property wasn't explicitely defined for a source, it is taken from the
+% beam properties.
+%
+% The default settings for the component position are
+% \Lkeyword{position}\opt{=start}.
+% \fi
+% \ifGERMAN
+% Eine optische Quelle gibt ein paar Eigenschaften für alle von ihr
+% ausgehenden Strahlen vor, falls es die erste Komponente in einem
+% Strahlengang ist. Die verwendbaren Eigenschaften sind
+% \Lkeyword{beamangle}, \Lkeyword{beamwidth}, \Lkeyword{beamdiv} und
+% \Lkeyword{beamalign}. Alle Eigenschaften, die von einer optischen
+% Quelle definiert werden, können nicht später durch Strahlparameter
+% überschrieben werden. Wird ein Parameter nicht explizit von der Quelle
+% definiert, so werden die Parameter von dem Strahl-Stil verwendet.
+%
+% Die Voreinstellung für die Positionierung ist
+% \Lkeyword{position}\opt{=start}.
+% \fi
+% \end{ltxsyntax}
+%
+% \iffalse
+%<*ignore>
+% \fi
+\begin{LTXexample}
+\begin{pspicture}(5,2)
+  \pnodes(1.5,1){A}(5,1){B}
+  \optsource[innerlabel, beamdiv=10, beamangle=10](A)(B){Laser}
+  \lens[lens=2 2 2](A)(B)
+  \optplane(B)
+  \drawwidebeam{-}
+  \drawbeam[linecolor=red]{-}
+\end{pspicture}
+\end{LTXexample}
+% \iffalse
+%</ignore>
+% \fi
+%
+% \begin{optionlist}
+% \numitem[1.4]{sourcewidth}
+% \ifGERMAN Die Breite der Box.\fi
+% \ifENGLISH The width of the box.\fi
+%
+% \numitem[0.8]{sourceheight}
+% \ifGERMAN Die Höhe der Box.\fi
+% \ifENGLISH The height of the box.\fi
+%
+% \optitem{sourcesize}{\prm{width} \prm{height}}
+% \ifGERMAN Die Breite und Höhe der Box, äquivalent zum Aufruf von
+% \Lkeyword{sourcewidth} und \Lkeyword{sourceheight}.
+% \fi
+% \ifENGLISH The width and height of the box, is equivalent to calling both
+% \Lkeyword{sourcewidth} and \Lkeyword{sourceheight}.
+% \fi
+% \end{optionlist}
 %
 % \ifGERMAN\section{Kristall}\fi
 % \ifENGLISH\section{Crystal}\fi
@@ -6788,12 +6866,15 @@
 %   \cmditem{oenodeIfc}{num}{comp}
 %
 %   \ifGERMAN
-%   Der Grenzflächenknoten \prm{num}, wobei \prm{num} eine positive Ganzzahl
-%   oder \opt{N} ist. Der letzte Knoten ist immer \opt{N}.
+%   Der Grenzflächenknoten \prm{num}, wobei \prm{num} eine positive
+%   Ganzzahl oder der Buchstabe \opt{N} ist. Der letzte Knoten ist immer
+%   \opt{N}, kann aber auch über die entsprechende Zahl angesprochen
+%   werden.
 %   \fi
 %   \ifENGLISH
-%   The interface node \prm{num}, where the number is a positive integer or
-%   \opt{N}. The last node is always defined as \opt{N}.
+%   The interface node \prm{num}, where the number is a positive integer
+%   or the character \opt{N}. The last node is always defined as \opt{N}
+%   but can also be accessed via its number.
 %   \fi
 %
 %   \cmditem{oenodeIn}{comp}
@@ -8065,11 +8146,12 @@
 %</ignore>
 % \fi
 % 
-% \choitem[relative]{beamalign}{rel, relative, abs, absolute}
+% \choitem[relative]{beamalign}{rel, relative, abs, absolute, firstcomp}
 % \ifGERMAN
 % Gibt vor, ob der Winkel \Lkeyword{beamangle} relativ zu der Verbindung
-% zwischen den ersten beiden Komponenten ist, oder ob es sich um einen absoluten
-% Winkel handelt.
+% zwischen den ersten beiden Komponenten ist, ob es sich um einen
+% absoluten Winkel handelt, oder ob der Winkel durch die Ausrichtung der
+% ersten Komponente vorgegeben wird.
 %
 % Ein absoluter Winkel kann sehr hilfreich sein, falls eine der beiden ersten
 % Komponenten gedreht oder verschoben wurde. Dabei werden die
@@ -8104,6 +8186,37 @@
 %</ignore>
 % \fi
 %
+% \ifGERMAN 
+% Im folgenden Beispiel liegen beide Komponenten auf der horizontalen
+% Linie $\overline{AB}$. Der grüne Strahl, mit
+% \Lkeyword{beamalign}\opt{=rel} verläuft daher auch horizontal. Der
+% rote Strahl ist hingegen mit \Lkeyword{beamalign}\opt{=firstcomp}
+% entsprechend der Drehung der ersten Komponente ausgerichtet.
+% \fi
+% \ifENGLISH 
+% Both components in the following example are align on the horizontal
+% line $\overline{AB}$. The green beam with
+% \Lkeyword{beamalign}\opt{=rel} is accordingly aligned
+% horizontally. The red beam with \Lkeyword{beamalign}\opt{=firstcomp}
+% is aligned according to the rotation of the first component:
+% \fi
+%
+% \iffalse
+%<*ignore>
+% \fi
+\begin{LTXexample}[morekeywords = {[21]{beamalign, angle}}]
+\begin{pspicture}(4,3)
+  \pnodes(1.5,1.5){A}(4,1.5){B}
+  \optbox[position=start, rotateref=r, angle=10](A)(B)
+  \optplate[position=end, plateheight=3](A)(B)
+  \addtopsstyle{Beam}{beamdiv=20}
+  \drawwidebeam{-}
+  \drawwidebeam[beamalign=firstcomp, linecolor=red]{-}
+\end{pspicture}
+\end{LTXexample}
+% \iffalse
+%</ignore>
+% \fi
 %
 % \numitem[0]{beampathskip}
 % \ifGERMAN
@@ -8364,11 +8477,11 @@
 % \fi
 \begin{LTXexample}[morekeywords = {[21]{stopinsidecount, startinsidecount}}]
 \begin{pspicture}(4,2)
-  \pnodes(0,2){A}(2,0.8){B}(4,2){C}
-  \optprism[compname=P, prismtype=reflective, prismangle=90](A)(B)(C)
-  \lens[abspos=1.33](\oenodeIfc{2}{P})(A)%
-  \lens[abspos=1.33](\oenodeIfc{2}{P})(C)%
-  \newpsstyle{Beam}{linestyle=none, fillstyle=solid}%
+  \pnodes(0,2){A}(2,0){B}(4,2){C}
+  \optprism[compname=P, n=1, prismtype=reflective, prismangle=90](A)(B)(C)
+  \lens[abspos=1.08](\oenodeIfc{2}{P})(A)
+  \lens[abspos=1.08](\oenodeIfc{2}{P})(C)
+  \newpsstyle{Beam}{linestyle=none, fillstyle=solid}
   \drawwidebeam[fillcolor=green, beamwidth=0.2, beaminsidelast, stopinsidecount=1](A){2}{1}
   \drawwidebeam[fillcolor=orange, beaminsidefirst, startinsidecount=1, loadbeam]{1}{3}(C)
 \end{pspicture}
@@ -12412,7 +12525,48 @@
 %
 % \begin{optionlist}
 % \boolitem[false]{showinterfaces}
+% \ifGERMAN Zeigt alle Grenzflächen einer Komponente an.\fi
+% \ifENGLISH Visualizes all interfaces of a component.\fi
+%
+% \iffalse
+%<*ignore>
+% \fi
+\begin{LTXexample}
+\begin{pspicture}(3,1.5)
+  \psset[optexp]{showinterfaces, aomgratingcount=6}
+  \addtopsstyle{IfcStyle}{linewidth=2\pslinewidth}
+  \pnodes(0,1.5){A}(3,0.5){B}(3,1.5){C}
+  \optaom[aomalign=symmetric](A)(B)(C){symmetric}
+  \addtopsstyle{Beam}{arrows=->, linewidth=4\pslinewidth}
+  \drawbeam[linecolor=red!50](A){}(C)
+  \drawbeam[linecolor=red](A){}(B)
+\end{pspicture}
+\end{LTXexample}
+
+\begin{LTXexample}
+\begin{pspicture}(3,1.5)
+  \psset[optexp]{showinterfaces, aomgratingcount=6}
+  \addtopsstyle{IfcStyle}{linewidth=2\pslinewidth}
+  \pnodes(0,1){A}(3,1){B}(3,1.5){C}
+  \optaom[aomalign=straight](A)(B)(C){straight}
+  \addtopsstyle{Beam}{arrows=->, linewidth=4\pslinewidth}
+  \drawbeam[linecolor=red!50](A){}(C)
+  \drawbeam[linecolor=red](A){}(B)
+\end{pspicture}
+\end{LTXexample}
+% \iffalse
+%</ignore>
+% \fi
+%
 % \styleitem[linestyle=dashed, dash=1pt 1pt, linecolor=red!70!black]{IfcStyle}
+% \ifGERMAN
+% Bestimmt das Aussehen der mit \Lkeyword{showinterfaces} angezeigten
+% Grenzflächen.
+% \fi
+% \ifENGLISH
+% Determines the appearance of the interfaces, which are shown with
+% \Lkeyword{showinterfaces}.
+% \fi
 % \end{optionlist}
 %
 % \ifENGLISH\section{Overview of special nodes}\fi
@@ -13348,6 +13502,16 @@
 %
 % \begin{changelog}
 % \patchcmd{\release}{\setlength{\itemsep}{0pt}}{\setlength{\itemsep}{0pt}\setlength{\parsep}{0pt}}{}{}
+%   \begin{release}{4.10}{2014-06-04}
+%   \item Added value \opt{firstcomp} to parameter \opt{beamalign}\see{prm:beamalign}
+%   \item Modified \cs{optsource} to handle also the beam alignment\see{comp:optsource}
+%   \end{release}
+%   \begin{release}{4.9}{2014-06-03}
+%   \item Added new component \cs{optsource}\see{comp:optsource}
+%   \item Improved naming of the last component name, which can now be
+%     accessed also by its number besides using \opt{N}.
+%   \item Fixed bug related to \opt{extnodes} together with \opt{compname}
+%   \end{release}
 %   \begin{release}{4.8}{2014-02-28}
 %   \item Added component \cs{optaom}\see{comp:optaom}
 %   \item Added option \opt{beammode}\see{prm:beammode}
@@ -13366,7 +13530,7 @@
 %   \item Added option \opt{usewirestyle}\see{prm:usewirestyle}
 %   \item Added line style \opt{fade}, with options \opt{fadeto},
 %     \opt{fadepoints}, \opt{fadefunc}, and
-%     \opt{fadefuncname}\see{prm:fade}
+%     \opt{fadefuncname}\see{prm:fade}.
 %   \end{release}
 %   \begin{release}{4.4}{2013-07-14}
 %   \item Added component \cs{transmissiongrating}\see{comp:transmissiongrating}
@@ -14471,6 +14635,28 @@
 }%
 \psset[optexp]{optboxsize=1.4 0.8}%
 %    \end{macrocode}
+%
+% Box
+%    \begin{macrocode}
+\define@key[psset]{optexp}{sourcewidth}{%
+  \pst@checknum{#1}\POE@key@sourcewidth
+}
+\define@key[psset]{optexp}{sourceheight}{%
+  \pst@checknum{#1}\POE@key@sourceheight
+}
+\define@key[psset]{optexp}{sourcesize}{%
+  \pst@expandafter\POE@psset@@sourcesize{#1} {} {} {}\@nil
+}%
+\def\POE@psset@@sourcesize#1 #2 #3\@nil{%
+  \ifx\\#2\\%
+    \PackageWarning{pst-optexp}{%
+      Parameter 'sourcesize' requires two numbers.}%
+  \fi
+  \psset[optexp]{sourcewidth=#1, sourceheight=#2}%
+}%
+\psset[optexp]{sourcesize=1.4 0.8}%
+%    \end{macrocode}
+%
 % arrowbox
 %    \begin{macrocode}
 \define@key[psset]{optexp}{arrowcompwidth}{%
@@ -15463,7 +15649,7 @@
   \pst@getint{#1}\POE@key@beampathcount
 }%
 \define@choicekey+[psset]{optexp}{beamalign}%
-  [\val\nr]{rel,abs,relative,absolute}%
+  [\val\nr]{rel,abs,relative,absolute,firstcomp}%
   {%
     \ifcase\nr\relax
       \let\POE@key@beamalign\POE@str@relative
@@ -16240,9 +16426,11 @@
      /beamalign 
        \ifx\POE@key@beamalign\POE@str@absolute\space 
          absolute
-       \else 
+       \else\ifx\POE@key@beamalign\POE@str@relative\space
          relative
-       \fi def
+       \else
+         firstcomp
+       \fi\fi def
      /beampathskip \POE@key@beampathskip\space def
      \POE@key@beampathcount\space dup -1 gt { beampathskip add } if /beampathcount ED
      /useNA \ifPOE@useNA true \else false \fi def
@@ -16355,12 +16543,16 @@
     \ifx\pslinestyle\@none\ifx\psk@ArrowInside\@empty 1\else 0\fi\else 0\fi
     \addto@pscode{ cleartomark false false }%
   \else
-    \addto@pscode{%
+%    \end{macrocode}
+% Get the beamproperties from the first component if it is a source.
+%    \begin{macrocode}
+    \POE@HandleSourceBeam
 %    \end{macrocode}
 % I need to pack it this way in order to avoid replacing the \opt{n} inside the
 % code here. This must be done later, when it refers to the correct refractive
 % indices.
 %    \begin{macrocode}
+    \addto@pscode{%
       {/nbeam {\POE@key@n cvx exec} bind def
        \ifPOE@pswarning
          /Warning /PrintWarning load def
@@ -16375,7 +16567,7 @@
           0 exch
         } if
       } ifelse \tx@ScreenCoor] cvx
-      \POE@key@beamangle\space
+      beamangle
       currentdict /lastBeamPointTmp undef
       currentdict /lastVecTmp undef
       loadbeampoints 1 ge 
@@ -16422,7 +16614,37 @@
 \def\POE@strokesinglebeam{%
   gsave 
     /Lineto /lineto load def
-    \tx@Drawbeam 
+    20 dict begin
+      DrawbeamPrepare
+%    \end{macrocode}
+% If there are only three elements or less on the stack, the first ray
+% misses the next interface or is even parallel to the input interface.
+%    \begin{macrocode}
+      counttomark 3 gt { 
+%    \end{macrocode}
+% Define some parameters for Drawbeam which are based on TeX-parameters
+%    \begin{macrocode}
+        \ifx\psk@arrowA\arrowType@H
+          \pst@number\pshooklength
+        \else
+          \psk@arrowsize\space CLW mul add dup \psk@arrowlength\space mul exch \psk@arrowinset mul neg add  
+        \fi
+        /arrowlength exch def 
+        /arrowminlength \POE@key@ArrowInsideMinLength\space\pst@number\psunit mul def
+        /arrowmaxlength \POE@key@ArrowInsideMaxLength\space\pst@number\psunit mul def
+        /arrowpos  \psk@ArrowInsidePos\space def
+        /arrowno   \psk@ArrowInsideNo\space cvi def
+        /ArrowPosStart \psk@ArrowInsideOffset\space def
+        /dArrowPosStart \psk@ArrowInsidePos\space def
+        counttomark 3 idiv /N exch def
+        (\psk@ArrowInside) length 0 gt {
+          DrawbeamArrowInside
+        }{
+          DrawbeamSimple
+        } ifelse
+      } if
+      cleartomark
+    end
     \tx@setlinejoin
     \pst@number\pslinewidth SLW
     \pst@usecolor\pslinecolor
@@ -16437,6 +16659,10 @@
 %    \begin{macrocode}
 \def\drawwidebeam@ii{%
   \def\pst@fill##1{ gsave ##1 grestore }%
+%    \end{macrocode}
+% Get the beamproperties from the first component if it is a source.
+%    \begin{macrocode}
+  \POE@HandleSourceBeam
   \addto@pscode{%
     {/nbeam {\POE@key@n cvx exec} bind def
       \ifPOE@pswarning
@@ -16449,8 +16675,8 @@
 % arrange and create the input vectors
 %    \begin{macrocode}
   \addto@pscode{%
-    \POE@key@beamangle\space dup
-    \POE@key@beamdiv\space 0.5 mul dup 4 -1 roll add 3 1 roll sub
+    beamangle dup
+    beamdiv 0.5 mul dup 4 -1 roll add 3 1 roll sub
   }%
 %    \end{macrocode}
 % the start positions
@@ -16464,12 +16690,14 @@
           0 exch 
         } if
       } ifelse
-      mark \POE@key@beamwidth\space counttomark 0 eq {
-        0 
+%    \end{macrocode}
+% if \opt{beamwidth} is defined at Postscript level, it was defined from the source object.
+%    \begin{macrocode}
+      currentdict /beamwidth known {
+        beamwidth currentdict /beamwidth undef
       } {
-        0.5 mul
-      } ifelse
-      exch pop
+        mark \POE@key@beamwidth\space counttomark 0 eq { 0 } if exch pop
+      } ifelse 0.5 mul
       3 copy add \tx@ScreenCoor\space ToVec 
       5 1 roll sub \tx@ScreenCoor
     ] cvx
@@ -16559,126 +16787,6 @@
 }%
 %    \end{macrocode}
 % \end{macro}
-%
-%    \begin{macrocode}
-\pst@def{Drawbeam}<
-%    \end{macrocode}
-% Remove trailing empty line parts.
-%    \begin{macrocode}
-    { counttomark 6 le {
-        exit
-      } if
-      3 index not {
-        pop pop pop 
-      }{ 
-        exit
-      } ifelse
-    } loop
-%    \end{macrocode}
-% Remove heading empty line parts. Note, that the first point must not have
-% 'draw = true', because it is the starting point which we have to move to.
-%    \begin{macrocode}
-    { counttomark 3 le {
-        exit
-      } if
-      counttomark 3 sub index not {
-        counttomark -3 roll pop pop pop
-      }{
-        exit
-      } ifelse
-    } loop
-%    \end{macrocode}
-%    \begin{macrocode}
-  counttomark 3 le {
-%    \end{macrocode}
-% first ray misses the next interface or is even parallel to the input interface.
-%    \begin{macrocode}
-    cleartomark
-  }{
-%    \end{macrocode}
-% This is the /Line definition from \opt{pstricks-add}, adapted to the beam path
-% structure which includes the boolean values to indicate if a line is drawn, or
-% if we use moveto. There was no way to patch the original definition to account
-% for the moveto parts and avoid duplicating the code.
-%    \begin{macrocode}
-  counttomark 3 div cvi /N ED
-  (\psk@ArrowInside) length 0 gt { 
-    \ifx\psk@arrowA\arrowType@H   % do we have a Hook arrow at the beginning?
-      \pst@number\pshooklength  % yes 
-    \else
-      \psk@arrowsize\space CLW mul add dup \psk@arrowlength\space mul exch \psk@arrowinset mul neg add  
-    \fi
-    /arrowlength exch def 
-    6 copy pop				% copy all four values for the arrow line
-    /y1 ED /x1 ED pop /y2 ED /x2 ED 	% save them
-    /Alpha y2 y1 sub x2 x1 sub Atan def % the gradient of the line
-    pop 3 -1 roll 5 1 roll 
-    ArrowA 
-    x1 Alpha cos arrowlength mul add	% dx add
-    y1 Alpha sin arrowlength mul add	% dy add, to get the current point at the end of the arrow tip
-    5 -1 roll 3 1 roll true
-    /N N 1 sub def
-    N {
-      6 copy pop 
-      /y1 ED /x1 ED pop /y2 ED /x2 ED /draw ED
-%    \end{macrocode}
-% Check for line segment length and draw the arrow only, if the segment is long
-% enough. This is in first place to avoid drawing an inside arrow for the
-% pinhole which has three interfaces instead of one so that it can be used as
-% real spatial filter.
-%    \begin{macrocode}
-      x1 y1 x2 y2 @ABDist dup
-      \POE@key@ArrowInsideMinLength\space\pst@number\psunit mul ge 
-      exch \POE@key@ArrowInsideMaxLength\space\pst@number\psunit mul dup 0 lt 
-        3 1 roll le or and {
-        x1 y1
-        \psk@ArrowInsidePos\space 1 gt {
-          /Alpha y2 y1 sub x2 x1 sub Atan def
-          /ArrowPos \psk@ArrowInsideOffset\space def
-          /dArrowPos \psk@ArrowInsidePos\space abs def
-          \psk@ArrowInsideNo\space cvi {
-            /ArrowPos ArrowPos dArrowPos add def
-            x1 Alpha cos ArrowPos mul add
-            y1 Alpha sin ArrowPos mul add
-            6 index { ArrowInside } if
-            pop pop
-          } repeat
-        }{
-          /ArrowPos \psk@ArrowInsideOffset\space def
-          /dArrowPos \psk@ArrowInsideNo 1 gt {%
-            1.0 \psk@ArrowInsideNo 1.0 add div
-          }{\psk@ArrowInsidePos } ifelse def
-            \psk@ArrowInsideNo\space cvi {
-              /ArrowPos ArrowPos dArrowPos add def
-              x2 x1 sub ArrowPos mul x1 add
-              y2 y1 sub ArrowPos mul y1 add
-              6 index { ArrowInside } if
-              pop pop
-            } repeat
-        } ifelse
-        pop pop
-      } if
-      draw {Lineto}{moveto} ifelse
-    } repeat
-  }{
-    pop 5 copy 3 -1 roll pop 
-    ArrowA pop pop pop pop
-    counttomark 3 idiv -1 2 {
-      pop {
-        lineto
-      }{
-        moveto
-      } ifelse
-    } for
-  } ifelse
-  {CP 4 2 roll ArrowB lineto pop pop } {moveto} ifelse
-%    \end{macrocode}
-% remove the mark
-%    \begin{macrocode}
-  pop
-  } ifelse
->
-%    \end{macrocode}
 % 
 %    \begin{macrocode}
 \def\POE@getcomprange#1-#2\@nil{%
@@ -17322,61 +17430,6 @@
 \let\newOptexpElecComp\newOptexpFiberComp
 %    \end{macrocode}
 % \end{macro}
-%
-% \begin{macro}{\POE@compalias}
-%   Components which have a \opt{compname} assigned, must also be
-%   available by their component number. Here, all necessary
-%   informations (nodes, component dictionary) are referenced such that
-%   any information is accessible via number or name. First parameter is
-%   the component name, second one the component id.
-%    \begin{macrocode}
-\def\POE@compalias#1#2{%
-  \POE@Verb{%
-%    \end{macrocode}
-% Copy the component dictionary
-%    \begin{macrocode}
-    /\oenode{}{#2} dup currentdict exch known { 
-      load /\oenode{}{#1} ED 
-    } { 
-      pop 
-    } ifelse
-    (\oenode{}{#1}) (\oenode{}{#2})
-    tx@NodeDict begin
-%    \end{macrocode}
-% Copy all interface nodes of the component.
-%    \begin{macrocode}
-      1 {
-        3 copy inttostr dup 
-        3 1 roll 2 copy NodeName
-        currentdict exch known {
-          NodeName load 3 1 roll NodeName ED
-          1 add
-        } {
-          pop (N) NodeName load 3 1 roll 
-          pop (N) NodeName ED
-          pop exit
-        } ifelse
-      } loop
-%    \end{macrocode}
-% Copy all other nodes associated with the component (reference nodes, center
-% node, label node etc).
-%    \begin{macrocode}
-      [ (A) (B) (@A) (@B) (Center) (Label) (Rotref) 
-        (TrefA) (TrefB) (@TrefA) (@TrefB) (Ext)
-      counttomark {
-        counttomark 3 add -2 roll 2 copy counttomark 1 add 2 roll
-        3 -1 roll dup 4 1 roll NodeName dup 
-        currentdict exch known { 
-          load 3 1 roll exch NodeName ED 
-        } { 
-          pop pop pop 
-        } ifelse
-      } repeat pop pop pop
-    end
-  }%
-\ignorespaces}%
-%    \end{macrocode}
-% \end{macro}
 % 
 % \begin{macro}{\optplane}
 %   Define an invisible plane which is used only for ray tracing. The first node
@@ -17398,6 +17451,72 @@
 %    \end{macrocode}
 % \end{macro}
 % 
+% \begin{macro}{\POE@SaveBeamParameters}
+%   Save the current beam parameters. This is used to be able to set a
+%   source beam with the usual beam parameters.
+%    \begin{macrocode}
+\def\POE@SaveBeamParameters{%
+  \let\POE@tempA\POE@key@beamangle
+  \let\POE@tempB\POE@key@beamdiv
+  \let\POE@tempC\POE@key@beamwidth
+  \let\POE@tempD\POE@key@beamalign
+  \let\POE@key@beamangle\relax
+  \let\POE@key@beamdiv\relax
+  \let\POE@key@beamwidth\relax
+  \let\POE@key@beamalign\relax
+}%
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\POE@SetSourceAndRestoreBeamParameters}
+%    \begin{macrocode}
+\def\POE@SetSourceAndRestoreBeamParameters{%
+  \let\POE@key@sourcebeamangle\POE@key@beamangle
+  \let\POE@key@sourcebeamdiv\POE@key@beamdiv
+  \let\POE@key@sourcebeamwidth\POE@key@beamwidth
+  \let\POE@key@sourcebeamalign\POE@key@beamalign
+  \let\POE@key@beamangle\POE@tempA
+  \let\POE@key@beamdiv\POE@tempB
+  \let\POE@key@beamwidth\POE@tempC
+  \let\POE@key@beamalign\POE@tempD
+}%      
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\POE@HandleSourceBeam}
+%   Load beam properties from the first component on the stack, if it is
+%   an optical source. Also handle the beamalign=firstcomp case, since
+%   this also depends on the first component.
+%    \begin{macrocode}
+\def\POE@HandleSourceBeam{%
+  \addto@pscode{%
+    counttomark 0 eq not {
+      dup cvn load dup /source known { 
+        /source get { def } forall
+      }{ pop } ifelse
+    } if
+%    \end{macrocode}
+% Handle the beamalign=firstcomp case. Calculate the angle of the first
+% component's reference line and set the beamalign parameter to
+% absolute.
+%    \begin{macrocode}
+    beamalign firstcomp eq {
+      dup dup (Center) NodeName tx@NodeDict exch known not {
+%    \end{macrocode}
+% If we have no node called \opt{\ldots Center}, the first object isn't
+% a component, but a node. Switch to relative alignment.
+%    \begin{macrocode}
+        pop /beamalign relative def
+      } {
+        RelConnAngle@tref exch atan /beamangle exch def
+        /beamalign absolute def
+      } ifelse
+    } if
+  }%
+}%
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\begin@OptexpObj}
 %    \begin{macrocode}
 \def\begin@OptexpObj{%
@@ -17407,7 +17526,9 @@
   \begingroup
     \POE@insideobjtrue
     \POE@Verb{InitOptexpComp }%
+    \POE@SaveBeamParameters
     \use@par
+    \POE@SetSourceAndRestoreBeamParameters
 %    \end{macrocode}
 % The \opt{compshift} refers to the $y$-direction, shifting in $x$-direction
 % is done by \opt{abspos} or \opt{position}
@@ -17463,18 +17584,34 @@
     \POE@transformnode{\oenode@RefB{}}{\oenode@TrefB{}}%
   }%
 }%
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\POE@unsetbeamparameters}
+% Unset some beam parameters which might be used by \cs{optsource}.
+%    \begin{macrocode}
+\def\POE@unsetbeamparameters{%
+  \let\POE@key@beamangle\relax
+  \let\POE@key@beamdiv\relax
+  \let\POE@key@beamwidth\relax
+}%
+%    \end{macrocode}
+% \end{macro}
 %
 % \begin{macro}{\end@OptexpObj}
 %    \begin{macrocode}
 \def\end@OptexpObj{%
   \ifnum9<1\POE@key@compname\else
-    \POE@compalias{\POE@key@compname}{\the\POE@cnt}%
+    \POE@Verb{
+      (\oenode{}{\POE@key@compname})
+      (\oenode{}{\the\POE@cnt}) CompAlias }%
   \fi
   \endgroup
   \ignorespaces%
 }%
 %    \end{macrocode}
 % \end{macro}
+%
 % \begin{macro}{\end@OptexpDipole}
 %    \begin{macrocode}
 \let\end@OptexpDipole\end@OptexpObj
@@ -17736,7 +17873,7 @@
     \ifPOE@backlayer
       \POE@Verb{%
         (1) (3) (\oenode{}{}) CorrectDipoleIfc 
-        (2) (N) (\oenode{}{}) CorrectDipoleIfc 
+        (2) (4) (\oenode{}{}) CorrectDipoleIfc 
       }%
       \ifPOE@fiberpresetin@
         \ifPOE@fiberpresetin@top
@@ -17794,7 +17931,7 @@
     \ifPOE@backlayer
       \POE@Verb{%
         (1) (2) (\oenode{}{}) CorrectDipoleIfc 
-        (1) (N) (\oenode{}{}) CorrectDipoleIfc 
+        (1) (3) (\oenode{}{}) CorrectDipoleIfc 
       }%
       \ifPOE@fiberpresetin@
         \drawfiber@{FiberIn}[stopnode=1](#1){}
@@ -17845,8 +17982,8 @@
     \POE@drawcomponent{wdmcoupler}{#4}
     \ifPOE@backlayer 
       \POE@Verb{%
-        (1) (N) (\oenode{}{}) CorrectDipoleIfc 
-        (2) (N) (\oenode{}{}) CorrectDipoleIfc
+        (1) (3) (\oenode{}{}) CorrectDipoleIfc 
+        (2) (3) (\oenode{}{}) CorrectDipoleIfc
       }%
       \ifPOE@fiberpresetout@
         \drawfiber@{FiberOut}[startnode=N]{}(#3)
@@ -18351,6 +18488,7 @@
 \newOptexpDipole{crystal}
 \newOptexpDipole{polarization}
 \newOptexpDipole{optbox}
+\newOptexpDipole{optsource}{position=start}
 \newOptexpDipole{optplate}
 \newOptexpDipole{optretplate}
 \newOptexpDipole{optdetector}{position=end}
@@ -19509,6 +19647,48 @@
 %    \end{macrocode}
 % \end{macro}
 % 
+% \subsubsection{optsource}
+%
+% \begin{macro}{\optsource@ref}
+%    \begin{macrocode}
+\def\optsource@ref{%
+  \let\POE@key@optboxwidth\POE@key@sourcewidth
+  \let\POE@key@optboxheight\POE@key@sourceheight
+  \optbox@ref
+}%
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\optsource@nodes}
+%    \begin{macrocode}
+\def\optsource@nodes{%
+  \POE@dipole@nodes
+  \POE@Verb{%
+    \oenode{}{} begin
+    4 dict dup /source exch def begin
+      \if\POE@key@sourcebeamangle\relax\else
+        /beamangle \POE@key@sourcebeamangle\space def
+      \fi
+      \if\POE@key@sourcebeamdiv\relax\else
+        /beamdiv \POE@key@sourcebeamdiv\space def
+      \fi
+      \if\POE@key@sourcebeamwidth\relax\else
+        /beamwidth \POE@key@sourcebeamwidth\space def
+      \fi
+      \if\POE@key@sourcebeamalign\relax\else
+        /beamalign \POE@key@sourcebeamalign\space def
+      \fi
+    end
+    source length 0 eq { currentdict /source undef } if
+    end }%
+}%
+%
+% \begin{macro}{\optsource@comp}
+%    \begin{macrocode}
+\let\optsource@comp\POE@comp@rectangle
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsubsection{optplate}
 %
 % \begin{macro}{\optplate@ref}
@@ -20910,7 +21090,7 @@
     \ifPOE@backlayer
       \POE@Verb{%
         (1) (3) (\oenode{}{}) CorrectDipoleIfc 
-        (2) (N) (\oenode{}{}) CorrectDipoleIfc 
+        (2) (4) (\oenode{}{}) CorrectDipoleIfc 
       }%
       \ifPOE@wirepresetin@top
         \drawwire@{WireIn1}[stopnode=1](#1){}
@@ -21281,25 +21461,6 @@ tx@OptexpDict begin
 } bind def
 %    \end{macrocode}
 % \end{macro}
-%
-% \begin{macro}{IfcCopy}
-%   Copy an interface \PSvar{from} to an interface \PSvar{to}, must be called
-%   within the respective component dictionary. This involves also copying the
-%   node associated with the interface.
-%   \begin{pssyntax}
-%     \PSvar{from} \PSvar{to} \PSop{CopyIfc}
-%   \end{pssyntax}
-%    \begin{macrocode}
-/IfcCopy { 
-  2 copy IfcName exch IfcName load dup
-  length dict copy def
-  name exch NodeName name 3 -1 roll NodeName 
-  tx@NodeDict begin
-    load dup length dict copy def
-  end
-} bind def
-%    \end{macrocode}
-% \end{macro}
 % 
 % \begin{macro}{calcNodes}
 %   Calculate the reference node coordinates for reflective components and
@@ -21467,7 +21628,7 @@ tx@OptexpDict begin
   /reverse ED
   dup cvn load /N get dup
   reverse { -1 1 } { 1 1 3 -1 roll } ifelse
-  { 2 copy eq { pop (N) } { inttostr } ifelse
+  { inttostr
     3 -1 roll dup 4 1 roll exch NodeName 3 1 roll
   } for
   pop pop
@@ -21639,10 +21800,24 @@ tx@OptexpDict begin
 % \end{macro}
 % 
 % Define some constants.
+%
+% These are used for checks of the \opt{beamalign} and \opt{fiberalign} parameters.
+%    \begin{macrocode}
+/relative 0 def /absolute 1 def /center 2 def /firstcomp 3 def
+%    \end{macrocode}
+% 
+% These constants are used to describe the characteristics of interfaces.
 %    \begin{macrocode}
-/relative 0 def /absolute 1 def /center 2 def
 /refl 0 def /trans 1 def /absorb 2 def /refltrans 3 def /auto 4 def /undefined -1 def
+%    \end{macrocode}
+% 
+% These give the ordering of the internal interfaces of a component.
+%    \begin{macrocode}
 /desc 0 def /asc 1 def /amb 2 def
+%    \end{macrocode}
+% 
+% The possible status after computing the outgoing vector at an interface.
+%    \begin{macrocode}
 /ok 0 def /tir 1 def /missed 2 def
 /bgRefIndex 0 def
 %    \end{macrocode}
@@ -21724,15 +21899,16 @@ tx@OptexpDict begin
 % only a single plane is specified, create the aliases.
 %    \begin{macrocode}
       name (1) 3 -1 roll {sc} NewCompIfc 
-      (1) (N) IfcCopy
+      (1) (2) IfcCopy
+      (2) (N) IfcAlias
   }{
     N -1 1 { %
-      dup N eq { pop (N) }{inttostr} ifelse
-      exch name 3 1 roll {sc} NewCompIfc
+      inttostr exch name 3 1 roll {sc} NewCompIfc
     } for
+    N inttostr (N) IfcAlias
   } ifelse
   ambiguous ambIfc 0 gt and { 
-    ambIfc N eq { (N) }{ ambIfc inttostr } ifelse (C) IfcCopy
+    ambIfc inttostr (C) IfcCopy
   } if
   end
   pop
@@ -21764,12 +21940,14 @@ tx@OptexpDict begin
 % only a single plane is specified, create the aliases.
 %    \begin{macrocode}
     {0 1} 0 0 trans name (1) {PlainIfc} {sc} NewCompIfc 
-    (1) (N) IfcCopy
+    (1) (2) IfcCopy
+    (2) (N) IfcAlias
   }{
     N -1 1 {
-      dup N eq { pop (N) }{inttostr} ifelse
+      inttostr
       {0 1} 0 0 absorb name 6 -1 roll {PlainIfc} {sc} NewCompIfc
     } for
+    N inttostr (N) IfcAlias
   } ifelse
   end
   pop
@@ -21778,12 +21956,33 @@ tx@OptexpDict begin
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{IfcCopy}
+%   Copy an interface \PSvar{from} to an interface \PSvar{to}, must be called
+%   within the respective component dictionary. This involves also copying the
+%   node associated with the interface.
+%   \begin{pssyntax}
+%     \PSvar{from} \PSvar{to} \PSop{CopyIfc}
+%   \end{pssyntax}
+%    \begin{macrocode}
+/IfcCopy { 
+  2 copy IfcName exch IfcName load dup
+  length dict copy def
+  name exch NodeName name 3 -1 roll NodeName 
+  tx@NodeDict begin
+    load dup length dict copy def
+  end
+} bind def
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{IfcAlias}
 %   Create an alias of an interface. This involves creating also an
 %   alias for the associated node.  Must be called withing
 %   \PSvar{NewOptexpComp}.
 %
-% \PSstring{OrigPN} \PSstring{AliasPN} \PSop{IfcAlias}
+%   \begin{pssyntax}
+%     \PSstring{OrigPN} \PSstring{AliasPN} \PSop{IfcAlias}
+%   \end{pssyntax}
 %    \begin{macrocode}
 /IfcAlias {
   2 copy IfcName exch IfcName load def
@@ -21793,6 +21992,75 @@ tx@OptexpDict begin
 } bind def
 %    \end{macrocode}
 % \end{macro}
+%
+% \begin{macro}{CompAlias}
+%   Components which have a \opt{compname} assigned, must also be
+%   available by their component number. Here, all necessary
+%   informations (nodes, component dictionary) are referenced such that
+%   any information is accessible via number or name. 
+%   \begin{pssyntax}
+%     \PSstring{NameStem} \PSstring{IDStem} \PSop{CompAlias}
+%   \end{pssyntax}
+%    \begin{macrocode}
+/CompAlias {
+%    \end{macrocode}
+% Copy the component dictionary
+%    \begin{macrocode}
+  2 copy cvn dup currentdict exch known { 
+    load def 
+  } { 
+    pop 
+  } ifelse
+  tx@NodeDict begin
+%    \end{macrocode}
+% Copy all interface nodes of the component.
+%    \begin{macrocode}
+  1 {
+    3 copy inttostr dup 
+    3 1 roll 2 copy NodeName
+    currentdict exch known {
+      NodeName load 3 1 roll NodeName ED
+      1 add
+    } {
+      pop (N) NodeName load 3 1 roll 
+      pop (N) NodeName ED
+      pop exit
+    } ifelse
+  } loop
+%    \end{macrocode}
+% Copy all other nodes associated with the component (reference nodes, center
+% node, label node etc).
+%    \begin{macrocode}
+  mark (A) (B) (@A) (@B) (Center) (Label) (Rotref) 
+       (TrefA) (TrefB) (@TrefA) (@TrefB) (Ext) (Origin)
+  counttomark {
+    counttomark 3 add -2 roll 2 copy counttomark 1 add 2 roll
+    3 -1 roll dup 4 1 roll NodeName dup 
+    currentdict exch known { 
+      load 3 1 roll exch NodeName ED 
+    } { 
+      pop pop pop 
+    } ifelse
+  } repeat pop 
+%    \end{macrocode}
+% Copy additional external nodes, the maximum is 8 (all combinations of
+% l, r, t, b, c). Old and new node name stems are still on the stack.
+%    \begin{macrocode}
+  exch 1 1 8 {
+    3 copy
+    (Ext) exch 5 string cvs strcat dup 3 1 roll 
+    NodeName 3 1 roll NodeName
+    dup currentdict exch known {
+      load def pop
+    } {
+      pop pop pop exit
+    } ifelse
+  } for
+  pop pop
+  end
+} bind def
+%    \end{macrocode}
+% \end{macro}
 % 
 % \begin{macro}{GetPlaneVec}
 %   Push the coordinates of the plane vector on the stack, for curved interfaces
@@ -21856,7 +22124,8 @@ tx@OptexpDict begin
 % \end{macro}
 %
 % \begin{macro}{GetIfcCenterCorr}
-% Get the center node of a interface, either by specifying the name of the component and the interface number
+%   Get the coordinates of an interface node. This checks if corrected
+%   coordinates for proper connection handling are available.
 %   \begin{pssyntax}
 %     \PSvar{IfcNum} \PSstring{CompName} \PSop{GetIfcCenterCorr} \PSvar{X|XCorr Y|YCorr}
 %   \end{pssyntax}
@@ -22695,7 +22964,120 @@ tx@OptexpDict begin
 } bind def
 %    \end{macrocode}
 % \end{macro}
-% 
+%
+% \begin{macro}{DrawbeamPrepare}
+%   Prepare the data points for drawing with \PSop{DrawbeamSimple} and
+%   \PSop{DrawbeamArrowInside}.
+%    \begin{macrocode}
+/DrawbeamPrepare {
+%    \end{macrocode}
+% Remove trailing empty line parts.
+%    \begin{macrocode}
+  { 
+    counttomark 6 le { exit } if
+    3 index not { pop pop pop }{ exit } ifelse
+  } loop
+%    \end{macrocode}
+% Remove heading empty line parts. Note, that the first point must not have
+% 'draw = true', because it is the starting point which we have to move to.
+%    \begin{macrocode}
+  { 
+    counttomark 3 le { exit } if
+    counttomark 3 sub index not {
+      counttomark -3 roll pop pop pop
+    }{
+      exit
+    } ifelse
+  } loop
+} bind def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{DrawbeamSimple}
+%    \begin{macrocode}
+/DrawbeamSimple {
+  pop 5 copy 3 -1 roll pop 
+  ArrowA pop pop pop pop
+  counttomark 3 idiv -1 2 {
+    pop {
+      lineto
+    }{
+      moveto
+    } ifelse
+  } for
+  {CP 4 2 roll ArrowB lineto pop pop } {moveto} ifelse
+} bind def
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{DrawbeamArrowInside}
+% This is the /Line definition from \opt{pstricks-add}, adapted to the beam path
+% structure which includes the boolean values to indicate if a line is drawn, or
+% if we use moveto. There was no way to patch the original definition to account
+% for the moveto parts and avoid duplicating the code.
+%    \begin{macrocode}
+/DrawbeamArrowInside {
+  6 copy pop
+  /y1 ED /x1 ED pop /y2 ED /x2 ED
+  /Alpha y2 y1 sub x2 x1 sub Atan def
+  pop 3 -1 roll 5 1 roll 
+  ArrowA 
+%    \end{macrocode}
+% dx add, and dy add, to get the current point at the end of the arrow tip.
+%    \begin{macrocode}
+  x1 Alpha cos arrowlength mul add
+  y1 Alpha sin arrowlength mul add
+  5 -1 roll 3 1 roll true
+  /N N 1 sub def
+  N {
+    6 copy pop 
+    /y1 ED /x1 ED pop /y2 ED /x2 ED /draw ED
+%    \end{macrocode}
+% Check for line segment length and draw the arrow only, if the segment is long
+% enough. This is in first place to avoid drawing an inside arrow for the
+% pinhole which has three interfaces instead of one so that it can be used as
+% real spatial filter.
+%    \begin{macrocode}
+    x1 y1 x2 y2 @ABDist dup
+    arrowminlength ge 
+    exch arrowmaxlength dup 0 lt 
+    3 1 roll le or and {
+      x1 y1
+      arrowpos 1 gt {
+        /Alpha y2 y1 sub x2 x1 sub Atan def
+        /dArrowPos dArrowPosStart abs def
+        /ArrowPos ArrowPosStart def
+        arrowno {
+          /ArrowPos ArrowPos dArrowPos add def
+          x1 Alpha cos ArrowPos mul add
+          y1 Alpha sin ArrowPos mul add
+          6 index { ArrowInside } if
+          pop pop
+        } repeat
+      }{
+        arrowno 1 gt { 
+          1.0 arrowno 1.0 add div
+        }{
+          dArrowPosStart
+        } ifelse /dArrowPos ED
+        /ArrowPos ArrowPosStart def
+        arrowno {
+          /ArrowPos ArrowPos dArrowPos add def
+          x2 x1 sub ArrowPos mul x1 add
+          y2 y1 sub ArrowPos mul y1 add
+          6 index { ArrowInside } if
+          pop pop
+        } repeat
+      } ifelse
+      pop pop
+    } if
+    draw {Lineto}{moveto} ifelse
+  } repeat
+  {CP 4 2 roll ArrowB lineto pop pop } {moveto} ifelse
+} bind def
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{isAmbiguous}
 %   Check if \PSvar{compname} is ambiguous, i.e. if it can have alternating beam
 %   paths depending on the input and output plane (e.g. beamsplitter can either
@@ -23100,11 +23482,7 @@ tx@OptexpDict begin
 %    \begin{macrocode}
             name GetRefIndex
           } ifelse
-          exch dup N eq {
-            pop (N)
-          } {
-            inttostr
-          } ifelse exch
+          exch inttostr exch
           3 1 roll name
           4 1 roll
           dup IfcName load /mode get
@@ -23127,20 +23505,13 @@ tx@OptexpDict begin
 % \end{macro}
 % 
 % \begin{macro}{IfcName}
-% Construct the interface name from \PSvar{num}. This must be called within a dict of a
-% optexpcomp, because the last node ends with (N) instead of the number and we must
-% know the number of component interfaces.
+% Construct the interface name from \PSvar{num}.
 % \begin{pssyntax}
 % \PSvar{num} \PSop{IfcName} \PSname{P@num}
 % \end{pssyntax}
 %    \begin{macrocode}
 /IfcName {
-  dup dup 1 eq not exch N eq and {
-    pop (N)
-  } {
-    inttostr
-  } ifelse
-  (P@) exch strcat cvn
+  inttostr (P@) exch strcat cvn
 } bind def
 %    \end{macrocode}
 % \end{macro}
@@ -23158,9 +23529,7 @@ tx@OptexpDict begin
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{NodeName}
-% Construct the plane name from IfcNum. This must be called within a dict of a
-% optexpcomp, because the last node ends with (N) instead of the number and we must
-% know the plane count of the component.
+% Construct the node name from a string or number.
 % \begin{pssyntax}
 % \PSstring{name} \PSvar{num} \PSop{NodeName} \PSname{N@namenum}
 % \end{pssyntax}
@@ -23884,7 +24253,7 @@ tx@OptexpDict begin
 %   estimation of the fiber connections does not work properly. So these
 %   interfaces are separated as less as possible so that the NearestNode
 %   procedure estimates two different distances. The changed nodes are saved
-%   only in the interface dictionaly as XCorr and YCorr. You must use these for
+%   only in the interface dictionary as XCorr and YCorr. You must use these for
 %   the fiber connections.
 %   \begin{pssyntax}
 %     \PSstring{node1} \PSstring{node2} \PSstring{basename} \PSop{CorrectDipoleIfc}
-- 
cgit v1.2.3

