texlive[60259] Master/texmf-dist: yquant (17aug21)

commits+karl at tug.org commits+karl at tug.org
Tue Aug 17 22:49:48 CEST 2021


Revision: 60259
          http://tug.org/svn/texlive?view=revision&revision=60259
Author:   karl
Date:     2021-08-17 22:49:48 +0200 (Tue, 17 Aug 2021)
Log Message:
-----------
yquant (17aug21)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/yquant/README.md
    trunk/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf
    trunk/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-config.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-env.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex
    trunk/Master/texmf-dist/tex/latex/yquant/yquant.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty

Modified: trunk/Master/texmf-dist/doc/latex/yquant/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/yquant/README.md	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/doc/latex/yquant/README.md	2021-08-17 20:49:48 UTC (rev 60259)
@@ -7,16 +7,18 @@
 
 A detailed reference with lots of examples is provided in the PDF version of this Readme. We will sketch some basic usage.
 
-Now yquant also understands circuits written in the qasm language!
+Now yquant also understands circuits written in the qasm language and provides a simple interface for circuit equations!
 
-## License
-This material is subject to the LaTeX Project Public License 1.3c.
+Support the development:
+- [![PayPal](https://img.shields.io/badge/donate-via%20PayPal-blue.svg?style=flat)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UTR3MRBYJ825A&source=url)
+- ![Bitcoin](https://img.shields.io/badge/donate-BTC-blue.svg?style=flat) 3KBFpoJuA4eSPLGXEf3jicqaV1czhK36fH
+- ![Ethereum](https://img.shields.io/badge/donate-ETH-blue.svg?style=flat) 0xE0F774221290b1E41ea62c2dd9af5dbD3df7c685
 
 ## Examples
-Many more examples and explanations can be found in the [PDF version](https://github.com/projekter/yquant/raw/master/doc/latex/yquant/yquant-doc.pdf) of this Readme.
+Many more examples and explanations can be found in the [PDF version](doc/latex/yquant/yquant-doc.pdf) of this Readme.
 
 ### Simple teleportation circuit
-![ex-01.png](https://github.com/projekter/yquant/raw/master/markdown/ex-01.png)
+![ex-01.png](markdown/ex-01.png)
 ```LaTeX
 \begin{tikzpicture}
   \begin{yquant}
@@ -35,7 +37,7 @@
 ```
 
 ### Three-qubit phase estimation circuit with QFT and controlled-U
-![ex-02.png](https://github.com/projekter/yquant/raw/master/markdown/ex-02.png)
+![ex-02.png](markdown/ex-02.png)
 ```LaTeX
 \begin{tikzpicture}
   \begin{yquant}
@@ -58,7 +60,7 @@
 ```
 
 ### Three-qubit FT QEC circuit with syndrome measurement
-![ex-03.png](https://github.com/projekter/yquant/raw/master/markdown/ex-03.png)
+![ex-03.png](markdown/ex-03.png)
 ```LaTeX
 \begin{tikzpicture}
   \begin{yquant}
@@ -93,34 +95,39 @@
 ```
 
 ### Error correction
-![ex-04.png](https://github.com/projekter/yquant/raw/master/markdown/ex-04.png)
+![ex-04.png](markdown/ex-04.png)
 ```LaTeX
-% \usetikzlibrary{fit, quotes}
+% \usetikzlibrary{quotes}
 \begin{tikzpicture}
   \begin{yquant}
     qubit {} msg[3];
-    [name=inits]
-    qubit {$\ket0$} syndrome[3];
+    nobit syndrome[3];
 
-    [name=scnot0]
-    cnot syndrome[0] | msg[0];
-    cnot syndrome[0] | msg[1];
-    cnot syndrome[1] | msg[1];
-    cnot syndrome[1] | msg[2];
-    cnot syndrome[2] | msg[0];
-    cnot syndrome[2] | msg[2];
-    [name=smeas]
-    dmeter {$M_{\symbol{\numexpr`a+\idx}}$} syndrome;
+    [this subcircuit box style={dashed, "Syndrome Measurement"}]
+    subcircuit {
+       qubit {} msg[3];
+       [out]
+       qubit {$\ket0$} syndrome[3];
+
+       cnot syndrome[0] | msg[0];
+       cnot syndrome[0] | msg[1];
+       cnot syndrome[1] | msg[1];
+       cnot syndrome[1] | msg[2];
+       cnot syndrome[2] | msg[0];
+       cnot syndrome[2] | msg[2];
+
+       dmeter {$M_{\symbol{\numexpr`a+\idx}}$} syndrome;
+    } (msg[-2], syndrome[-2]);
+
     ["Recovery"]
     box {$\mathcal R$} (msg) | syndrome;
     discard syndrome;
   \end{yquant}
-  \node[draw, dashed, fit=(inits-2) (scnot0-p0) (smeas-2), "Syndrome Measurement"] {};
 \end{tikzpicture}
 ```
 
 ### Lots of controls
-![ex-05.png](https://github.com/projekter/yquant/raw/master/markdown/ex-05.png)
+![ex-05.png](markdown/ex-05.png)
 ```LaTeX
 \begin{tikzpicture}
    \begin{yquant*}
@@ -133,4 +140,26 @@
       discard a[2, 3];
    \end{yquant*}
 \end{tikzpicture}
+```
+
+### Circuit equations
+![ex-06.png](markdown/ex-06.png)
+```LaTeX
+% \useyquantlanguage{groups}
+\begin{tikzpicture}
+   \begin{yquantgroup}
+      \registers{
+         qubit {} q[2];
+      }
+      \circuit{
+         h -;
+         cnot q[1] | q[0];
+         h -;
+      }
+      \equals
+      \circuit{
+         cnot q[0] | q[1];
+      }
+   \end{yquantgroup}
+\end{tikzpicture}
 ```
\ No newline at end of file

Modified: trunk/Master/texmf-dist/doc/latex/yquant/yquant-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/doc/latex/yquant/yquant-doc.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -18,7 +18,7 @@
 \usepackage[compat=newest]{yquant}
 \usepackage{braket,hyphenat,microtype,hologo,minted,import,ragged2e}
 \usetikzlibrary{quotes,fit,shapes.symbols,backgrounds,quantikz}
-\useyquantlanguage{qasm}
+\useyquantlanguage{qasm,groups}
 \usepackage{amsmath,adjustbox,cleveref}
 \usepackage[framemethod=tikz]{mdframed}
 % END_FOLD
@@ -217,7 +217,7 @@
       This document outlines the scope and usage of the \Yquant{} package.
       It contains both a reference and a huge number of examples.
       \Yquant{} is a package that makes typesetting quantum circuits easy; the package is available on CTAN.
-      This beta version~0.4.1 \emph{should} be stable and interfaces are not very likely to change in an incompatible way in the future.
+      This beta version~0.5 \emph{should} be stable and interfaces are not very likely to change in an incompatible way in the future.
       \compat{New in 0.4}Sometimes, backwards\hyp incompatible changes are required or advisable, in which case a compatibility setting will allow to revert back to the old behavior (rather, to maximize compatibility, this is an opt\hyp in setting: unless you choose the new behavior, you will get the old one).
       Please do report all issues and desirable additions on \href{https://github.com/projekter/yquant/issues}{GitHub}.
 
@@ -333,7 +333,7 @@
             This allows certain features that are expected to break old layout or functionality to revert to their previous behavior.
             Every feature affected by the \texttt{compat} key is documented in this manual.
             Once a compatibility version is selected in a document, it cannot be changed any more.
-            Compatibility versions will include the major and minor, but not the patch level version number.
+            Compatibility versions will include the major and minor, but not the patch level version number (though not every major or minor version will necessarily introduce new compatibility versions).
             Bugs that clearly violated behavior described in this manual will be fixed without a possibility to revert back.
             Changes that are not supposed to result in a (more than marginally) different result will not be included in the compatibility layer.
             If you find this to be wrong in a particular case, please file a bug report.
@@ -962,6 +962,34 @@
             Hence, the most prominent application of this key is if the wires before and after the subcircuit are \gate{nobit}s, which provides a clean way to build up circuit equations with perfectly aligned wires (examples can be found in \cref{sec:examples}).
          \end{option}
 
+         \begin{option}[New in 0.5]{operators/subcircuit/name mangling}!prefix or discard!
+            This option defines how named nodes within subcircuits are made available to the outer circuit:
+            \begin{itemize}
+               \item \texttt{prefix or discard} \\
+                  If the subcircuit itself has a name $s$ and the inner gate has a name $g$, the outer circuit can refer to the inner gate via the name \texttt{$s$-$g$}.
+                  Note that $s$ itself may not only consist of the user\hyp specified name, but may instead already be suffixed by \texttt{-0}, \texttt{-1}, \dots, if the subcircuits were assigned to multiple targets.
+
+                  If the subcircuit itself has no name, works as \texttt{discard}.
+               \item \texttt{prefix or transparent} \\
+                  If the subcircuit itself has a name, as works as \texttt{prefix or discard}; else, works as \texttt{transparent}.
+               \item \texttt{transparent} \\
+                  The inner gates are always available in the outer circuit by their original names.
+                  Note that this may potentially lead to naming conflicts, which are always resolved by the latest name overwriting all previous declarations without notice.
+               \item \texttt{discard} \\
+                  The inner gates will not be available in the outer circuit.
+            \end{itemize}
+            Note that if a new gate is defined via \tex!\yquantdefinegate!---which internally uses subcircuits---the value of this option at the time of declaration is the relevant one, not the one at the time of usage.
+            This can be influenced via \style{/yquant/operators/subcircuit/name mangling reset}.
+         \end{option}
+
+         \begin{option}[New in 0.5]{operators/subcircuit/name mangling reset}!true!
+            The current value of \style{/yquant/operators/subcircuit/name mangling} will be reset at the beginning of a subcircuit to the value it had upon declaration of the subcircuit only if this option is \texttt{true} upon \emph{using} the subcircuit (which typically will only make a difference if the subcircuit was defined via \tex!\yquantdefinegate! at some earlier stage).
+            \begin{warning}
+               Setting this value to \tex!false! has the potential of breaking the corresponding subcircuit/custom gate, as it may internally reference gates by names that are no longer the correct ones.
+               Do not use this property without a very good reason and thorough understanding of what is happening.
+            \end{warning}
+         \end{option}
+
          \begin{option}[New in 0.4]{operators/subcircuit/seamless}!/yquant/operators/subcircuit/frameless, /yquant/register/default name=, /yquant/circuit/seamless!
             This option carries out multiple actions that are responsible to let the current subcircuit appear in a ``seamless'' state:
             \begin{itemize}
@@ -1024,6 +1052,7 @@
          All nodes in the subcircuit will then have the name \texttt{\textit{<subcircuit name>}-\textit{<name specified in the subcircuits>}}.
          Note that here, \texttt{\textit{<subcircuit name>}} is the \emph{full} name of the subcircuit, which includes the \tex!-\idx! suffix, \compat{New in 0.4.1}unless there is only a single target register.
          For nested subcircuits, you will get multiple prefixes.
+         \compat{New in 0.5}The prefixing behavior can be influenced by \style{/yquant/operators/subcircuit/name mangling}.
 
       \subsection{Shapes and the drawing pipeline}
          All \Yquant{} shapes have the anchors available you would typically expect from a \TikZ{} shape of the given outline.
@@ -1402,6 +1431,8 @@
          \begin{itemize}
             \item \compat{New in 0.4}\yquant!frameless! \\
                This \style{/yquant/operators/subcircuit/frameless} style is activated with this shorthand.
+            \item \compat{New in 0.5}\yquant!name mangling! \\
+               This shorthand will pass the value of the attribute directly to the configuration key \style{/yquant/operators/subcircuit/name mangling}.
             \item \compat{New in 0.4}\yquant!seamless! \\
                The \style{/yquant/operators/subcircuit/seamless} style is activated with this shorthand (implies \yquant!frameless!).
             \item \yquant!value=<subcircuit>! (required) \\
@@ -1871,42 +1902,27 @@
          As the \pkg{qcircuit} manual uses a bit larger separation between the operators than \Yquant's default, we globally say\\*\tex!\yquantset{operator/separation=1em}!.
 
          \subsubsection{I. Introduction}
-            \begin{example}<Updated in 0.4, 0.1.1>%
+            \begin{example}<Updated in 0.5, 0.4, 0.1.1>%
                \begin{codeexample*}
-\begin{tikzpicture}
-   \begin{yquant}[operators/subcircuit/frameless]
-      nobit q[3];
-
-      subcircuit {
-         [out]
-         qubit {} q[3];
-         box {$U$} q[2] | q[0, 1];
-      } (q);
-      discard -;
-
-      [draw=none]
-      box {$=$} (-);
-
-      subcircuit {
-         [out]
-         qubit {} q[3];
-         box {$V$} q[2] | q[1];
-         cnot q[1] | q[0];
-         box {$V^\dagger$} q[2] | q[1];
-         cnot q[1] | q[0];
-         box {$V$} q[2] | q[0];
-      } (q);
-      discard -;
-   \end{yquant}
-\end{tikzpicture}
+% \useyquantlanguage{groups}
+\begin{yquantgroup}
+   \registers{
+      qubit {} q[3];
+   }
+   \circuit{
+      box {$U$} q[2] | q[0, 1];
+   }
+   \equals
+   \circuit{
+      box {$V$} q[2] | q[1];
+      cnot q[1] | q[0];
+      box {$V^\dagger$} q[2] | q[1];
+      cnot q[1] | q[0];
+      box {$V$} q[2] | q[0];
+   }
+\end{yquantgroup}
                \end{codeexample*}
-               The best way to realize circuit equalities is with the help of \texttt{frameless} subcircuits.
-               The \texttt{[frameless]} attribute can either be specified on each subcircuit individually or, as done here, globally via the corresponding style.
-               In this way, we can specify all subcircuits individually.
-               All wires that are identical in the circuits must be outer wires; but in fact, we do not want them to be visible outside of the subcircuits.
-               Consequently, we initialize them in the outer circuit as \gate{nobit}s, declare them with the \texttt{[out]} attribute, and discard them right after the subcircuit.
-               It is important not to discard them within the subcircuit, as the wires would then not extend to the same horizontal final position.
-               The equality sign is realized very easily by means of a \gate{box} gate that spans all registers and from which we remove the border.
+               The best way to realize circuit equalities is with the help of \pkg{groups} language extension, which is documented in \cref{sec:foreign:groups}.
             \end{example}
 
             \begin{example}<Updated in 0.4>
@@ -2494,7 +2510,7 @@
 
                   In general, any macros that are used within a \TikZ{} path or a \Yquant{} operation must not be fragile, or must be preceded with \tex!\protect!.
                   In this example, \tex!\\! is a robust command (at least in newer kernels), so protection is not required.
-                  Since it may occur quite frequently that \Yquant{} is used within a \tex!center! environment or in \tex!\centering! mode (in which \tex!\\! is still fragile), \Yquant{} takes care of this (it actually robustifies \tex!\@centercr!, which is the meaning of \tex!\\! in these surroundings).
+                  Since it may occur quite frequently that \Yquant{} is used within a \tex!center! environment or in \tex!\centering! mode (in which \tex!\\! is still fragile), \Yquant{} takes care of this (it actually robustifies \tex!\@centercr!, which is the meaning of \tex!\\! in these surroundings---and which is now incorporated into the \LaTeX{} kernel as of June~2021).
 
                   In order to change the style of an individual wire, we use \gate{addstyle}.
                   To make the final line shorter, we change the operator separation by issuing \tex!\yquantset! at the end.
@@ -2824,7 +2840,6 @@
 
             \Yquant{} does not provide a mechanism for vertical labels, but you may of course just insert line breaks at appropriate positions (and set the \texttt{align} property of the labels).
 
-         \clearpage
          \subsubsection{VI. Spacing}
             \paragraph{A. Local adjustment}\leavevmode
                \begin{example}<Updated in 0.4>
@@ -2872,6 +2887,7 @@
                   Also note that the \style{/yquant/operator/minimum width} style is unsuitable for the given task: it would not change the visual width, only what \Yquant{} assumes its width to be.
                \end{example}
 
+            \clearpage
             \paragraph{B. Global Adjustment}\leavevmode
                \begin{example}
                   \begin{codeexample*}
@@ -2902,7 +2918,7 @@
 
             \clearpage
             \paragraph{C. Alignment}\leavevmode
-               \begin{example}<Updated in 0.4>
+               \begin{example}<Updated in 0.5, 0.4>
                   \begin{codeexample}
 \begin{tikzpicture}
    \begin{yquant*}
@@ -2920,123 +2936,84 @@
                   \end{codeexample}
                   Not specifying anything for the vertical alignment will lead to the common \TikZ{} problem: the baseline will be at the bottom, which is particularly bad in this case due to the missing $X$ gate.
                   The keys for minimal register sizes do not help here, since they only affect \Yquant's internal handling, but not the bounding box calculated by \TikZ.
-                  The recommended way to draw circuit equations is always with \texttt{frameless} \gate{subcircuit}s; only this will guarantee perfect wire alignment in all cases.
+                  The recommended way to draw circuit equations is always with the \pkg{groups} language extension.
 
                   \begin{codeexample}
-\begin{tikzpicture}
-   \begin{yquant}
-      nobit q[2];
-
-      [frameless]
-      subcircuit {
-         [out]
-         qubit {} q[2];
-         x q[0];
-         cnot q[1] | q[0];
-      } (q);
-      discard -;
-
-      [draw=none]
-      box {$=$} (q);
-
-      [frameless]
-      subcircuit {
-         [out]
-         qubit {} q[2];
-         cnot q[1] | q[0];
-         x q;
-      } (q);
-      discard -;
-   \end{yquant}
-\end{tikzpicture}
+% \useyquantlanguage{groups}
+\begin{yquantgroup}
+   \registers{
+      qubit {} q[2];
+   }
+   \circuit{
+      x q[0];
+      cnot q[1] | q[0];
+   }
+   \equals
+   \circuit{
+      cnot q[1] | q[0];
+      x q;
+   }
+\end{yquantgroup}
                   \end{codeexample}
                \end{example}
 
-               \begin{example}<New in 0.4>
+               \clearpage
+               \begin{example}<Updated in 0.5\\New in 0.4>
                   \begin{codeexample*}
-\begin{tikzpicture}
-   \begin{yquant}
-      qubit {$\ket x$} q;
-      qubit {$\ket y$} q[+1];
+% \useyquantlanguage{groups}
+\begin{yquantgroup}
+   \registers{
+      qubit {} q[2];
+   }
+   \circuit{
+      init {$\ket x$} q[0];
+      init {$\ket y$} q[1];
 
-      [seamless]
-      subcircuit {
-         [in]
-         qubit {} q[2];
+      h q[0];
+      cnot q[1] | q[0];
+      output {} (-);
+   }
+   \equals[$\mapsto\quad\ket{\psi_{x, y}}\quad\mapsto$]
+   \circuit{
+      init {} (q);
+      cnot q[1] | q[0];
+      h q[0];
 
-         h q[0];
-         cnot q[1] | q[0];
-         output {\quad$\mapsto$} (-);
-      } (q);
-
-      [draw=none, inner sep=0pt]
-      box {$\ket{\psi_{x, y}}$} (q);
-
-      [seamless]
-      subcircuit {
-         [out]
-         qubit {} q[2];
-
-         init {$\mapsto$\quad} (q);
-         cnot q[1] | q[0];
-         h q[0];
-      } (q);
-
       output {$\ket x$} q[0];
       output {$\ket y$} q[1];
-   \end{yquant}
-\end{tikzpicture}
+   }
+\end{yquantgroup}
                   \end{codeexample*}
                   Here, we do not have a circuit equation (i.e., logical statements involving multiple rather independent circuits), but a circuit progression.
-                  We start with some ``outer'' states (note we could again have used the \tex!\symbol! trick to make the declaration a bit shorter), let them enter into the first subcircuit and define an output of this.
-                  In the opposite way, we proceed after giving the state.
-                  Where to put the actual labels (e.g., the \gate{box} could also have contained $\mapsto \ket{\psi_{x, y}} \mapsto$ and the \gate{output} and \gate{init} gates could have been empty) is up to the user.
-
-                  Note that we used \texttt{seamless} instead of \texttt{frameless}, which gives a tighter spacing that is more suitable if initializers or outputs are present.
+                  Since only in one circuit we have a description of the registers, we declare them without an initial text and put their initialization into \gate{init} gates.
+                  The mapping in between is done by using the optional argument of the \tex!\equals! macro.
+                  In order to obtain the braces at the ends, we use empty \gate{output} and \gate{init} gates.
                \end{example}
 
                \clearpage
                \subparagraph{1. Perfecting Vertical Alignment}\leavevmode
-                  \begin{example}<Updated in 0.4>
+                  \begin{example}<Updated in 0.5, 0.4>
                      \begin{codeexample*}
-\begin{tikzpicture}
-   \begin{yquant}
-      nobit q[2];
-
-      [frameless]
-      subcircuit {
-         [out]
-         qubit {} q;
-         [out]
-         qubit {$\ket0$} q[+1];
-
-         cnot q[0] | q[1];
-         cnot q[1] | q[0];
-         cnot q[0] | q[1];
-      } (q);
-      discard -;
-
-      [draw=none]
-      box {$=$} (q);
-
-      [frameless]
-      subcircuit {
-         [out]
-         qubit {} q;
-         [out]
-         qubit {$\ket0$} q[+1];
-
-         cnot q[1] | q[0];
-         cnot q[0] | q[1];
-      } (q);
-      discard -;
-   \end{yquant}
-\end{tikzpicture}
+% \useyquantlanguage{groups}
+\begin{yquantgroup}
+   \registers{
+      qubit {} q;
+      qubit {$\ket0$} q[+1];
+   }
+   \circuit{
+      cnot q[0] | q[1];
+      cnot q[1] | q[0];
+      cnot q[0] | q[1];
+   }
+   \equals
+   \circuit{
+      cnot q[1] | q[0];
+      cnot q[0] | q[1];
+   }
+\end{yquantgroup}
                      \end{codeexample*}
-                     Using \gate{subcircuit}s here looks like an overkill, but it is the best way both for logical consistency and also to achieve perfect horizontal alignment.
                   \end{example}
 
-            \clearpage
             \paragraph{D. Scaling}\leavevmode
                \begin{example}
                   \begin{codeexample*}
@@ -3054,6 +3031,7 @@
                   In earlier versions, there was a bug that required \Yquant{} to reset the \texttt{transform shape} key for \texttt{label}s, which would then require you to scale those manually.
                \end{example}
 
+         \clearpage
          \subsubsection{VII. Typesetting}
             \paragraph{A. Global Styling}\leavevmode
                \begin{example}
@@ -3106,7 +3084,6 @@
                   \Yquant{} properly splits discontiguous multi\hyp qubit operations.
                \end{example}
 
-            \clearpage
             \paragraph{B. Per-Gate Styling}\leavevmode
                \begin{example}<Updated in 0.4>
                   \begin{codeexample}
@@ -3200,7 +3177,6 @@
                   Here, we used the key \style{/yquant/this subcircuit box style} to influence only the style of the subcircuit box itself instead of providing global options that apply to every object in the subcircuit (you wouldn't want the label be assigned to every single gate).
                \end{example}
 
-               \clearpage
                \begin{example}<Updated in 0.4>
                   \begin{codeexample*}
 % \usetikzlibrary{quotes}
@@ -3278,10 +3254,168 @@
             \end{example}
       \endgroup
 
-   \section{Foreign language support}\label{sec:foreign}
+   \section{Foreign language support and extensions}\label{sec:foreign}
       \Yquant{} is built in various modules, so that it is not hard to use the quantum circuit rendering backend, but expose a different language frontend.
       \compat{New in 0.3}\Yquant{} not only understands its own language, but also others.
+      \compat{New in 0.5}Although we refer to ``foreign languages,'' additional extension packages of the \Yquant{} language itself are also covered in this section and can be loaded by the same syntax.
 
+      \subsection[groups]{\compat{New in 0.5}groups}\label{sec:foreign:groups}
+         By saying \tex!\useyquantlanguage{groups}! in the preamble after loading \Yquant{} itself, additional support for groups of \Yquant{} circuits is loaded.
+         Various circuits in a group share a common set of registers, are appropriately aligned horizontally if on the same line and can also be aligned vertically among multiple lines.
+         The main intended use is for circuit equations.
+
+         This extension provides the environment \tex!yquantgroup!.
+         You may use this environment within a \tex!tikzpicture!; in this case, all page\hyp break related features are not available.
+         You may alternatively use the environment outside of a \tex!tikzpicture!; in this case, it will start and end the pictures appropriately.
+
+         As with \tex!yquant!, the environment accepts optional options that are passed to \tex!\yquantset!; a starred form is available that allows for the lazy creation of registers---but note that \emph{shared} registers must always be created explicitly; only if some circuits in the group have additional registers, the lazy creation applies.
+
+         \subsubsection{General usage}
+            \begin{minted}{tex}
+% preamble:
+% \usepackage[compat=<version>]{yquant}
+% \useyquantlanguage{groups}
+\begin{tikzpicture}% tikz options possible. This environment may be omitted.
+   % tikz commands go here
+   \begin{yquantgroup}% yquant(group) options possible.
+      \registers{
+         % arbitrary shared register declaration go here
+      }
+      % any of \circuit, \equals, \\, \shiftright
+      % if the tikzpicture environment was omitted: also allows
+      % \pagebreak, \newpage, \clearpage, \cleardoublepage
+      % in most cases, TikZ commands are also allowed
+   \end{yquantgroup}
+   % tikz commands go here
+\end{tikzpicture}
+            \end{minted}
+
+         \subsubsection{Special macros}
+            \paragraph*{\tex!\registers!}
+               The \tex!\registers! macro can and must only be used once in a \tex!yquantgroup! environment.
+               It contains the declaration of all the registers that are shared among the various circuits within a group.
+               Basically, if you follow the convention in a usual \Yquant{} circuit to first declare all the registers, then use the gates, then you would put the declaration part in the \tex!\registers! macro.
+               However, note that it is in principle also possible to mix register declarations with other gates and \TikZ{} commands.
+
+               In case you do not use the \gate{import} gate in any of the circuits within the group and you do not declare own registers, the behavior is very straightforward: basically, the content of \tex!\registers! is copied verbatim at the beginning of each circuit.
+               Otherwise, the general rule is: importing a register will ensure that all non\hyp declaration commands that preceded this register declaration are executed; and importing the last register will additionally execute all succeeding commands within \tex!\registers!.
+
+            \paragraph*{\tex!\circuit[<style>]{<content>}!}
+               The \tex!\circuit! macro can be thought of as starting a \tex!yquant! (or \tex!yquant*!) environment and using its mandatory argument \tex!<content>! as the content of the circuit; the optional \tex!<style>! is used to apply additional styling options to the circuit.
+
+               This is not entirely accurate: In reality, the content is put into a \gate{subcircuit} and \tex!<style>! is passed as arguments to the subcircuit.
+
+               The default style \style{/yquant/operators/every group circuit} is applied to the circuit.
+               This style is configured such that the illusion of working in a top\hyp level \tex!yquant! environment is very convincing: The circuit is frameless by default and uses the transparent name mangling scheme.
+
+               All the registers that were previously defined via \tex!\registers! are automatically available within the circuit, as if their declaration had been copied.
+               In fact, \Yquant{} will make a register available the first time it is referenced in some gate; if at the end of a circuit some of the shared registers were not used, they will be imported before exiting the circuit.
+               Consequently, if you define own registers just for a single circuit, these will always be at the very top.
+               This can be influenced by means of the \gate{import} gate, which is only available in group \tex!\circuit!s.
+               This gate allows to import a declared register at an arbitrary position.
+
+            \paragraph*{\tex!\equals*[<content>]!}\label{sec:foreign:groups:equals}
+               The \tex!\equals! macro inserts a blank text---internally, a \gate{box}\hyp like gate with the style \style{/yquant/operators/every group equals}---that contains \tex!<content>!.
+               If omitted, \tex!<content>! is given by \tex!$=$!.
+
+               The optional star will put a horizontal alignment mark at the position where the box is inserted.
+               Similar to the \tex!&! operation in \pkg{amsmath}'s \tex!align! environment or the \tex!\>! in \TeX's native \tex!tabbing!, \Yquant{} will now remember the horizontal position of the box internally and will allow you to directly jump to this position in the next line.
+               Note that you may well have multiple alignment marks in a single line, which \Yquant{} internally numbers \texttt{1}, \texttt{2}, \dots.
+
+            \paragraph*{\tex!\\[<separation>]!}
+               The \tex!\\! macro inserts a line break (never a page break), so that the next \tex!\circuit! or \tex!\equals! will be put below all circuits that were output before, and it will again start at the same left position as the first circuit.
+               The default vertical distance is given by \style{/yquant/group/line separation}, but it may be overwritten by the optional \tex!<separation>! argument, which must be a \TeX{} dimension.
+
+               Note that if you \emph{set} new alignment marks in a new line, this will delete the alignment marks that were previously set.
+
+               If the option \style{/yquant/group/aligned} is passed to the \tex!yquantgroup! environment, the command \tex!\shiftright! is implied after each linebreak.
+
+            \paragraph*{\tex!\shiftright*[<where>]!}
+               The \tex!\shiftright! command will put the ``cursor,'' i.e., the horizontal position at which the next \tex!\circuit! or \tex!\equals! will start, at the position specified by \tex!<where>!.
+               By default, \tex!<where>! is \tex!1!.
+               If the optional star is present, \Yquant{} will additionally put an alignment mark at this position (see the documentation for \hyperref[sec:foreign:groups:equals]{\tex!\equals!}).
+               If the option \style{/yquant/group/aligned} is passed to the \tex!yquantgroup! environment, the command \tex!\shiftright! is implied after each linebreak or starred page break.
+
+               The option \tex!<where>! can take various forms:
+               \begin{itemize}
+                  \item It may be a natural number \texttt{1}, \texttt{2}, \dots, denoting the number of an alignment mark specified in a previous line.
+                  \item It may be the number \texttt{0}, denoting the very beginning of the line; this is useful if the \style{/yquant/group/aligned} option is given, but for a specific line, no alignment should be performed.
+                  \item It may be a \TeX{} dimension, in which case this dimension is directly added to the cursor (so it is a relative value).
+                     This is where passing the optional star makes most sense.
+                     If you want to position absolutely, you may first issue \tex!\shiftright[0]! followed by a shift by the dimension that you want.
+               \end{itemize}
+
+               \begin{warning}
+                  The macro is named \tex!\shiftright!; however, \Yquant{} does not enforce that the actual position is to the right of the current position.
+                  You may indeed be able to create overlapping circuits if you shift back to a previous position.
+               \end{warning}
+
+            \paragraph*{\tex!\pagebreak*!, \tex!\newpage*!, \tex!\clearpage*!, \tex!\cleardoublepage*!}
+               The page breaking commands are available only if the \tex!yquantgroup! was not enclosed in a \tex!tikzpicture!.
+               They will end the current picture environment, issue the original page breaking command, and start a new picture.
+               Hence, if you want to pass options globally to the picture, you should use the \style{/yquant/preamble} option for the \tex!yquantgroup!; the content of this key will be passed as options for every implicitly started \tex!tikzpicture!.
+
+               Usually, remembering the horizontal alignment marks on a new page does not make much sense.
+               For this reason, the commands will delete all alignment; use their starred versions to retain them.
+               If the option \style{/yquant/group/aligned} is passed to the \tex!yquantgroup! environment, the command \tex!\shiftright! is implied after the starred version of the page break.
+
+               Typically, you will not want to refer to named gates in a circuit on a different page; remember that if you need this feature, you must pass the \texttt{remember picture} key in the \style{/yquant/preamble} option, as this is a reference to another \tex!tikzpicture!.
+               Also don't forget to use the (\TikZ) \texttt{overlay} key on the corresponding path that references the node in order not to mess up with the bounding box (see the \TikZ{} documentation for those two keys).
+
+            \subsubsection{Configuration}
+               Loading the \pkg{groups} language extension will define several new configuration keys.
+
+               \begin{option}{group/every group}!!
+                  Style that is installed for every \tex!yquantgroup! and \tex!yquantgroup*! environment, as if it had been given as an option.
+                  The style's default path is \texttt{/tikz}.
+               \end{option}
+
+               \begin{option}{group/line separation}!5mm!
+                  This is the default vertical line separation that is inserted whenever a new line is issued in a \tex!yquantgroup!.
+               \end{option}
+
+               \begin{option}{group/aligned}!false!
+                  This boolean flag defines whether \tex!\shiftright! is automatically issued after \tex!\\! and the starred page breaking commands.
+               \end{option}
+
+               \begin{option}{preamble}!!
+                  This style may only be passed to the \tex!yquantgroup! alignment directly as an option; it is not available via \tex!\yquantset! and the like.
+                  It is only relevant if the \tex!yquantgroup! is not contained in a \tex!tikzpicture!.
+                  The content of this style will be given as an optional argument to the \tex!tikzpicture!; this is the recommended way to specify \TikZ{} options, as they are automatically preserved among page breaks.
+               \end{option}
+
+               \begin{option}{operators/every group circuit}!/yquant/operators/every subcircuit, /yquant/operators/subcircuit/frameless, /yquant/operators/subcircuit/name mangling=transparent!
+                  This style is installed for the \gate{subcircuit} that implicitly wraps each \tex!\circuit!.
+                  Note that some magic is carried out to ensure that the name mangling setting only applies to the \emph{direct} content of the \tex!\circuit!; any \gate{subcircuit}s within the \tex!\circuit! will use the default name mangling scheme.
+               \end{option}
+
+               \begin{option}{operators/every group equals}!shape=yquant-rectangle, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm!
+                  This style is installed for every \tex!\equals!, which is internally realized similarly to a \gate{box} gate.
+               \end{option}
+
+            \subsubsection{Gates and operations}
+               No gates or operations may be used directly within the \tex!yquantgroup! environment, but all the usual \Yquant{} gates and operations are available within \tex!\registers! and \tex!\circuit!.
+               Additionally, within \tex!\circuit!, the \gate{import} gate is available.
+
+               \paragraph*{\yquant!import!}\label{gate:import}\leavevmode\\
+                  Syntax: \yquant!import <target>;! \\
+                  This is a pseudo\hyp gate that makes all the outer registers given in \tex!<target>! available in the current circuit.
+                  Consequently, the register names that are specified in \tex!<target>!, also ranges, do not refer to the registers in the \emph{current} \tex!\circuit!, but instead to those defined via \tex!\registers!.
+                  Therefore, it is for example possible to import all outer registers at once using \yquant!import -;!.
+                  Vector registers can also be imported partially.
+
+                  If additional content (\TeX{} commands such as \TikZ{} paths, non\hyp creation gates) is used within \tex!\registers!, everything that comes \emph{before} the declaration of a register will be copied into the \tex!\circuit! when the register is imported; for a vector, this refers to the index zero.
+                  Additionally, any additional content that comes \emph{after} the declaration of the last register will be copied directly after the last register was imported.
+
+                  \begin{warning}[Out-of-order importing]
+                     Note that it is principle possible to import registers out\hyp of\hyp order.
+                     Since matching outer and inner wires in subcircuits is done in the order in which they appear, this will lead to inner registers with names that do not match their outer registers and is probably highly undesirable.
+                  \end{warning}
+
+                  Usually, this gate will not be needed as \Yquant{} will automatically import an outer register upon its first use.
+
+                  \emph{Possible attributes:} none
+
       \subsection{qasm}\label{sec:foreign:qasm}
          By saying \tex!\useyquantlanguage{qasm}! in the preamble after loading \Yquant{} itself, the parser for \pkg{qasm} (not OpenQASM) is loaded.
          It provides the environment \tex!qasm! as well as the macro \tex!\qasmimport!, which works similarly to \tex!\yquantimport! (but does not accept additional options).
@@ -3342,7 +3476,8 @@
             The following command is then used to print all of them:
             \begin{minted}{tex}
 % preamble:
-% \usepackage{yquant,import}
+% \usepackage[compat=<version>]{yquant}
+% \usepackage{import}
 % \useyquantlanguage{qasm}
 \def\yquantimportpath{qasm/}
 \foreach \circuitno in {1, ..., 18} {
@@ -3429,9 +3564,18 @@
       \subsection*{2021-03-27: Version 0.4}
          New gate: \gate{inspect}. Various bug fixes. \\
          Introduce the \texttt{direct control} feature: \gate{measure} gates can now substitute positive controls of future gates.
-      
+
       \subsection*{2021-07-03: Version 0.4.1}
          Fix \href{https://github.com/projekter/yquant/issues/9}{\#9}: Output bracket misaligned. \\
          Fix \href{https://github.com/projekter/yquant/issues/10}{\#10}: Unable to access node in subcircuit. As of this version, named nodes in subcircuits will also be properly aliased if there is only a single target subcircuit (so that you don't need to use the \texttt{-0} suffix for the subcircuit's name).
+
+      \subsection*{2021-08-17: Version 0.5}
+         Improvement: Active outer canvas transformations (\TikZ{} shifts, scalings, rotations) should be supported more nicely (no guarantees!). \\
+         Improvement: Custom gates (\tex!\yquantdefinegate!) can now contain \TikZ{} \tex!\path!\hyp like commands without the \tex!\noexpand! prefix. \\
+         Improvement: Automatically discard wires \emph{inside} a subcircuit (even if they had the \texttt{out} or \texttt{inout} attribute) if they are discarded directly after the subcircuit \emph{and} they have output gates within the subcircuit (else, the wire would be re\hyp drawn from the output to the border of the subcircuit). \\
+         Bugfix: Referencing named gates in nested subcircuits now works without producing an error (worked before, but gave errors). \\
+         Bugfix: Properly handle the \texttt{direct control} feature if it was specified, but not used until the end of the (sub)circuit. \\
+         Introduce name mangling options for subcircuits. \\
+         Implement \href{https://github.com/projekter/yquant/issues/11}{\#11}: Circuit equations. As of this version, the \pkg{groups} language is available that allows to easily implement circuit equations.
 %END_FOLD
 \end{document}
\ No newline at end of file

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-config.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-config.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-config.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -221,6 +221,17 @@
       {\pgfkeysalso{/yquant/operators/subcircuit/frameless, /yquant/register/default name=}%
        \letcs\yquant at prevseamless{\yquant at prefix seamless}%
        \yquant at config@circuit at seamlesstrue},
+   operators/subcircuit/name mangling/.is choice,%
+   operators/subcircuit/name mangling/prefix or discard/.code=%
+      {\def\yquant at config@operator at subcircuit@mangling{0}},%
+   operators/subcircuit/name mangling/prefix or transparent/.code=%
+      {\def\yquant at config@operator at subcircuit@mangling{1}},%
+   operators/subcircuit/name mangling/transparent/.code=%
+      {\def\yquant at config@operator at subcircuit@mangling{2}},%
+   operators/subcircuit/name mangling/discard/.code=%
+      {\def\yquant at config@operator at subcircuit@mangling{3}},%
+   operators/subcircuit/name mangling reset/.is if=%
+      yquant at config@operator at subcircuit@manglingreset,
    operators/every swap/.style=%
       {shape=yquant-swap, radius=.75mm, draw},%
    operators/every wave/.style=%
@@ -272,4 +283,13 @@
 \newif\ifyquant at config@operator at position@advance
 \yquant at config@operator at position@advancetrue
 \newif\ifyquant at config@circuit at seamless
-\newif\ifyquant at config@operator at multi
\ No newline at end of file
+\def\yquant at config@operator at subcircuit@mangling{0}
+\newif\ifyquant at config@operator at subcircuit@manglingreset
+\yquant at config@operator at subcircuit@manglingresettrue
+\newif\ifyquant at config@operator at multi
+
+\protected\def\yquant at config@operator at subcircuit@mangling at set#1{%
+   \ifyquant at config@operator at subcircuit@manglingreset%
+      \def\yquant at config@operator at subcircuit@mangling{#1}%
+   \fi%
+}
\ No newline at end of file

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-draw.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -9,16 +9,12 @@
          \ifx\yquant at draw@init at type\yquant at register@type at none%
             % in case the wire was discarded before, forget about the lastx position, it should always start with the others
             \yquant at register@get at lastwire{#1}\wirelast%
-            \expandafter\expandafter\expandafter\ifstrempty\expandafter\expandafter\expandafter{%
-               \expandafter\@thirdoffour\wirelast%
-            }{%
-               \yquant at register@set at lastwire{#1}{%
-                  {\yquant at draw@subcircuit at wirestart}{\yquant at draw@subcircuit at wirestart}{}%
-                  {\unexpanded\expandafter\expandafter\expandafter{%
-                      \expandafter\@fourthoffour\wirelast%
-                   }}%
-               }%
-            }\relax
+            \yquant at register@set at lastwire{#1}{%
+               {\yquant at draw@subcircuit at wirestart}{\yquant at draw@subcircuit at wirestart}{}%
+               {\unexpanded\expandafter\expandafter\expandafter{%
+                   \expandafter\@fourthoffour\wirelast%
+                }}%
+            }%
          \fi%
          \yquant at register@set at type{#1}{#2}%
       \fi%
@@ -476,51 +472,142 @@
          \let\yquant at draw@subcircuit at wirestart=\newx%
          \let\yquant at parent=\yquant at prefix%
          \def\yquant at prefix{yquant at env#1@}%
-         \ifstrempty{#2}{%
-            % we make sure there are no conflicts by prefixing any named nodes in any case.
+         \pgfkeysgetvalue{/tikz/name prefix}\yquant at draw@subcircuit at prevprefix%
+         % name mangling
+         \ifcase\yquant at config@operator at subcircuit@mangling\relax%
+            % prefix or discard: if we have an outer name, use it as the prefix; if not, discard all names
+            \ifstrempty{#2}{%
+               % we make sure there are no conflicts by prefixing any named nodes in any case.
+               \pgfkeys{/tikz/name prefix/.expanded={sub\yquant at prefix-}}%
+               \let\pgf at nodecallback=\yquant at draw@subcircuit at nodecallback%
+            }{%
+               \pgfkeys{/tikz/name prefix/.expanded={\yquant at draw@subcircuit at prevprefix#2-}}%
+               \ifnum#3=1 %
+                  \let\pgf at nodecallback=\yquant at draw@subcircuit at nodecallback%
+               \fi%
+            }%
+         \or%
+            % prefix or transparent: if we have an outer name, use it as a prefix; if not, directly use the outer namespace
+            \ifstrempty{#2}\relax{%
+               \pgfkeys{/tikz/name prefix/.expanded={\yquant at draw@subcircuit at prevprefix#2-}}%
+               \ifnum#3=1 %
+                  \let\pgf at nodecallback=\yquant at draw@subcircuit at nodecallback%
+               \fi%
+            }%
+         \or%
+            % transparent: all names go directly in the outer namespace
+         \or%
+            % discard: no name will be visible in the outer namespace whatsoever
             \pgfkeys{/tikz/name prefix/.expanded={sub\yquant at prefix-}}%
             \let\pgf at nodecallback=\yquant at draw@subcircuit at nodecallback%
-         }{%
-            \pgfkeys{/tikz/name prefix/.expanded={\pgfkeysvalueof{/tikz/name prefix}#2-}}%
-            \ifnum#3=1 %
-               \let\pgf at nodecallback=\yquant at draw@subcircuit at nodecallback%
-            \fi%
-         }%
+         \else%
+            \PackageError{yquant.sty}{Assertion failure}{Unknown value for name mangling.}%
+         \fi%
          \pgfkeys{/yquant/operators/this subcircuit box/.style={}}%
          \edef\yquant at draw@subcircuit at style{%
             /yquant/every operator, \yquant at draw@@style,%
             /yquant/this operator, /yquant/internal/multi main=true,%
-         }
+         }%
          \expandafter\tikzset\expandafter{\yquant at draw@subcircuit at style}%
-         \csname\yquant at prefix draw\endcsname%
-         \dimen0=\yquant at register@get at y1\relax%
-         \ifdim\dimen0>\pgf at picmaxy %
-            \global\pgf at picmaxy=\dimen0 %
+         \begingroup%
+            \csname\yquant at prefix draw\endcsname%
+         \endgroup%
+         % BEGIN_FOLD bounding box
+         % Completely empty wires did not yet affect the bounding box
+         % Problem: we compare an user-mode TikZ position (register y position) with a system-level pgf position (picture boundary box). If shifts or scalings are in effect, we must first transform the point appropriately. Note that negative scalings may upset our assumption of which is the minimum and which is the maximum! If additionally rotations are in effect, we must even consider those transformations for the leftmost and the rightmost point, which makes all of this far more complicated than it should be. For this reason, we have a shortcut in action in case no nontranslation transformations are present.
+         \ifpgf at pt@identity%
+            \dimen0=\dimexpr\yquant at register@get at y1+\pgf at pt@y\relax%
+            \ifdim\dimen0>\pgf at picmaxy %
+               \global\pgf at picmaxy=\dimen0 %
+            \fi%
+            \dimen0=\dimexpr\yquant at register@get at y{\csname\yquant at prefix registers\endcsname}+\pgf at pt@y\relax%
+            \ifdim\dimen0<\pgf at picminy %
+               \global\pgf at picminy=\dimen0 %
+            \fi%
+         \else%
+            % first wire, left end
+            \pgfpointtransformed{\pgfqpoint{\yquant at draw@@x-.5\dimexpr\@firstofthree#4\relax}{\yquant at register@get at y1\relax}}%
+            \ifdim\pgf at y>\pgf at picmaxy %
+               \global\pgf at picmaxy=\pgf at y %
+            \fi%
+            \ifdim\pgf at y<\pgf at picminy % negative scaling
+               \global\pgf at picminy=\pgf at y %
+            \fi%
+            % first wire, right end
+            \pgfpointtransformed{\pgfqpoint{\yquant at draw@@x+.5\dimenxpr\@firstofthree#4\relax}{\yquant at register@get at y1\relax}}%
+            \ifdim\pgf at y>\pgf at picmaxy %
+               \global\pgf at picmaxy=\pgf at y %
+            \fi%
+            \ifdim\pgf at y<\pgf at picminy % negative scaling
+               \global\pgf at picminy=\pgf at y %
+            \fi%
+            % last wire, left end
+            \pgfpointtransformed{\pgfqpoint{\yquant at draw@@x-.5\dimexpr\@firstofthree#4\relax}{\yquant at register@get at y{\csname\yquant at prefix registers\endcsname}\relax}}%
+            \ifdim\pgf at y>\pgf at picmaxy %
+               \global\pgf at picmaxy=\pgf at y %
+            \fi%
+            \ifdim\pgf at y<\pgf at picminy % negative scaling
+               \global\pgf at picminy=\pgf at y %
+            \fi%
+            % last wire, right end
+            \pgfpointtransformed{\pgfqpoint{\yquant at draw@@x+.5\dimenxpr\@firstofthree#4\relax}{\yquant at register@get at y{\csname\yquant at prefix registers\endcsname}\relax}}%
+            \ifdim\pgf at y>\pgf at picmaxy %
+               \global\pgf at picmaxy=\pgf at y %
+            \fi%
+            \ifdim\pgf at y<\pgf at picminy % negative scaling
+               \global\pgf at picminy=\pgf at y %
+            \fi%
          \fi%
-         \dimen0=\dimexpr\yquant at register@get at y{\csname\yquant at prefix registers\endcsname}\relax%
-         \ifdim\dimen0<\pgf at picminy %
-            \global\pgf at picminy=\dimen0 %
+         % END_FOLD
+         \ifnum\yquant at config@operator at subcircuit@mangling<2 %
+            % only bother with aliasing if the prefix is present at all
+            \ifnum#3=1 %
+               \ifstrempty{#2}\relax{%
+                  % we must apply the aliasing to all the included nodes. We do this in this group, which still has the callback available, so that the aliased nodes will also be added to the list and can propagate (note that the number of node names is then exponential in the number of nested subcircuits)
+                  \pgfkeysgetvalue{/tikz/name prefix}\yquant at draw@subcircuit at alias@prefix%
+                  \expandafter\protected\expandafter\edef\expandafter%
+                     \yquant at draw@subcircuit at alias@do\expandafter##\expandafter1\yquant at draw@subcircuit at alias@prefix##2\relax##3\relax{%
+                     \noexpand\ifstrempty{##1}{%
+                        \noexpand\pgfnodealias{\yquant at draw@subcircuit at prevprefix\yquant at draw@subcircuit at alias@removezero#2-##2}{\yquant at draw@subcircuit at alias@prefix##2}%
+                        \noexpand\@gobble% there is an additional \relax
+                     }\relax%
+                  }%
+                  \expandafter\forlistcsloop\expandafter%
+                     {\expandafter\yquant at draw@subcircuit at alias\expandafter{%
+                        \yquant at draw@subcircuit at alias@prefix}%
+                     }\yquant at draw@subcircuit at nodelist%
+               }%
+            \fi%
          \fi%
-         \ifnum#3=1 %
-            % we must apply the aliasing to all the included nodes. We do this in this group, which still has the callback available, so that the aliased nodes will also be added to the list and can propagate (note that the number of node names is then exponential in the number of nested subcircuits)
-            \protected\def\yquant at draw@subcircuit at alias@do##1#2-##2\relax##3\relax{%
-               \ifstrempty{##1}{%
-                  \pgfnodealias{\yquant at draw@subcircuit at alias@removezero#2-##2}{#2-##2}%
-                  \@gobble% there is an additional \relax
-               }\relax%
-            }%
-            \forlistcsloop%
-               {\yquant at draw@subcircuit at alias{#2}}\yquant at draw@subcircuit at nodelist%
-         \fi%
       }}%
+      \ifpgf at pt@identity%
+         \dimen0=\dimexpr.5\pgf at picminy+.5\pgf at picmaxy-\pgf at pt@y\relax%
+         \dimen2=\dimexpr\pgf at picmaxy-\pgf at picminy\relax%
+      \else%
+         \begingroup%
+            \pgftransforminvert%
+            \pgfpointtransformed{\pgfqpoint{\pgf at picminx}{\pgf at picminy}}%
+            \@tempdima=\pgf at y%
+            \pgfpointtransform{\pgfqpoint{\pgf at picmaxx}{\pgf at picmaxy}}%
+            \edef\cmd{\@tempdima=\the\@tempdima\space\@tempdimb=\the\@tempdimb\space}%
+            \expandafter%
+         \endgroup%
+         \cmd%
+         \pgfpointtransformed{\pgfqpoint{\yquant at draw@@x}%
+                                        {.5\dimexpr\@tempdima+\@tempdimb\relax}}%
+         \dimen0=\pgf at y%
+         \pgfpointtransformed{\pgfqpoint{\yquant at draw@@x}%
+                                        {\dimexpr\@tempdimb-\@tempdima\relax}}%
+         \dimen2=\pgf at y%
+      \fi%
       \edef\cmd{%
-         \noexpand\path (\yquant at draw@@x, \the\dimexpr.5\pgf at picminy+.5\pgf at picmaxy\relax)%
+         \noexpand\path (\yquant at draw@@x, \the\dimen0)%
             node[/yquant/every operator, \yquant at draw@@style,%
                  /yquant/operators/every subcircuit box, /yquant/this operator,%
                  /yquant/operators/this subcircuit box,%
                  /yquant/internal/multi main=true,%
                  name prefix=, name suffix=, name=yquantbox]%
-            {\vbox to \the\dimexpr\pgf at picmaxy-\pgf at picminy\relax {\hbox to \@firstofthree#4 {}}};%
+            {\vbox to \the\dimen2 {\hbox to \@firstofthree#4 {}}};%
       }%
       \cmd%
       \unhbox\yquant at prepare@subcircuit at box%
@@ -535,8 +622,40 @@
    % Now that the subcircuit is finished, we need advance all the wires
    \dimdef\newx{\yquant at draw@@x+.5\dimexpr\yquant at draw@@width\relax}%
    \forlistloop\yquant at draw@group at advance{#5}%
-   \ifstrempty{#2}{%
-      % However, if the outer node was not named, no access to the inner nodes is desired, so we delete all nodes again.
+   % name mangling
+   \ifcase\yquant at config@operator at subcircuit@mangling\relax%
+      % prefix or discard
+      \ifstrempty{#2}{%
+         % However, if the outer node was not named, no access to the inner nodes is desired, so we delete all nodes again.
+         \def\do##1{%
+            \csgundef{pgf at sh@ns@##1}%
+            \csgundef{pgf at sh@np@##1}%
+            \csgundef{pgf at sh@nt@##1}%
+            \csgundef{pgf at sh@pi@##1}%
+            \csgundef{pgf at sh@ma@##1}%
+         }%
+         \dolistcsloop{\yquant at draw@subcircuit at nodelist}%
+         \csgundef\yquant at draw@subcircuit at nodelist%
+      }{%
+         \ifcsname\yquant at prefix draw at subcircuit@nodelist\endcsname%
+            \csxappto{\yquant at prefix draw at subcircuit@nodelist}%
+                     {\csname\yquant at draw@subcircuit at nodelist\endcsname}%
+         \fi%
+      }%
+   \or%
+      % prefix or transparent: in any case, make everything available for mangling in the outer circuit
+      \ifcsname\yquant at prefix draw at subcircuit@nodelist\endcsname%
+         \csxappto{\yquant at prefix draw at subcircuit@nodelist}%
+                  {\csname\yquant at draw@subcircuit at nodelist\endcsname}%
+      \fi%
+   \or%
+      % transparent: same
+      \ifcsname\yquant at prefix draw at subcircuit@nodelist\endcsname%
+         \csxappto{\yquant at prefix draw at subcircuit@nodelist}%
+                  {\csname\yquant at draw@subcircuit at nodelist\endcsname}%
+      \fi%
+   \or%
+      % discard: remove them all
       \def\do##1{%
          \csgundef{pgf at sh@ns@##1}%
          \csgundef{pgf at sh@np@##1}%
@@ -546,18 +665,15 @@
       }%
       \dolistcsloop{\yquant at draw@subcircuit at nodelist}%
       \csgundef\yquant at draw@subcircuit at nodelist%
-   }{%
-      \ifcsname\yquant at prefix draw at subcircuit@nodelist\endcsname%
-         \csxappto{\yquant at prefix draw at subcircuit@nodelist}%
-                  {\csname\yquant at draw@subcircuit at nodelist\endcsname}%
-      \fi%
-   }%
+   \else%
+      \PackageError{yquant.sty}{Assertion failure}{Unknown value for name mangling (2).}%
+   \fi%
 }
 
 \def\yquant at draw@subcircuit at alias@removezero#1-0{#1}
 
 \def\yquant at draw@subcircuit at alias#1#2{%
-   \yquant at draw@subcircuit at alias@do#2\relax#1-0-\relax\relax%
+   \yquant at draw@subcircuit at alias@do#2\relax#10-\relax\relax%
 }
 
 \protected\long\def\yquant at draw@subcircuit at single#1#2#3#4#5{%
@@ -606,7 +722,7 @@
          \yquant at softpath@extractmaxxat\nonaffectedpgfshapeclippathhorzresult%
                                        {\yquant at register@get at y\i}%
          \let\pgfshapeclippathhorzresult=\empty%
-         \yquant at circuit@extendwire\i{*}%
+         \yquant at circuit@extendwire\i*%
       }{%
          \let\pgfshapeclippathhorzresult=\nonaffectedpgfshapeclippathhorzresult%
          \yquant at circuit@extendwire\i{center}%
@@ -767,9 +883,9 @@
                            \pgf at picmaxy=0pt %
                         \fi%
                         \pgftransforminvert%
-                        \pgfpointtransformednonlinear{\pgfqpoint{\pgf at picminx}{\pgf at picminy}}%
+                        \pgfpointtransformed{\pgfqpoint{\pgf at picminx}{\pgf at picminy}}%
                         \global\@tempdima=\pgf at y%
-                        \pgfpointtransformednonlinear{\pgfqpoint{\pgf at picmaxx}{\pgf at picmaxy}}%
+                        \pgfpointtransformed{\pgfqpoint{\pgf at picmaxx}{\pgf at picmaxy}}%
                         \global\@tempdimb=\pgf at y%
                      \endgroup%
                      % To avoid rendering artifacts at all zoom levels with all renderers, we need to make the clipping region large. Let's try the current bounding box first.

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-env.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-env.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-env.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -48,6 +48,7 @@
    \yquant at env@begin at generic\yquant%
 }
 
+% sync with yquantlanguage-groups
 \long\protected\def\yquant at env@begin at generic#1[#2]{%
    \begingroup%
       \let\yquant at parent=\yquant at prefix%
@@ -89,9 +90,12 @@
 
 \protected\def\yquant at env@end{%
          \ifnum\csname\yquant at prefix registers\endcsname>0 %
-            \yquant at for \i := 1 to \csname\yquant at prefix registers\endcsname {%
-               \yquant at register@execclear at lastgate{\i}{@end}%
-            }%
+            \begingroup%
+               \let\yquant at circuit@operator at pctrls=\empty%
+               \yquant at for \i := 1 to \csname\yquant at prefix registers\endcsname {%
+                  \yquant at register@execclear at lastgate{\i}{@end}%
+               }%
+            \endgroup%
             \csgappto{\yquant at prefix draw}{%
                \yquant at circuit@endwires%
             }%
@@ -521,9 +525,8 @@
    \let\path=\tikz at command@path%
    \let\tikz at finish=\yquant at env@substikz at finish%
    \let\tikz at lib@scope at check=\yquant at env@substikz at scopecheck%
-   % we rely on the origin being the origin
-   \pgf at pt@x=0pt %
-   \pgf at pt@y=0pt %
+   % we will often access the bounding box, which is never transformed
+   \pgftransformreset%
 }
 
 % substitute the tikz commands (defined in \tikz at installcommands) so that they can be arbitrarily interleaved with yquant code. We patch \path, \scope, \endscope, \stopscope, their internal complements, and also patch \yquantset.

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-lang.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -35,6 +35,10 @@
    },%
    indirect control/.code={%
       \undef\yquant at lang@attr at directcontrol%
+   },%
+   name mangling/.code={%
+      \pgfkeysalso{/yquant/operators/subcircuit/name mangling={#1}}%
+      \appto\yquant at attrs@remaining{,/yquant/operators/subcircuit/name mangling={#1}}%
    }%
 }
 \yquant at langhelper@declare at attr@global{%
@@ -289,23 +293,38 @@
 }
 
 \protected\long\def\yquantdefinegate at i#1[#2]#3{%
-   \pgfkeys{/yquant/operators/every #1/.style={#2}}%
-   \yquant at prepare@ifs at set%
-   \protected at edef\yquantdefinegate at do{%
-      \yquant at langhelper@declare at command%
-         {#1}%
-         \yquant at register@get at multiaslist%
-         {%
-            \let\noexpand\yquant at lang@attr at value=\expandafter\noexpand\csname yquant at lang@@#1\endcsname%
-            \yquant at prepare@subcircuit{/yquant/operators/every #1}%
+   \begingroup%
+      \yquant at prepare@ifs at set%
+      % usually, we will not be in a tikzpicture here, so all the commands that abbreviate some path operation are undefined!
+      \tikz at installcommands%
+      % While we want the content to be expanded, protect the most likely TikZ commands - the same ones that we usually substitute in \yquant at env@substikz.
+      \protected\def\path{}%
+      \let\scoped=\path%
+      \let\scope=\path%
+      \let\endscope=\path%
+      \let\stopscope=\path%
+      \protected at edef\yquantdefinegate at do{%
+         \endgroup%
+         \noexpand\pgfkeys{/yquant/operators/every #1/.code={%
+            \yquant at config@operator at subcircuit@mangling at set{%
+               \yquant at config@operator at subcircuit@mangling%
+            }%
+            \noexpand\pgfkeysalso{\unexpanded{#2}}%
+         }}%
+         \yquant at langhelper@declare at command%
+            {#1}%
+            \yquant at register@get at multiaslist%
+            {%
+               \let\noexpand\yquant at lang@attr at value=\expandafter\noexpand\csname yquant at lang@@#1\endcsname%
+               \yquant at prepare@subcircuit{/yquant/operators/every #1}%
+            }%
+         % This does not clear the attributes for redefines, but makes at least sure nothing is marked as required that should not be.
+         \yquant at langhelper@setup at attrs{#1}{}{}%
+         % Now define the gate's content as a macro
+         \def\expandafter\noexpand\csname yquant at lang@@#1\endcsname{%
+            #3%
          }%
-      % This does not clear the attributes for redefines, but makes at least sure nothing is marked as required that should not be.
-      \yquant at langhelper@setup at attrs{#1}{}{}%
-      % Now define the gate's content as a macro
-      \def\expandafter\noexpand\csname yquant at lang@@#1\endcsname{%
-         #3%
       }%
-   }%
    \yquantdefinegate at do%
 }
 
@@ -348,14 +367,16 @@
 
 \protected\long\def\yquantdefinebox at i#1#2[#3]#4{%
    \pgfkeys{/yquant/operators/every #1/.style={#3}}%
-   \yquant at prepare@ifs at set%
-   \protected at edef\yquantdefinebox at do{%
-      \yquant at langhelper@declare at command%
-         {#1}%
-         {\unexpanded{#2}}%
-         {\yquant at prepare{#4}{/yquant/operators/every #1}}%
-   }%
-   \yquantdefinebox at do%
+   \begingroup%
+      \yquant at prepare@ifs at set%
+      \protected at edef\yquantdefinebox at do{%
+         \endgroup%
+         \yquant at langhelper@declare at command%
+            {#1}%
+            {\unexpanded{#2}}%
+            {\yquant at prepare{#4}{/yquant/operators/every #1}}%
+      }%
+      \yquantdefinebox at do%
    \yquant at langhelper@setup at attrs{#1}{}{}%
 }
 % END_FOLD
@@ -391,7 +412,7 @@
    {%
       \yquant at prepare@subcircuit{/yquant/operators/every subcircuit}%
    }
-\yquant at langhelper@setup at attrs{subcircuit}{value}{frameless,seamless}
+\yquant at langhelper@setup at attrs{subcircuit}{value}{frameless,seamless,name mangling}
 % END_FOLD
 
 % BEGIN_FOLD other geometric shapes
@@ -565,7 +586,7 @@
 
 \yquant at langhelper@declare at command@uncontrolled%
    {discard}%
-   {\yquant at langhelper@execclear at lastgatefalse}%
+   {}%
    {%
       \let\yquant at circuit@settype at to=\yquant at register@type at none%
       \yquant at circuit@actonwires%
@@ -661,7 +682,7 @@
 
 \yquant at langhelper@declare at command@uncontrolled%
    {settype}%
-   {\yquant at langhelper@execclear at lastgatefalse}%
+   {}%
    {%
       \yquant at register@type at fromstring\yquant at lang@attr at value\yquant at circuit@settype at to%
       \yquant at circuit@actonwires%
@@ -682,7 +703,7 @@
 
 \yquant at langhelper@declare at command@uncontrolled%
    {setstyle}%
-   {\yquant at langhelper@execclear at lastgatefalse}%
+   {}%
    {%
       \yquant at circuit@actonwires%
          \@gobbletwo%
@@ -694,7 +715,7 @@
 
 \yquant at langhelper@declare at command@uncontrolled%
    {addstyle}%
-   {\yquant at langhelper@execclear at lastgatefalse}%
+   {}%
    {%
       \yquant at circuit@actonwires%
          \@gobbletwo%

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-langhelper.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -1,5 +1,7 @@
 % BEGIN_FOLD Parsing attributes
 \let\yquant at langhelper@list at attrs=\empty
+% gatecallback is called by every "standard" gate (which does not include the "create" type of gates)
+\let\yquant at langhelper@gatecallback=\@gobble
 
 \protected\long\def\yquant at langhelper@check at attrs[#1]{%
    \appto\yquant at langhelper@list at attrs{#1,}%
@@ -175,6 +177,7 @@
       \PackageError{yquant.sty}{Unsupported yquant command: `#1'}%
          {You used a command that is unknown to yquant.}%
    \fi%
+   \edef\yquant at langhelper@cmd at original{#1}%
    % Provide the association with the correct attributes
    \csname yquant at langhelper@setup at attrs@set@\cmd\endcsname%
    % For "ordinary" uses of the quotes library (without additional options), it would be better not to load the library now, since then the original text (everything in quotes) is just appended to /yquant/operator style. However, then uses with options will break the pgfkeys parser, as they are invalid. For this reason, we must enable the quotes library already at this state, with the consequence that we store the longer version, i.e., the output of the quotes-parsed expression instead.
@@ -225,6 +228,7 @@
    \begingroup%
       \lowercase{\edef\cmd{#1}}%
       \long\protected\csxdef{yquant at lang@\cmd}##1##2##3{%
+         \noexpand\yquant at langhelper@gatecallback{\cmd}%
          \noexpand\yquant at langhelper@execclear at lastgatetrue%
          \unexpanded{#2}%
          \yquant at circuit@operator{##1}{##2}{##3}%
@@ -252,6 +256,7 @@
          \noexpand\ifstrempty{##2}\relax{%
             \noexpand\PackageError{yquant.sty}{Negative controls are not allowed for the command `\cmd`}{}%
          }%
+         \noexpand\yquant at langhelper@gatecallback{\cmd}%
          \noexpand\yquant at langhelper@execclear at lastgatetrue%
          \unexpanded{#2}%
          \yquant at circuit@operator{}{}{##3}%

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-prepare.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -198,7 +198,7 @@
 }
 
 \protected\def\yquant at prepare@inject at discard#1{%
-   \csappto{\yquant at prefix draw}{%
+   \csgappto{\yquant at prefix draw}{%
       \yquant at draw@inject at outer{#1}%
    }%
    \csgundef{yquant at prepare@@injection@#1}%
@@ -467,6 +467,13 @@
       \fi%
 }
 
+\protected\gdef\yquant at prepare@output at discard#1#2#3{%
+   \ifstrequal{#3}{discard}{%
+      % This notification is triggered in the main circuit if there was an output gate on a wire with [out] or [inout] modifier, but the wire was discarded directly after the subcircuit. Then, it would look weird to extend the wire from the output gate until the end of the subcircuit, so we change the modifier to [ancilla] (not really, this is an artificial state) or [out].
+      \listcsxadd{#2inonly}{#1}%
+   }\relax%
+}
+
 \protected\long\def\yquant at prepare@output at single#1#2#3{%
    \yquant at sort@eadd{%
       \yquant at draw@output at single%
@@ -474,6 +481,14 @@
          {\nodename}%
    }%
    \listadd\yquant at prepare@list{#3}%
+   % we must be extra careful with outputs in subcircuits: Assume the wire is discarded after the subcircuit, then we don't want to extend it after our output label
+   \ifdefined\yquant at parent%
+      \ifinlistcs{#3}{\yquant at prefix inonly}\relax{%
+         \yquant at register@set at lastgate{#3}{%
+            \yquant at prepare@output at discard{#3}{\yquant at prefix}%
+         }%
+      }%
+   \fi%
    % determine the actual dimensions by a virtual draw command
    \pgfinterruptboundingbox%
       \yquant at config@operator at multifalse%
@@ -500,6 +515,18 @@
    \eappto\yquant at prepare@list{%
       \expandafter\yquant at list@range\@secondandthirdoffive#3%
    }%
+   % we must be extra careful with outputs in subcircuits: Assume the wire is discarded after the subcircuit, then we don't want to extend it after our output label
+   \ifdefined\yquant at parent%
+      \edef\first{\@secondoffive#3}%
+      \edef\last{\@thirdoffive#3}%
+      \yquant at for \i := \first to \last {%
+         \xifinlistcs\i{\yquant at prefix inonly}\relax{%
+            \yquant at register@set at lastgate\i{%
+               \yquant at prepare@output at discard{\i}{\yquant at prefix}%
+            }%
+         }%
+      }%
+   \fi%
    \pgfinterruptboundingbox%
       \yquant at config@operator at multitrue%
       \yquant at env@virtualize at path%
@@ -605,6 +632,19 @@
    \@gobblethree% three arguments for the endgroup
 }
 
+\let\yquant at prepare@subcircuit at pgfpointanchor=\pgfpointanchor
+\patchcmd\yquant at prepare@subcircuit at pgfpointanchor{%
+   \pgferror{No shape named `#1' is known}%
+}{}\relax{%
+   \PackageWarning{yquant.sty}{Patching \string\pgfpointanchor\space for the purpose of subcircuits failed; using and referencing named nodes in subcircuits may lead to irrelevant errors.}%
+}
+\let\yquant at prepare@subcircuit at pgfpointshapeborder=\pgfpointshapeborder
+\patchcmd\yquant at prepare@subcircuit at pgfpointshapeborder{%
+   \pgferror{No shape named `#1' is known}%
+}{}\relax{%
+   \PackageWarning{yquant.sty}{Patching \string\pgfpointshapeborder\space for the purpose of subcircuits failed; using and referencing named nodes in subcircuits may lead to irrelevant errors.}%
+}
+
 \protected\def\yquant at prepare@subcircuit at hspace#1#2{%
    \yquant at prepare@subcircuit at getmaxx{#1}%
    \dimdef\newx{\newx+#2}%
@@ -689,6 +729,9 @@
             \edef\yquant at prefix{yquant at env\yquant at circuit@subcircuit at id @}%
             \let\yquant at draw@init=\yquant at prepare@subcircuit at init%
             \let\yquant at draw@group=\yquant at prepare@subcircuit at group%
+            % We may have draw actions within the subcircuit which reference nodes that have been created within the same subcircuit - but they are not known at the stage of preparation! So we here hack into the node querying macros of pgf and just let every unknown node be equal to the origin. If the node is truely unknown, we will find out about this in the draw stage.
+            \let\pgfpointanchor=\yquant at prepare@subcircuit at pgfpointanchor%
+            \let\pgfpointshapeborder=\yquant at prepare@subcircuit at pgfpointshapeborder%
             \let\yquant at draw@alias=\@gobble%
             \let\yquant at draw@hspace=\yquant at prepare@subcircuit at hspace%
             \let\yquant at circuit@endwires=\yquant at prepare@subcircuit at endwires%
@@ -713,7 +756,7 @@
                \global\pgf at picminy=0pt %
             \fi%
             \ifyquant at env@seamless{%
-               % for seamless circuits, we do not have an initial separation. However, if there is an label to registers (which you should not do for seamless subcircuits), the "initial" separation is in fact an inner one, so we need it.
+               % for seamless circuits, we do not have an initial separation. However, if there is a label to registers (which you should not do for seamless subcircuits), the "initial" separation is in fact an inner one, so we need it.
                \ifdim\pgf at picminx<0pt %
                   \global\advance\pgf at picmaxx by \yquant at config@operator at sep\relax%
                \fi%

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -44,6 +44,7 @@
 \protected\def\yquant at register@define#1#2#3{%
    \csnumgdef{\yquant at prefix registers}%
              {\csname\yquant at prefix registers\endcsname+1}%
+   % sync with yquantlanguage-groups/\yquantgroup at startenvironment
    \csxdef{\yquant at prefix register@\csname\yquant at prefix registers\endcsname}{%
       {#1}% type
       {0pt}% x pos

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant-tools.tex	2021-08-17 20:49:48 UTC (rev 60259)
@@ -452,11 +452,12 @@
    \fi%
 }
 
-% #1 is a pgf soft path. We extract the maximum x position at the y position specified in #2 and assign it to \dimen0.
+% #1 is a pgf soft path. We extract the maximum x position at the y position specified in #2 and assign it to \dimen0, which is translated to the user coordinate system.
 \protected\def\yquant at softpath@extractmaxxat#1#2{%
    \begingroup%
       \dimen0=-16000pt %
       \dimen2=#2 %
+      \pgftransforminvert%
       \let\pgfsyssoftpath at movetotoken=\yquant at softpath@extractmaxxat at moveto%
       \let\pgfsyssoftpath at linetotoken=\yquant at softpath@extractmaxxat at lineto%
       \let\pgfsyssoftpath at curvetosupportatoken=\yquant at softpath@extractmaxxat at curveto%
@@ -476,51 +477,53 @@
 }
 
 \protected\def\yquant at softpath@extractmaxxat at moveto#1#2{%
-   \dimen4=#1 %
-   \dimen6=#2 %
+   \pgfpointtransformed{\pgfqpoint{#1}{#2}}%
+   \dimen4=\pgf at x %
+   \dimen6=\pgf at y %
 }
 
 \protected\def\yquant at softpath@extractmaxxat at lineto#1#2{%
-   \ifyquant at OR{\ifdim\dimen4>\dimen0 }{\ifdim#1>\dimen0 }{%
+   \pgfpointtransformed{\pgfqpoint{#1}{#2}}%
+   \ifyquant at OR{\ifdim\dimen4>\dimen0 }{\ifdim\pgf at x>\dimen0 }{%
       \ifdim\dimen6=\dimen2 %
          \yquant at softpath@extractmaxxat at update{\dimen4}%
       \else%
          \ifdim\dimen6<\dimen2 %
-            \unless\ifdim#2<\dimen2 %
+            \unless\ifdim\pgf at y<\dimen2 %
                \expandafter\yquant at softpath@extractmaxxat at update\expandafter{\the\dimexpr%
                   \dimen4+% x0
-                  \dimexpr#1-\dimen4\relax*% (x1-x0)
-                  \dimexpr\dimen2-\dimen6\relax/\dimexpr#2-\dimen6\relax% (y-y0)/(y1-y0)
+                  \dimexpr\pgf at x-\dimen4\relax*% (x1-x0)
+                  \dimexpr\dimen2-\dimen6\relax/\dimexpr\pgf at y-\dimen6\relax% (y-y0)/(y1-y0)
                \relax}%
             \fi%
          \else%
-            \unless\ifdim#2>\dimen2 %
+            \unless\ifdim\pgf at y>\dimen2 %
                \expandafter\yquant at softpath@extractmaxxat at update\expandafter{\the\dimexpr%
                   \dimen4+% x0
-                  \dimexpr#1-\dimen4\relax*% (x1-x0)
-                  \dimexpr\dimen2-\dimen6\relax/\dimexpr#2-\dimen6\relax% (y-y0)/(y1-y0)
+                  \dimexpr\pgf at x-\dimen4\relax*% (x1-x0)
+                  \dimexpr\dimen2-\dimen6\relax/\dimexpr\pgf at y-\dimen6\relax% (y-y0)/(y1-y0)
                \relax}%
             \fi%
          \fi%
       \fi%
    }\relax%
-   \dimen4=#1 %
-   \dimen6=#2 %
+   \dimen4=\pgf at x%
+   \dimen6=\pgf at y%
 }
 
-\protected\def\yquant at softpath@extractmaxxat at curveto@checkx#1#2#3{%
+\protected\def\yquant at softpath@extractmaxxat at curveto@checkx{%
    % \dimen11 holds our only candidate for t. Is it within the curve?
    \unless\ifdim\dimen11<0pt %
       \unless\ifdim\dimen11>1pt %
-         % it is. \dimen4: x0, #1: xa, #2: xb, #3: x1
+         % it is. \dimen4: x0, \pgf at xa: xa, \pgf at xb: xb, \pgf at xc: x1
          \begingroup%
             \dimen12=\dimexpr1pt-\dimen11\relax% 1 - t
             \dimen13=\dimexpr\dimen11*\dimen11/65535\relax% t^2
             \dimen14=\dimexpr\dimen12*\dimen12/65535\relax% (1 - t)^2
-            \dimen255=\dimexpr\dimen13*\dimen11/65535*\dimexpr#3\relax/65535+% t^3 x1
-                              3\dimen13*\dimen12/65535*\dimexpr#2\relax/65535+% t^2(1 - t) xb
+            \dimen255=\dimexpr\dimen13*\dimen11/65535*\pgf at xc/65535+% t^3 x1
+                              3\dimen13*\dimen12/65535*\pgf at xb/65535+% t^2(1 - t) xb
                               \dimen14*\dimen12/65535*\dimen4/65535+% (1 - t)^3 x0
-                              3\dimen11*\dimen14/65535*\dimexpr#1\relax/65535% 3t(1 - t)^2 xa
+                              3\dimen11*\dimen14/65535*\pgf at xa/65535% 3t(1 - t)^2 xa
                       \relax%
             \expandafter%
          \endgroup%
@@ -536,6 +539,15 @@
    % where x0 = \dimen4 (the moveto point), xa = #1, xb = #3, x1 = #5.
    % Likewise for y:
    %       y0 = \dimen6 (the moveto point), ya = #2, yb = #4, y1 = #6.
+   \pgfpointtransformed{\pgfqpoint{#1}{#2}}%
+   \pgf at xa=\pgf at x%
+   \pgf at ya=\pgf at y%
+   \pgfpointtransformed{\pgfqpoint{#3}{#4}}%
+   \pgf at xb=\pgf at x%
+   \pgf at yb=\pgf at y%
+   \pgfpointtransformed{\pgfqpoint{#5}{#6}}%
+   \pgf at xc=\pgf at x%
+   \pgf at yc=\pgf at y%
    % We first solve the third-order polynomial for t using the y value, then plug it back into the x value.
    % TODO: this is accurate to approx. 3 digits. Can this be improved by reformulating Cardanos formula to involve less divisions?
    \begingroup%
@@ -542,13 +554,13 @@
       % We need so may dimensions that we break with TeX's convention for their use.
       % for the multiplications with and divisions by dimensions, we exploit that eTeX fuses muldiv to 64 bits. Further note that each dimension has a scaling factor of 65535 for sp<->pt conversion. This is why don't factor out divisions (which would be more efficient, but not give the benefit of 64bit accuracy).
       % a = 3(ya - yb) + (y1 - y0)
-      \dimen1=\dimexpr3\dimexpr#2-#4\relax+#6-\dimen6\relax%
+      \dimen1=\dimexpr3\pgf at ya-3\pgf at yb+\pgf at yc-\dimen6\relax%
       \ifdim\dimen1=0pt %
          % this is only a quadratic curve!
          % b = 3(y0 - 2ya + yb)
-         \dimen3=\dimexpr3\dimexpr\dimen6-2\dimexpr#2\relax+#4\relax*65535\relax%
+         \dimen3=\dimexpr3\dimexpr\dimen6-2\pgf at ya+\pgf at yb\relax*65535\relax%
          % c: 3(ya - y0)
-         \dimen5=\dimexpr3\dimexpr#2-\dimen6\relax*65535\relax%
+         \dimen5=\dimexpr3\dimexpr\pgf at ya-\dimen6\relax*65535\relax%
          % d: y0 - <desired y>
          \dimen7=\dimexpr\dimexpr\dimen6-\dimen2\relax*65535\relax%
          % check the discriminant of the equation
@@ -558,17 +570,17 @@
             \pgfmathsqrt@{\the\dimen8\@gobbletwo}%
             \dimen11=\dimexpr\dimexpr-\dimen5+\pgfmathresult pt\relax*65535/%
                              \dimexpr2\dimen3\relax\relax%
-            \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+            \yquant at softpath@extractmaxxat at curveto@checkx%
             \dimen11=\dimexpr\dimexpr-\dimen5-\pgfmathresult pt\relax*65535/%
                              \dimexpr2\dimen3\relax\relax%
-            \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+            \yquant at softpath@extractmaxxat at curveto@checkx%
          \fi%
       \else%
          % We will simplify by directly dividing all coefficients by a
          % b = 3(y0 - 2ya + yb)
-         \dimen3=\dimexpr3\dimexpr\dimen6-2\dimexpr#2\relax+#4\relax*65535/\dimen1\relax%
+         \dimen3=\dimexpr3\dimexpr\dimen6-2\pgf at ya+\pgf at yb\relax*65535/\dimen1\relax%
          % c: 3(ya - y0)
-         \dimen5=\dimexpr3\dimexpr#2-\dimen6\relax*65535/\dimen1\relax%
+         \dimen5=\dimexpr3\dimexpr\pgf at ya-\dimen6\relax*65535/\dimen1\relax%
          % d: y0 - <desired y>
          \dimen7=\dimexpr\dimexpr\dimen6-\dimen2\relax*65535/\dimen1\relax%
          % Note that now our a value (\dimen1) is no longer needed, it is one.
@@ -603,7 +615,7 @@
                \pgfmathpow@{\the\dimexpr-\dimen13\relax\@gobbletwo}{.3333333333}%
                \dimen11=\dimexpr\dimen11-\pgfmathresult pt-.33333333333\dimen3\relax%
             \fi%
-            \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+            \yquant at softpath@extractmaxxat at curveto@checkx%
          \else%
             \ifdim\dimen10=0pt %
                % easiest case, three real roots, two of which are equal:
@@ -617,10 +629,10 @@
                   \dimen15=-\pgfmathresult pt %
                \fi%
                \dimen11=\dimexpr2\dimen15-.33333333333\dimen3\relax%
-               \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+               \yquant at softpath@extractmaxxat at curveto@checkx%
                % check the next candidate
                \dimen11=\dimexpr-\dimen15-.33333333333\dimen3\relax%
-               \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+               \yquant at softpath@extractmaxxat at curveto@checkx%
             \else%
                % nastiest case, three distinct real roots which we can find only by taking a complex-valued cube root.
                % p + i q = cbrt(R + i sqrt(|D|))
@@ -643,11 +655,11 @@
                % y_2 = -p - sqrt(3)q - b/3a
                % y_3 = -p + sqrt(3)q - b/3a
                \dimen11=\dimexpr2\dimen14-.33333333333\dimen3\relax%
-               \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+               \yquant at softpath@extractmaxxat at curveto@checkx%
                \dimen11=\dimexpr-\dimen14-1.732050808\dimen15-.33333333333\dimen3\relax%
-               \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+               \yquant at softpath@extractmaxxat at curveto@checkx%
                \dimen11=\dimexpr-\dimen14+1.732050808\dimen15-.33333333333\dimen3\relax%
-               \yquant at softpath@extractmaxxat at curveto@checkx{#1}{#3}{#5}%
+               \yquant at softpath@extractmaxxat at curveto@checkx%
             \fi%
          \fi%
       \fi%
@@ -655,30 +667,34 @@
       \expandafter%
    \endgroup%
    \expandafter\dimen\expandafter0\expandafter=\the\dimen0  %
-   \dimen4=#5 %
-   \dimen6=#6 %
+   \dimen4=\pgf at xc %
+   \dimen6=\pgf at yc %
 }
 
 \protected\def\yquant at softpath@extractmaxxat at rectto#1#2\pgfsyssoftpath at rectsizetoken#3#4{%
    % #1: lower left x, #2: lower left y, #3: width, #4: height
-   % note that neither width nor height need be positive!
-   \ifdim#4>0pt %
-      \unless\ifdim#2>\dimen2 %
-         \unless\ifdim\dimexpr#2+#4\relax<\dimen2 %
-            \ifdim#3>0pt %
-               \yquant at softpath@extractmaxxat at update{\dimexpr#1+#3\relax}%
+   \pgfpointtransformed{\pgfqpoint{#1}{#2}}%
+   \pgf at xa=\pgf at x%
+   \pgf at ya=\pgf at y%
+   \pgfpointtransformed{\pgfqpoint{\dimexpr#1+#3\relax}{\dimexpr#2+#4\relax}}%
+   % (\pgf at xa, \pgf at ya) one corner, (\pgf at x, \pgf at y) other corner
+   \ifdim\pgf at y>\pgf at ya %
+      \unless\ifdim\pgf at ya>\dimen2 %
+         \unless\ifdim\pgf at y<\dimen2 %
+            \ifdim\pgf at x>\pgf at xa %
+               \yquant at softpath@extractmaxxat at update\pgf at x%
             \else%
-               \yquant at softpath@extractmaxxat at update{#1}%
+               \yquant at softpath@extractmaxxat at update\pgf at xa%
             \fi%
          \fi%
       \fi%
    \else%
-      \unless\ifdim#2<\dimen2 %
-         \unless\ifdim\dimexpr#2+#4\relax>\dimen2 %
-            \ifdim#3>0pt %
-               \yquant at softpath@extractmaxxat at update{\dimexpr#1+#3\relax}%
+      \unless\ifdim\pgf at ya<\dimen2 %
+         \unless\ifdim\pgf at y>\dimen2 %
+            \ifdim\pgf at x>\pgf at xa %
+               \yquant at softpath@extractmaxxat at update\pgf at x%
             \else%
-               \yquant at softpath@extractmaxxat at update{#1}%
+               \yquant at softpath@extractmaxxat at update\pgf at xa%
             \fi%
          \fi%
       \fi%

Modified: trunk/Master/texmf-dist/tex/latex/yquant/yquant.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquant.sty	2021-08-17 20:49:32 UTC (rev 60258)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquant.sty	2021-08-17 20:49:48 UTC (rev 60259)
@@ -15,7 +15,7 @@
 %
 % The Current Maintainer of this work is Benjamin Desef.
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{yquant}[2021/07/03 v0.4.1 Yet another quantum circuit library for LaTeX]
+\ProvidesPackage{yquant}[2021/08/17 v0.5 Yet another quantum circuit library for LaTeX]
 
 \RequirePackage{etoolbox}[2018/02/11]
 \RequirePackage{tikz}[2015/08/29]
@@ -32,7 +32,7 @@
 }
 \ProcessOptionsX
 \unless\ifdefined\yquant at compat
-   \PackageWarning{yquant.sty}{Please specify the `compat` key for yquant. Using `0.3`. Current version is `0.4`.}
+   \PackageWarning{yquant.sty}{Please specify the `compat` key for yquant. Using `0.3`. Current compatibility version `0.4`.}
    \def\yquant at compat{1}
 \fi
 
@@ -51,9 +51,12 @@
 % usually, \\ is robust; but when using \centering, it is \let to \@centercr, which is not robust (probably because this happens only when not protecting). Fix this, so that \\ does not require \protect if a centered circuit is drawn.
 \robustify\@centercr
 
-\outer\def\useyquantlanguage#1{%
-   \RequirePackage{yquantlanguage-#1}
+\def\useyquantlanguage@#1{%
+   \RequirePackage{yquantlanguage-#1}%
 }
+\outer\def\useyquantlanguage{%
+   \forcsvlist\useyquantlanguage@
+}
 
 \endinput
 %%

Added: trunk/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty	2021-08-17 20:49:48 UTC (rev 60259)
@@ -0,0 +1,527 @@
+% yquantlanguage-groups.sty
+%  Extend yquant for quick and simple circuit equations.
+%
+% Copyright 2021 Benjamin Desef
+%
+% This work may be distributed and/or modified under the conditions of the LaTeX Project
+% Public License, either version 1.3c of this license or (at your option) any later
+% version.
+% The latest version of this license is in
+%   http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX version 2005/12/01 or
+% later.
+%
+% This work has the LPPL maintenance status `author-maintained'.
+%
+% The Current Maintainer of this work is Benjamin Desef.
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{yquantlanguage-groups}[2021/08/14 v0.5 yquant-groups]
+
+\RequirePackage{yquant}[2021/08/14]
+
+% BEGIN_FOLD Config
+\newif\ifyquantgroup at config@aligned
+\pgfqkeys{/yquant}{%
+   group/every group/.style={},%
+   group/line separation/.code={%
+      \dimdef\yquantgroup at config@lineseparation{#1}%
+   },%
+   group/aligned/.is if=yquantgroup at config@aligned,
+   operators/every group circuit/.code={%
+      \pgfkeysalso{%
+         /yquant/operators/every subcircuit,%
+         /yquant/operators/subcircuit/frameless,%
+      }%
+      % we want no name mangling for the subcircuit that is responsible for the groups, but we want the original setting restored within (with the possibility to override this in the options). Since the outer option is queried in the preparation step and then fixes to what it is reset within the subcircuit, we just don't apply our name mangling rule during the preparation stage, only during execution.
+      \unless\ifyquantmeasuring%
+         \pgfkeysalso{%
+            /yquant/operators/subcircuit/name mangling=transparent%
+         }%
+      \fi%
+   },%
+   operators/every group equals/.style={shape=yquant-rectangle, align=center, inner xsep=1mm, x radius=2mm, y radius=2.47mm}
+}
+\def\yquantgroup at config@lineseparation{5mm}%
+% END_FOLD
+
+\def\yquantgroup at prefix{yquantgroup at env@registers@}%
+\def\yquantgroup at parent{yquantgroup at env@parent@}%
+
+% BEGIN_FOLD Environment
+\newenvironment{yquantgroup}[1][]{%
+   \ifdefined\yquant at parent%
+      \PackageError{yquant.sty}{yquantgroup must be top-level}%
+                   {You may not use the yquantgroup environment within a subcircuit or a user-defined gate.}%
+   \fi%
+   % macros that may have a meaning that we want to restore inside the circuits
+   \let\yquantgroup at save@registers=\registers%
+   \let\yquantgroup at save@circuit=\circuit%
+   \let\yquantgroup at save@equals=\equals%
+   \let\yquantgroup at save@shiftright=\shiftright%
+   \let\yquantgroup at save@linebreak=\\%
+   \let\yquantgroup at save@gatecallback=\yquant at langhelper@gatecallback%
+   % assign the new meaning
+   \let\registers=\yquantgroup at registers%
+   \let\circuit=\yquantgroup at circuit%
+   \let\equals=\yquantgroup at equals%
+   \let\shiftright=\yquantgroup at shiftright%
+   \let\\=\yquantgroup at linebreak%
+   % This is a bit inconsistent, we should check \iftikz at inside@picture, but this is no longer appropriately set since at pgf 3.1.2.
+   \let\ifyquantgroup at inpicture=\ifpgfpicture%
+   \pgfkeysgetvalue{/yquant/preamble}\yquantgroup at save@preamble%
+   \ifpgfpicture%
+      \let\pagebreak=\yquantgroup at nobreak%
+      \let\newpage=\yquantgroup at nobreak%
+      \let\clearpage=\yquantgroup at nobreak%
+      \let\cleardoublepage=\yquantgroup at nobreak%
+      \let\yquantgroup at start@tikzpicture=\relax%
+      \let\yquantgroup at end@tikzpicture=\relax%
+   \else%
+      \let\yquantgroup at save@pagebreak=\pagebreak%
+      \let\pagebreak=\yquantgroup at pagebreak%
+      \let\yquantgroup at save@newpage=\newpage%
+      \let\newpage=\yquantgroup at newpage%
+      \let\yquantgroup at save@clearpage=\clearpage%
+      \let\clearpage=\yquantgroup at clearpage%
+      \let\yquantgroup at save@cleardoublepage=\cleardoublepage%
+      \let\cleardoublepage=\yquantgroup at cleardoublepage%
+      \def\yquantgroup at start@tikzpicture{\tikzpicture \global\pgf at picminx=0pt }%
+      \def\yquantgroup at end@tikzpicture{\endtikzpicture}%
+      \pgfkeysdef{/yquant/preamble}{%
+         \def\yquantgroup at start@tikzpicture{\tikzpicture[{#1}] \global\pgf at picminx=0pt }%
+      }%
+   \fi%
+   \undef\yquantgroup%
+   \yquantset{#1, /tikz/.cd, /yquant/group/every group}%
+   \def\yquantgroup at alignments{0}%
+   \def\yquantgroup at currentxpos{-\yquant at config@operator at sep}%
+   \def\yquantgroup at currentypos{0pt}%
+   \let\yquantgroup at mangling=\yquant at config@operator at subcircuit@mangling%
+   \pgfkeyslet{/yquant/preamble}\yquantgroup at save@preamble%
+   \yquantgroup at start@tikzpicture%
+}{%
+   \ifdefined\yquant at prefix%
+      \yquant at env@end%
+   \fi%
+   \ifcsname\yquantgroup at parent cleanup\endcsname%
+      \yquant at for \i := 1 to \csname\yquantgroup at prefix registers\endcsname {%
+         \csgundef{\yquantgroup at prefix import@\i}%
+      }%
+      \expandafter\expandafter\expandafter\yquant at cleanup\csname\yquantgroup at parent cleanup\endcsname|%
+      \csgundef{\yquantgroup at parent cleanup}%
+      \gundef\yquantgroup at start@yquant%
+   \else%
+      \PackageWarning{yquant.sty}{Empty yquantgroup}%
+   \fi%
+   \gundef\yquantgroup at alignments%
+   \yquantgroup at end@tikzpicture%
+}
+
+\newenvironment{yquantgroup*}[1][]{%
+   \yquantgroup[{#1}]%
+      \yquant at env@lazytrue%
+}{%
+   \endyquantgroup%
+}
+% END_FOLD
+
+% BEGIN_FOLD Register declaration
+\protected\long\def\yquantgroup at registers#1{%
+   \begingroup%
+      \gdef\yquantgroup at registers@text{#1}%
+      \let\yquantgroup at save@lang at create@parse=\yquant at lang@create at parse@name%
+      \let\yquant at lang@create at parse@name=\yquantgroup at registers@create at parse%
+      \let\yquant at env@begin at generic=\yquantgroup at registers@env at generic%
+      \appto\yquant at langhelper@setup at attrs@set at nobit{%
+         \let\yquantgroup at registers@remember at attrs=\yquant at langhelper@list at attrs%
+      }%
+      \appto\yquant at langhelper@setup at attrs@set at qubit{%
+         \let\yquantgroup at registers@remember at attrs=\yquant at langhelper@list at attrs%
+      }%
+      \appto\yquant at langhelper@setup at attrs@set at cbit{%
+         \let\yquantgroup at registers@remember at attrs=\yquant at langhelper@list at attrs%
+      }%
+      \appto\yquant at langhelper@setup at attrs@set at qubits{%
+         \let\yquantgroup at registers@remember at attrs=\yquant at langhelper@list at attrs%
+      }%
+      \let\yquantgroup at registers@remember at attrs=\empty%
+      \setbox0=\hbox{%
+         \pgfinterruptboundingbox%
+            \yquant at envunstar[]%
+               #1%
+            \yquant at env@end%
+         \endpgfinterruptboundingbox%
+      }%
+      \def\registers{%
+         \PackageError{yquant.sty}{Double invocation of \string\registers}%
+                      {All registers must be specified once at the beginning of the group. Multiple declarations or later additions are not allowed.}%
+      }%
+      \unless\ifx\yquantgroup at registers@text\empty%
+         \csxappto{\yquantgroup at prefix import@\csname\yquantgroup at prefix registers\endcsname}{%
+            \unexpanded\expandafter{\yquantgroup at registers@text}%
+         }%
+      \fi%
+      \gundef\yquantgroup at registers@text%
+   \endgroup%
+}
+
+% sync with yquant-env
+\let\yquantgroup at registers@env at generic=\yquant at env@begin at generic
+\patchcmd\yquantgroup at registers@env at generic{%
+   \let\yquant at parent=\yquant at prefix%
+   \global\advance\yquant at env by 1 %
+   \edef\yquant at prefix{yquant at env\the\yquant at env @}%
+   \ifnum\yquant at env=1 %
+      \yquantmeasuringtrue%
+      \yquant at env@substikz#1%
+      \global\cslet{\yquant at prefix parameters}\empty%
+   \else%
+      \let\yquant at lang@reset at attrs@inputoutput=\yquant at lang@reset at attrs@inputoutput at subcircuit%
+      \global\cslet{\yquant at prefix parameters}\yquant at circuit@subcircuit at param%
+      \yquant at env@lazyfalse% forbid lazy register creation in subcircuits. We need a proper and in-order declaration of the subcircuit's interface.
+   \fi%
+}{%
+   \unless\ifnum\yquant at env=0 %
+      \PackageError{yquant.sty}{Assertion failure}%
+                   {Nested \string\registers-induced yquant environment found.}%
+   \fi%
+   \let\yquant at parent=\yquantgroup at parent%
+   \let\yquant at prefix=\yquantgroup at prefix%
+   \yquantmeasuringtrue%
+   \yquant at env@substikz#1%
+   \global\cslet{\yquant at prefix parameters}\empty%
+}\relax{%
+   \PackageError{yquant.sty}{Internal error}%
+                {Unable to patch yquant environment for \string\registers.}%
+}
+
+\protected\def\yquantgroup at registers@create at parse#1[#2;{%
+   \let\yquant at lang@create at type=\yquant at register@type at none%
+   \ifstrempty{#2}{%
+      \edef\yquantgroup at registers@splittext{%
+         \protected\long\def\noexpand\yquantgroup at registers@splittext####1%
+            \yquant at langhelper@cmd at original####2#1;####3%
+            \noexpand\yquantgroup at registers@splittext at end{%
+            \csgdef{\yquantgroup at prefix import@\the\numexpr\csname\yquant at prefix registers\endcsname+1\relax}{%
+               ####1\yquant at langhelper@cmd at original####2#1;%
+            }%
+            \gdef\noexpand\yquantgroup at registers@text{####3}%
+         }%
+      }%
+      \yquantgroup at registers@splittext%
+      \expandafter\yquantgroup at registers@splittext\yquantgroup at registers@text%
+                                                  \yquantgroup at registers@splittext at end%
+      \yquant at lang@create at do#1[1][;%
+   }{%
+      \edef\yquantgroup at registers@splittext{%
+         \protected\long\def\noexpand\yquantgroup at registers@splittext####1%
+            \yquant at langhelper@cmd at original####2#1[\yquantgroup at registers@create at parse@extract#2];####3%
+            \noexpand\yquantgroup at registers@splittext at end{%
+            \csgdef{\yquantgroup at prefix import@\the\numexpr\csname\yquant at prefix registers\endcsname+1\relax}{%
+               ####1\yquant at langhelper@cmd at original####2#1[+1];%
+            }%
+            \ifnum\yquantgroup at registers@create at parse@extract#2>1 %
+               \noexpand\yquant at for \noexpand\i := 2 to \yquantgroup at registers@create at parse@extract#2 {%
+                  \csgdef{\yquantgroup at prefix import@\noexpand\the\numexpr\csname\yquant at prefix registers\endcsname+\noexpand\i\relax}{%
+                     [\yquantgroup at registers@remember at attrs]%
+                     \yquant at langhelper@cmd at original####2#1[+1];%
+                  }%
+               }%
+            \fi%
+            \gdef\noexpand\yquantgroup at registers@text{####3}%
+         }%
+      }%
+      \yquantgroup at registers@splittext%
+      \expandafter\yquantgroup at registers@splittext\yquantgroup at registers@text%
+                                                  \yquantgroup at registers@splittext at end%
+      \yquant at lang@create at do#1[#2;%
+   }%
+}
+
+\def\yquantgroup at registers@create at parse@extract#1][{#1}
+% END_FOLD
+
+\protected\def\yquantgroup at startenvironments{%
+   \unless\ifcsname\yquantgroup at prefix registers\endcsname%
+      \PackageError{yquant.sty}{\string\circuit without \string\registers}%
+                   {A circuit was invoked without preceding register definitions.}%
+   \fi%
+   % since \registers is in subcircuit mode, that the existence of the macro implies that it is greater than zero
+   \ifdef\yquant at prefix{%
+      % We already started the yquant environment - but this means that potentially, we could have changed our wire styles. The underlying subcircuit architecture will preserve these changes, but since in our context, we treat the circuits as independent, this is not the desired behavior: remove all styles.
+      \yquant at for \i := 1 to \csname\yquant at prefix registers\endcsname {%
+         % we don't really need to flush a wire, since it is discarded anyway
+         \csxappto{\yquant at prefix draw}{%
+            \yquant at register@set at style{\i}{}%
+         }%
+      }%
+   }{%
+      \yquant at env@begin[/tikz/shift={(\yquantgroup at currentxpos, \yquantgroup at currentypos)}]%
+         % we re-create all the outer registers, but without the names.
+         % sync with yquant-registers/\yquant at register@define
+         \global\csletcs{\yquant at prefix registers}{\yquantgroup at prefix registers}%
+         \yquant at for \i := 1 to \csname\yquantgroup at prefix registers\endcsname {%
+            \csxdef{\yquant at prefix register@\i}{%
+               {\yquant at register@type at none}% type
+               {0pt}% x pos
+               {{\yquant at config@register at minimum@height}%
+                {\yquant at config@register at minimum@depth}%
+                {}}% height, depth, and multi-space parts; at the end, the y position
+               {{0pt}{0pt}{}{}}% wire start positions and clipping
+               {}% wire style
+               {\yquant at register@flag at clean}%
+            }%
+            \yquant at cleanup@csadd{\yquant at prefix register@\i}%
+            \csxappto{\yquant at prefix draw}{%
+               \yquant at draw@init{\i}{\yquant at register@type at none}%
+            }%
+         }%
+   }%
+}
+
+% BEGIN_FOLD Circuit
+\def\yquantgroup at circuit{%
+   \@ifnextchar[\yquantgroup at circuit@i%
+                {\yquantgroup at circuit@i[]}%
+}
+
+\long\def\yquantgroup at circuit@i[#1]#2{%
+   \yquantgroup at startenvironments%
+   \yquant [{#1}] group\space circuit {#2} (-);%
+   discard -;
+}
+
+\yquant at langhelper@declare at command@uncontrolled%
+   {group circuit}%
+   \yquant at register@get at multiaslist%
+   {%
+      \let\yquant at lang@import=\yquantgroup at circuit@import%
+      \edef\yquantgroup at circuit@nonimported{%
+         \yquant at list@range{1}{\csname\yquantgroup at prefix registers\endcsname}%
+      }%
+      \let\yquant at langhelper@gatecallback=\yquantgroup at circuit@gatecallback%
+      \yquant at prepare@subcircuit{/yquant/operators/every group circuit}%
+      \gundef\yquantgroup at circuit@nonimported%
+   }
+\yquant at langhelper@setup at attrs{group circuit}{value}{frameless,seamless}
+
+\yquant at langhelper@declare at command@uncontrolled{import}{%
+   \expandafter\ifstrequal\expandafter{\yquant at parent}{yquant at env1@}\relax{%
+      \PackageError{yquant.sty}{import gate in subcircuit}%
+                   {The import gate can only be used in the top-level \string\circuit, but not in subcircuits.}%
+   }%
+   \let\yquantgroup at circuit@oldprefix=\yquant at prefix%
+   \let\yquant at prefix=\yquantgroup at prefix%
+}{%
+   \let\yquant at prefix=\yquantgroup at circuit@oldprefix%
+   % we don't end the group here, so that potential attributes given to import will carry over
+   \undef\yquant at lang@attr at input%
+   \let\yquant at lang@attr at output=\relax%
+   \forlistloop\yquantgroup at circuit@directimport\yquant at circuit@operator at targets%
+}
+\let\yquantgroup at circuit@import=\yquant at lang@import
+\undef\yquant at lang@import
+
+\protected\def\yquantgroup at circuit@directimport#1{%
+   \listgremove\yquantgroup at circuit@nonimported{#1}%
+   \ifx\yquantgroup at circuit@nonimported\empty%
+      \gundef\yquant at lang@import%
+      \global\let\yquant at langhelper@gatecallback=\yquantgroup at save@gatecallback%
+   \fi%
+   \expandafter\expandafter\expandafter\yquant%
+      \csname\yquantgroup at prefix import@#1\endcsname%
+}
+
+\def\yquantgroup at circuit@restimport#1{%
+   % basically the same as directimport, but since we are doing all the remaining stuff, no need to check in between
+   \expandafter\expandafter\expandafter\yquant%
+      \csname\yquantgroup at prefix import@#1\endcsname%
+}
+
+\protected\def\yquantgroup at circuit@gatecallback#1{%
+   \ifstrequal{#1}{import}\relax{%
+      % this is called by every standard gate - so we ensure that before the first standard gate is used, all outer registers are imported. Note that we are actually in a group that already contains all the relevant setup for the _current_ gate, which should not influence the implicit imports at all! So this means we do a state reset as for subcircuits.
+      \begingroup%
+         \let\yquant at langhelper@list at attrs=\empty%
+         \yquant at lang@reset at attrs%
+         \undef\yquant at lang@attr at input%
+         \let\yquant at lang@attr at output=\relax%
+         \forlistloop\yquantgroup at circuit@restimport\yquantgroup at circuit@nonimported%
+      \endgroup%
+      \global\let\yquantgroup at circuit@nonimported=\empty%
+      \gundef\yquant at lang@import%
+      \global\let\yquant at langhelper@gatecallback=\yquantgroup at save@gatecallback%
+   }%
+}
+% END_FOLD
+
+% BEGIN_FOLD Equals box
+\yquant at langhelper@declare at command%
+   {group equals}%
+   \yquant at register@get at allowmultitrue%
+   {%
+      \expandafter\yquant at prepare%
+         \expandafter{\yquant at lang@attr at value}%
+         {/yquant/operators/every group equals}%
+   }
+\yquant at langhelper@setup at attrs{group equals}{value}{}
+
+\def\yquantgroup at equals{%
+   \@ifstar{\yquantgroup at equals@i1}%
+           {\yquantgroup at equals@i0}%
+}
+
+\def\yquantgroup at equals@i#1{%
+   \@ifnextchar[{\yquantgroup at equals@ii{#1}}%
+                {\yquantgroup at equals@ii{#1}[$=$]}%
+}
+
+\protected\long\def\yquantgroup at equals@ii#1[#2]{%
+   \yquantgroup at startenvironments%
+   \ifx0#1%
+      \yquant group\space equals {#2} (-);%
+   \else%
+      \numgdef\yquantgroup at alignments{\yquantgroup at alignments+1}%
+      % hopefully no prefixes/suffixes are installed - if we reset them here, it will also reset them for the content, which we don't want to do; but this will then give an error when we try to access the node. Probably never a problem.
+      \yquant [name=yquantgroup at internal@alignment@\yquantgroup at alignments]%
+         group\space equals {#2} (-);%
+      \ifnum\yquantgroup at alignments>1 %
+         \pgfcoordinate{yquantgroup at internal@alignment@\the\numexpr\yquantgroup at alignments-1\relax}{west}%
+         \pgf at xa=\pgf at x%
+         \pgfcoordinate{yquantgroup at internal@alignment@\yquantgroup at alignments}{west}%
+         \unless\ifdim\pgf at x>\pgf at xa%
+            \PackageError{yquant.sty}{Invalid alignment mark position}%
+                         {The desired alignment mark position would be to the left of an already existing mark.}%
+         \fi%
+      \fi%
+   \fi%
+}
+% END_FOLD
+
+% BEGIN_FOLD alignment
+\def\yquantgroup at shiftright{%
+   \@ifstar{\yquantgroup at shiftright@i1}%
+           {\yquantgroup at shiftright@i0}%
+}
+
+\def\yquantgroup at shiftright@i#1{%
+   \@ifnextchar[{\yquantgroup at shiftright@ii{#1}}%
+                {\yquantgroup at shiftright@ii{#1}[1]}%
+}
+
+\def\yquantgroup at shiftright@ii#1[#2]{%
+   % first check whether #2 is a pure number or a dimension
+   \expandafter\expandafter\expandafter\ifstrempty\expandafter\expandafter\expandafter{%
+      \expandafter\yquantgroup at shiftright@removedim\the\dimexpr#2pt\relax\relax%
+   }{%
+      % #2 was no dimension (appending pt made it one)
+      \ifnum#2=0 %
+         \dimdef\yquantgroup at currentxpos{-\yquant at config@operator at sep}%
+      \else%
+         \ifnum\yquantgroup at alignments<#2 %
+            \PackageError{yquant.sty}{Unknown alignment point}%
+                         {Alignment points must first be defined using \string\equals*.}%
+         \fi%
+         \pgfpointanchor{yquantgroup at internal@alignment@#2}{west}%
+         \dimdef\yquantgroup at currentxpos{\pgf at x-\yquant at config@operator at sep}%
+      \fi%
+   }{%
+      % #2 was a dimension (the pt\relax remained)
+      \dimdef\yquantgroup at currentxpos{\yquantgroup at currentxpos+#2}%
+   }%
+   \ifx1#1%
+      \ifnum\yquantgroup at alignments>0 %
+         \pgfcoordinate{yquantgroup at internal@alignment@\yquantgroup at alignments}{west}%
+         \unless\ifdim\dimexpr\yquantgroup at currentxpos+\yquant at config@operator at sep\relax>\pgf at x%
+            \PackageError{yquant.sty}{Invalid alignment mark position}%
+                         {The desired alignment mark position would be to the left of an already existing mark.}%
+         \fi%
+      \fi%
+      \numgdef\yquantgroup at alignments{\yquantgroup at alignments+1}%
+      \pgfcoordinate{yquantgroup at internal@alignment@\yquantgroup at alignments}%
+           {\pgfqpoint{\dimexpr\yquantgroup at currentxpos+\yquant at config@operator at sep\relax}%
+                      {\yquantgroup at currentypos}}%
+   \fi%
+}
+
+\def\yquantgroup at shiftright@removedim#1\relax{}
+% END_FOLD
+
+% BEGIN_FOLD breaks
+\def\yquantgroup at linebreak{%
+   \@ifnextchar[\yquantgroup at linebreak@i%
+                {\yquantgroup at linebreak@i[\yquantgroup at config@lineseparation]}%
+}
+
+\def\yquantgroup at linebreak@i[#1]{%
+   \ifdefined\yquant at prefix%
+      \yquant at env@end%
+   \else%
+      \PackageError{yquant.sty}{There is no line here to end}%
+                   {You did not start a circuit before requesting a line break.}%
+   \fi%
+   \def\yquantgroup at currentxpos{-\yquant at config@operator at sep}%
+   \dimdef\yquantgroup at currentypos{\pgf at picminy-#1}%
+   \ifyquantgroup at config@aligned%
+      \yquantgroup at shiftright@ii0[1]%
+   \fi%
+}
+
+\def\yquantgroup at nobreak{%
+   \PackageError{yquant.sty}{Page breaking disallowed in tikzpicture environment}%
+                {In order to allow for page breaking in a yquantgroup environment, move it outside of the tikzpicture.}%
+}
+
+\def\yquantgroup at bigbreak#1{%
+   \@ifstar{\yquantgroup at bigbreak@i{#1}1}{\yquantgroup at bigbreak@i{#1}0}%
+}
+
+\def\yquantgroup at bigbreak@i#1#2{%
+   \ifdefined\yquant at prefix%
+      \yquant at env@end%
+   \else%
+      \PackageError{yquant.sty}{There is no page here to end}%
+                   {You did not start a circuit before requesting a page break.}%
+   \fi%
+   % there is no cleanup of names when leaving a tikzpicture, so all the shapes are still there - all we have to do is to remember the correct number, and also be aware of the fact that the minimum x value in the picture needs to be preserved - else and left margin will just be dropped.
+   \ifx1#2%
+      \edef\tmp{%
+         \unexpanded{%
+            \yquantgroup at end@tikzpicture%
+            \par#1%
+            \yquantgroup at start@tikzpicture%
+         }%
+         \global\pgf at picminx=\the\pgf at picminx\space%
+         \ifyquantgroup at config@aligned%
+            \noexpand\yquantgroup at shiftright@ii0[1]%
+         \fi%
+      }%
+   \else%
+      \def\tmp{%
+         \yquantgroup at end@tikzpicture%
+         \par#1%
+         \yquantgroup at start@tikzpicture%
+         \def\yquantgroup at alignments{0}% the assignments were global, so we must rather reset them
+      }%
+   \fi%
+   \tmp%
+}
+
+\def\yquantgroup at pagebreak{%
+   \yquantgroup at bigbreak\yquantgroup at save@pagebreak%
+}
+
+\def\yquantgroup at newpage{%
+   \yquantgroup at bigbreak\yquantgroup at save@newpage%
+}
+
+\def\yquantgroup at clearpage{%
+   \yquantgroup at bigbreak\yquantgroup at save@clearpage%
+}
+
+\def\yquantgroup at cleardoublepage{%
+   \yquantgroup at bigbreak\yquantgroup at save@cleardoublepage%
+}
+% END_FOLD
+
+\endinput
\ No newline at end of file


Property changes on: trunk/Master/texmf-dist/tex/latex/yquant/yquantlanguage-groups.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property


More information about the tex-live-commits mailing list.