diff options
Diffstat (limited to 'graphics/pgf/contrib/tikz-feynman')
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/LICENSE | 1051 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/README.md | 115 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/references.bib | 122 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikz-feynman.pdf | bin | 0 -> 290598 bytes | |||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikz-feynman.sty | 41 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikz-feynman.tex | 1830 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikzfeynman.keys.code.tex | 815 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.0.lua | 1005 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.1.lua | 1037 | ||||
-rw-r--r-- | graphics/pgf/contrib/tikz-feynman/tikzlibraryfeynman.code.tex | 336 |
10 files changed, 6352 insertions, 0 deletions
diff --git a/graphics/pgf/contrib/tikz-feynman/LICENSE b/graphics/pgf/contrib/tikz-feynman/LICENSE new file mode 100644 index 0000000000..7c85a26f9a --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/LICENSE @@ -0,0 +1,1051 @@ +This documentation may be redistributed and/or modified under the terms of the +GNU General Public License as published by the Free Software Foundation, either +version 3 of the License, or (at your option) any later version. + +The code of this package may be distributed and/or modified under the conditions +of the LaTeX Project Public License, either version 1.3 of this license or (at +your option) any later version. + +A copy of both licenses are included hereunder: + +################################################################################ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + +################################################################################ + +The LaTeX Project Public License +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +LPPL Version 1.3c 2008-05-04 + +Copyright 1999 2002-2008 LaTeX3 Project + Everyone is allowed to distribute verbatim copies of this + license document, but modification of it is not allowed. + + +PREAMBLE +======== + +The LaTeX Project Public License (LPPL) is the primary license under +which the LaTeX kernel and the base LaTeX packages are distributed. + +You may use this license for any work of which you hold the copyright +and which you wish to distribute. This license may be particularly +suitable if your work is TeX-related (such as a LaTeX package), but +it is written in such a way that you can use it even if your work is +unrelated to TeX. + +The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE', +below, gives instructions, examples, and recommendations for authors +who are considering distributing their works under this license. + +This license gives conditions under which a work may be distributed +and modified, as well as conditions under which modified versions of +that work may be distributed. + +We, the LaTeX3 Project, believe that the conditions below give you +the freedom to make and distribute modified versions of your work +that conform with whatever technical specifications you wish while +maintaining the availability, integrity, and reliability of +that work. If you do not see how to achieve your goal while +meeting these conditions, then read the document `cfgguide.tex' +and `modguide.tex' in the base LaTeX distribution for suggestions. + + +DEFINITIONS +=========== + +In this license document the following terms are used: + + `Work' + Any work being distributed under this License. + + `Derived Work' + Any work that under any applicable law is derived from the Work. + + `Modification' + Any procedure that produces a Derived Work under any applicable + law -- for example, the production of a file containing an + original file associated with the Work or a significant portion of + such a file, either verbatim or with modifications and/or + translated into another language. + + `Modify' + To apply any procedure that produces a Derived Work under any + applicable law. + + `Distribution' + Making copies of the Work available from one person to another, in + whole or in part. Distribution includes (but is not limited to) + making any electronic components of the Work accessible by + file transfer protocols such as FTP or HTTP or by shared file + systems such as Sun's Network File System (NFS). + + `Compiled Work' + A version of the Work that has been processed into a form where it + is directly usable on a computer system. This processing may + include using installation facilities provided by the Work, + transformations of the Work, copying of components of the Work, or + other activities. Note that modification of any installation + facilities provided by the Work constitutes modification of the Work. + + `Current Maintainer' + A person or persons nominated as such within the Work. If there is + no such explicit nomination then it is the `Copyright Holder' under + any applicable law. + + `Base Interpreter' + A program or process that is normally needed for running or + interpreting a part or the whole of the Work. + + A Base Interpreter may depend on external components but these + are not considered part of the Base Interpreter provided that each + external component clearly identifies itself whenever it is used + interactively. Unless explicitly specified when applying the + license to the Work, the only applicable Base Interpreter is a + `LaTeX-Format' or in the case of files belonging to the + `LaTeX-format' a program implementing the `TeX language'. + + + +CONDITIONS ON DISTRIBUTION AND MODIFICATION +=========================================== + +1. Activities other than distribution and/or modification of the Work +are not covered by this license; they are outside its scope. In +particular, the act of running the Work is not restricted and no +requirements are made concerning any offers of support for the Work. + +2. You may distribute a complete, unmodified copy of the Work as you +received it. Distribution of only part of the Work is considered +modification of the Work, and no right to distribute such a Derived +Work may be assumed under the terms of this clause. + +3. You may distribute a Compiled Work that has been generated from a +complete, unmodified copy of the Work as distributed under Clause 2 +above, as long as that Compiled Work is distributed in such a way that +the recipients may install the Compiled Work on their system exactly +as it would have been installed if they generated a Compiled Work +directly from the Work. + +4. If you are the Current Maintainer of the Work, you may, without +restriction, modify the Work, thus creating a Derived Work. You may +also distribute the Derived Work without restriction, including +Compiled Works generated from the Derived Work. Derived Works +distributed in this manner by the Current Maintainer are considered to +be updated versions of the Work. + +5. If you are not the Current Maintainer of the Work, you may modify +your copy of the Work, thus creating a Derived Work based on the Work, +and compile this Derived Work, thus creating a Compiled Work based on +the Derived Work. + +6. If you are not the Current Maintainer of the Work, you may +distribute a Derived Work provided the following conditions are met +for every component of the Work unless that component clearly states +in the copyright notice that it is exempt from that condition. Only +the Current Maintainer is allowed to add such statements of exemption +to a component of the Work. + + a. If a component of this Derived Work can be a direct replacement + for a component of the Work when that component is used with the + Base Interpreter, then, wherever this component of the Work + identifies itself to the user when used interactively with that + Base Interpreter, the replacement component of this Derived Work + clearly and unambiguously identifies itself as a modified version + of this component to the user when used interactively with that + Base Interpreter. + + b. Every component of the Derived Work contains prominent notices + detailing the nature of the changes to that component, or a + prominent reference to another file that is distributed as part + of the Derived Work and that contains a complete and accurate log + of the changes. + + c. No information in the Derived Work implies that any persons, + including (but not limited to) the authors of the original version + of the Work, provide any support, including (but not limited to) + the reporting and handling of errors, to recipients of the + Derived Work unless those persons have stated explicitly that + they do provide such support for the Derived Work. + + d. You distribute at least one of the following with the Derived Work: + + 1. A complete, unmodified copy of the Work; + if your distribution of a modified component is made by + offering access to copy the modified component from a + designated place, then offering equivalent access to copy + the Work from the same or some similar place meets this + condition, even though third parties are not compelled to + copy the Work along with the modified component; + + 2. Information that is sufficient to obtain a complete, + unmodified copy of the Work. + +7. If you are not the Current Maintainer of the Work, you may +distribute a Compiled Work generated from a Derived Work, as long as +the Derived Work is distributed to all recipients of the Compiled +Work, and as long as the conditions of Clause 6, above, are met with +regard to the Derived Work. + +8. The conditions above are not intended to prohibit, and hence do not +apply to, the modification, by any method, of any component so that it +becomes identical to an updated version of that component of the Work as +it is distributed by the Current Maintainer under Clause 4, above. + +9. Distribution of the Work or any Derived Work in an alternative +format, where the Work or that Derived Work (in whole or in part) is +then produced by applying some process to that format, does not relax or +nullify any sections of this license as they pertain to the results of +applying that process. + +10. a. A Derived Work may be distributed under a different license + provided that license itself honors the conditions listed in + Clause 6 above, in regard to the Work, though it does not have + to honor the rest of the conditions in this license. + + b. If a Derived Work is distributed under a different license, that + Derived Work must provide sufficient documentation as part of + itself to allow each recipient of that Derived Work to honor the + restrictions in Clause 6 above, concerning changes from the Work. + +11. This license places no restrictions on works that are unrelated to +the Work, nor does this license place any restrictions on aggregating +such works with the Work by any means. + +12. Nothing in this license is intended to, or may be used to, prevent +complete compliance by all parties with all applicable laws. + + +NO WARRANTY +=========== + +There is no warranty for the Work. Except when otherwise stated in +writing, the Copyright Holder provides the Work `as is', without +warranty of any kind, either expressed or implied, including, but not +limited to, the implied warranties of merchantability and fitness for a +particular purpose. The entire risk as to the quality and performance +of the Work is with you. Should the Work prove defective, you assume +the cost of all necessary servicing, repair, or correction. + +In no event unless required by applicable law or agreed to in writing +will The Copyright Holder, or any author named in the components of the +Work, or any other party who may distribute and/or modify the Work as +permitted above, be liable to you for damages, including any general, +special, incidental or consequential damages arising out of any use of +the Work or out of inability to use the Work (including, but not limited +to, loss of data, data being rendered inaccurate, or losses sustained by +anyone as a result of any failure of the Work to operate with any other +programs), even if the Copyright Holder or said author or said other +party has been advised of the possibility of such damages. + + +MAINTENANCE OF THE WORK +======================= + +The Work has the status `author-maintained' if the Copyright Holder +explicitly and prominently states near the primary copyright notice in +the Work that the Work can only be maintained by the Copyright Holder +or simply that it is `author-maintained'. + +The Work has the status `maintained' if there is a Current Maintainer +who has indicated in the Work that they are willing to receive error +reports for the Work (for example, by supplying a valid e-mail +address). It is not required for the Current Maintainer to acknowledge +or act upon these error reports. + +The Work changes from status `maintained' to `unmaintained' if there +is no Current Maintainer, or the person stated to be Current +Maintainer of the work cannot be reached through the indicated means +of communication for a period of six months, and there are no other +significant signs of active maintenance. + +You can become the Current Maintainer of the Work by agreement with +any existing Current Maintainer to take over this role. + +If the Work is unmaintained, you can become the Current Maintainer of +the Work through the following steps: + + 1. Make a reasonable attempt to trace the Current Maintainer (and + the Copyright Holder, if the two differ) through the means of + an Internet or similar search. + + 2. If this search is successful, then enquire whether the Work + is still maintained. + + a. If it is being maintained, then ask the Current Maintainer + to update their communication data within one month. + + b. If the search is unsuccessful or no action to resume active + maintenance is taken by the Current Maintainer, then announce + within the pertinent community your intention to take over + maintenance. (If the Work is a LaTeX work, this could be + done, for example, by posting to comp.text.tex.) + + 3a. If the Current Maintainer is reachable and agrees to pass + maintenance of the Work to you, then this takes effect + immediately upon announcement. + + b. If the Current Maintainer is not reachable and the Copyright + Holder agrees that maintenance of the Work be passed to you, + then this takes effect immediately upon announcement. + + 4. If you make an `intention announcement' as described in 2b. above + and after three months your intention is challenged neither by + the Current Maintainer nor by the Copyright Holder nor by other + people, then you may arrange for the Work to be changed so as + to name you as the (new) Current Maintainer. + + 5. If the previously unreachable Current Maintainer becomes + reachable once more within three months of a change completed + under the terms of 3b) or 4), then that Current Maintainer must + become or remain the Current Maintainer upon request provided + they then update their communication data within one month. + +A change in the Current Maintainer does not, of itself, alter the fact +that the Work is distributed under the LPPL license. + +If you become the Current Maintainer of the Work, you should +immediately provide, within the Work, a prominent and unambiguous +statement of your status as Current Maintainer. You should also +announce your new status to the same pertinent community as +in 2b) above. + + +WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE +====================================================== + +This section contains important instructions, examples, and +recommendations for authors who are considering distributing their +works under this license. These authors are addressed as `you' in +this section. + +Choosing This License or Another License +---------------------------------------- + +If for any part of your work you want or need to use *distribution* +conditions that differ significantly from those in this license, then +do not refer to this license anywhere in your work but, instead, +distribute your work under a different license. You may use the text +of this license as a model for your own license, but your license +should not refer to the LPPL or otherwise give the impression that +your work is distributed under the LPPL. + +The document `modguide.tex' in the base LaTeX distribution explains +the motivation behind the conditions of this license. It explains, +for example, why distributing LaTeX under the GNU General Public +License (GPL) was considered inappropriate. Even if your work is +unrelated to LaTeX, the discussion in `modguide.tex' may still be +relevant, and authors intending to distribute their works under any +license are encouraged to read it. + +A Recommendation on Modification Without Distribution +----------------------------------------------------- + +It is wise never to modify a component of the Work, even for your own +personal use, without also meeting the above conditions for +distributing the modified component. While you might intend that such +modifications will never be distributed, often this will happen by +accident -- you may forget that you have modified that component; or +it may not occur to you when allowing others to access the modified +version that you are thus distributing it and violating the conditions +of this license in ways that could have legal implications and, worse, +cause problems for the community. It is therefore usually in your +best interest to keep your copy of the Work identical with the public +one. Many works provide ways to control the behavior of that work +without altering any of its licensed components. + +How to Use This License +----------------------- + +To use this license, place in each of the components of your work both +an explicit copyright notice including your name and the year the work +was authored and/or last substantially modified. Include also a +statement that the distribution and/or modification of that +component is constrained by the conditions in this license. + +Here is an example of such a notice and statement: + + %% pig.dtx + %% Copyright 2005 M. Y. Name + % + % This work may be distributed and/or modified under the + % conditions of the LaTeX Project Public License, either version 1.3 + % 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.3 or later is part of all distributions of LaTeX + % version 2005/12/01 or later. + % + % This work has the LPPL maintenance status `maintained'. + % + % The Current Maintainer of this work is M. Y. Name. + % + % This work consists of the files pig.dtx and pig.ins + % and the derived file pig.sty. + +Given such a notice and statement in a file, the conditions +given in this license document would apply, with the `Work' referring +to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being +generated from `pig.dtx' using `pig.ins'), the `Base Interpreter' +referring to any `LaTeX-Format', and both `Copyright Holder' and +`Current Maintainer' referring to the person `M. Y. Name'. + +If you do not want the Maintenance section of LPPL to apply to your +Work, change `maintained' above into `author-maintained'. +However, we recommend that you use `maintained', as the Maintenance +section was added in order to ensure that your Work remains useful to +the community even when you can no longer maintain and support it +yourself. + +Derived Works That Are Not Replacements +--------------------------------------- + +Several clauses of the LPPL specify means to provide reliability and +stability for the user community. They therefore concern themselves +with the case that a Derived Work is intended to be used as a +(compatible or incompatible) replacement of the original Work. If +this is not the case (e.g., if a few lines of code are reused for a +completely different task), then clauses 6b and 6d shall not apply. + + +Important Recommendations +------------------------- + + Defining What Constitutes the Work + + The LPPL requires that distributions of the Work contain all the + files of the Work. It is therefore important that you provide a + way for the licensee to determine which files constitute the Work. + This could, for example, be achieved by explicitly listing all the + files of the Work near the copyright notice of each file or by + using a line such as: + + % This work consists of all files listed in manifest.txt. + + in that place. In the absence of an unequivocal list it might be + impossible for the licensee to determine what is considered by you + to comprise the Work and, in such a case, the licensee would be + entitled to make reasonable conjectures as to which files comprise + the Work. diff --git a/graphics/pgf/contrib/tikz-feynman/README.md b/graphics/pgf/contrib/tikz-feynman/README.md new file mode 100644 index 0000000000..d37e445bfd --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/README.md @@ -0,0 +1,115 @@ +[Ti*k*Z-Feynman](http://www.jpellis.me/projects/tikz-feynman) [![ctan.org](https://img.shields.io/ctan/v/tikz-feynman.svg)](https://ctan.org/pkg/tikz-feynman) [![Travis](https://img.shields.io/travis/JP-Ellis/tikz-feynman/master.svg)](https://travis-ci.org/JP-Ellis/tikz-feynman) +============================================================= + +Ti*k*Z-Feynman is a LaTeX package allowing Feynman diagrams to be easily +generated within LaTeX with minimal user instructions and without the need of +external programs. It builds upon the Ti*k*Z package and leverages the graph +placement algorithms from Ti*k*Z in order to automate the placement of many +vertices. Ti*k*Z-Feynman still allows fine-tuned placement of vertices so that +even complex diagrams can still be generated with ease. + +Ti*k*Z-Feynman is made available through the +[Comprehensive TeX Archive Network (CTAN)][ctan] and comes with some thorough +[documentation][documentation] containing a tutorial and many examples. Please +refer to the [project page][projectpage] for additional information. + +Ti*k*Z-Feynman is open source and contribution are welcome. If you have any +suggestions, feature requests, or have found any bugs, feel free to create a new +issue or pull request on Github. + +Below are a few example to demonstrate how easy diagram can be, and how +extensible it can be. Many more are given in the +[documentation][documentation]: + +<p align="center"><img src="./images/qed.png" alt="QED Example" width=300px /></p> +```latex +\feynmandiagram [horizontal=a to b] { + i1 -- [fermion] a -- [fermion] i2, + a -- [photon] b, + f1 -- [fermion] b -- [fermion] f2, +}; +``` + +<p align="center"><img src="./images/penguin.png" alt="Penguin Example" width=300px /></p> +```latex +\feynmandiagram [large, vertical=e to f] { + a -- [fermion] b -- [photon, momentum=\(k\)] c -- [fermion] d, + b -- [fermion, momentum'=\(p_{1}\)] e -- [fermion, momentum'=\(p_{2}\)] c, + e -- [gluon] f, + h -- [fermion] f -- [fermion] i; +}; +``` + +<p align="center"><img src="./images/mixing.png" alt="Mixing Example" width=490px /></p> +```latex +\begin{tikzpicture} + \begin{feynman} + \vertex (a1) {\(\overline b\)}; + \vertex[right=1cm of a1] (a2); + \vertex[right=1cm of a2] (a3); + \vertex[right=1cm of a3] (a4) {\(b\)}; + \vertex[right=1cm of a4] (a5); + \vertex[right=2cm of a5] (a6) {\(u\)}; + + \vertex[below=2em of a1] (b1) {\(d\)}; + \vertex[right=1cm of b1] (b2); + \vertex[right=1cm of b2] (b3); + \vertex[right=1cm of b3] (b4) {\(\overline d\)}; + \vertex[below=2em of a6] (b5) {\(\overline d\)}; + + \vertex[above=of a6] (c1) {\(\overline u\)}; + \vertex[above=2em of c1] (c3) {\(d\)}; + \vertex at ($(c1)!0.5!(c3) - (1cm, 0)$) (c2); + + \diagram* { + {[edges=fermion] + (b1) -- (b2) -- (a2) -- (a1), + (b5) -- (b4) -- (b3) -- (a3) -- (a4) -- (a5) -- (a6), + }, + (a2) -- [boson, edge label=\(W\)] (a3), + (b2) -- [boson, edge label'=\(W\)] (b3), + + (c1) -- [fermion, out=180, in=-45] (c2) -- [fermion, out=45, in=180] (c3), + (a5) -- [boson, bend left, edge label=\(W^{-}\)] (c2), + }; + + \draw [decoration={brace}, decorate] (b1.south west) -- (a1.north west) + node [pos=0.5, left] {\(B^{0}\)}; + \draw [decoration={brace}, decorate] (c3.north east) -- (c1.south east) + node [pos=0.5, right] {\(\pi^{-}\)}; + \draw [decoration={brace}, decorate] (a6.north east) -- (b5.south east) + node [pos=0.5, right] {\(\pi^{+}\)}; + \end{feynman} +\end{tikzpicture} +``` + + [ctan]: https://ctan.org/pkg/tikz-feynman + [documentation]: http://www.jpellis.me/projects/tikz-feynman/tikz-feynman/tikz-feynman.pdf + [projectpage]: http://www.jpellis.me/projects/tikz-feynman + + +Licence +------- + +Ti*k*Z-Feynman + +Feynman Diagrams with Ti*k*Z + +Copyright (C) 2016 Joshua Ellis + + +This *documentation* may be redistributed and/or modified under the terms of the +GNU General Public License as published by the Free Software Foundation, either +version 3 of the License, or (at your option) any later version. + +The *code of this package* may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 of this +license or (at your option) any later version. + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is Joshua Ellis. + +This package is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. diff --git a/graphics/pgf/contrib/tikz-feynman/references.bib b/graphics/pgf/contrib/tikz-feynman/references.bib new file mode 100644 index 0000000000..7e222288ef --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/references.bib @@ -0,0 +1,122 @@ +@article{feynmf, + author = "Ohl, Thorsten", + title = "{Drawing Feynman diagrams with LaTeX and Metafont}", + journal = "Computer Physics Communications", + volume = 90, + year = 1995, + pages = "340-354", + doi = "10.1016/0010-4655(95)90137-S", + eprint = "hep-ph/9505351", + archivePrefix ="arXiv", + primaryClass = "hep-ph", + reportNumber = "IKDA-95-20", +} + +@article{axodraw, + title = "Axodraw", + journal = "Computer Physics Communications", + volume = 83, + number = 1, + pages = "45 - 58", + year = 1994, + issn = "0010-4655", + doi = "10.1016/0010-4655(94)90034-5", + author = "J.A.M. Vermaseren", +} + +@article{jaxodrawV1, + author = "Binosi, D. and Theussl, L.", + title = "{JaxoDraw: A Graphical user interface for drawing Feynman + diagrams}", + journal = "Computer Physics Communications", + volume = 161, + year = 2004, + pages = "76-86", + doi = "10.1016/j.cpc.2004.05.001", + eprint = "hep-ph/0309015", + archivePrefix ="arXiv", + primaryClass = "hep-ph", + reportNumber = "FTUV-03-0902", + SLACcitation = "%%CITATION = HEP-PH/0309015;%%" +} + +@article{jaxodrawV2, + author = "Binosi, D. and Collins, J. and Kaufhold, C. and Theussl, L.", + title = "{JaxoDraw: A Graphical user interface for drawing Feynman + diagrams. Version 2.0 release notes}", + journal = "Computer Physics Communications", + volume = 180, + year = 2009, + pages = "1709-1715", + doi = "10.1016/j.cpc.2009.02.020", + eprint = "0811.4113", + archivePrefix ="arXiv", + primaryClass = "hep-ph", + reportNumber = "ECT*-08-10", + SLACcitation = "%%CITATION = ARXIV:0811.4113;%%" +} + +@article{hu2005, + title = {Efficient, high-quality force-directed graph drawing}, + author = {Hu, Yifan}, + journal = {Mathematica Journal}, + volume = 10, + number = 1, + pages = {37--71}, + year = 2005, + publisher = {Redwood City, Ca.: Advanced Book Program, Addison-Wesley + Pub. Co., c1990-} +} + +@article{eades1991, + author = "Peter,Eades and Kozo,Sugiyama", + title = "How to Draw a Directed Graph", + journal = "Journal of Information Processing", + year = 1991, + volume = 13, + number = 4, + pages = "424--437", +} + +@phdthesis{pohlmann2011, + title = {Configurable graph drawing algorithms for the {TikZ} graphics + description language}, + author = {Pohlmann, Jannis}, + year = 2011, + school = {Institute of Theoretical Computer Science, Universit{\"a}t zu + L{\"u}beck, L{\"u}beck, Germany}, + url = + {http://www.tcs.uni-luebeck.de/downloads/papers/2011/2011-configurable-graph-drawing-algorithms-jannis-pohlmann.pdf} +} + +@Misc{tikz, + author = {Till Tantau}, + title = {The {TikZ} and {PGF} Packages}, + year = 2015, + url = {http://mirrors.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf}, +} + +@article{PhysRev.76.769, + title = {Space-Time Approach to Quantum Electrodynamics}, + author = {Feynman, R. P.}, + journal = {Phys. Rev.}, + volume = 76, + issue = 6, + pages = {769--789}, + numpages = 0, + year = 1949, + month = {Sep}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRev.76.769}, + url = {http://link.aps.org/doi/10.1103/PhysRev.76.769} +} + +@article{tikz-feynman, + title = {Tik{Z}-{F}eynman: {F}eynman diagrams with {T}ik{Z}}, + author = {Ellis, Joshua}, + archivePrefix = {arXiv}, + year = 2016, + eprint = {1601.05437}, + primaryClass = {hep-ph}, + url = {http://arxiv.org/abs/1601.05437}, +}
\ No newline at end of file diff --git a/graphics/pgf/contrib/tikz-feynman/tikz-feynman.pdf b/graphics/pgf/contrib/tikz-feynman/tikz-feynman.pdf Binary files differnew file mode 100644 index 0000000000..8b80a306ea --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikz-feynman.pdf diff --git a/graphics/pgf/contrib/tikz-feynman/tikz-feynman.sty b/graphics/pgf/contrib/tikz-feynman/tikz-feynman.sty new file mode 100644 index 0000000000..4586f34c25 --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikz-feynman.sty @@ -0,0 +1,41 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% TikZ-Feynman +% Feynman Diagrams with TikZ +% Copyright (C) 2015 Joshua Ellis +% +% +% This work may be distributed and/or modified under the conditions of the LaTeX +% Project Public License, either version 1.3 of this license or (at your option) +% any later version. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Joshua Ellis. +% +% This program is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +% FOR A PARTICULAR PURPOSE. See the LaTeX Project Public License for more +% details. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\tikzfeynman@date{2016/02/05} +\def\tikzfeynman@version@major{1} +\def\tikzfeynman@version@minor{1} +\def\tikzfeynman@version@patch{0} +\edef\tikzfeynman@version{\tikzfeynman@version@major.\tikzfeynman@version@minor.\tikzfeynman@version@patch} + +\ProvidesPackage{tikz-feynman}[\tikzfeynman@date v\tikzfeynman@version Feynman diagrams with TikZ] + +\RequirePackage{tikz}[2013/12/13] % v3.0.0 +\RequirePackage{ifluatex} +\RequirePackage{pgfopts} + +\usetikzlibrary{feynman} + +\endinput + +% Local Variables: +% TeX-master: "tikz-feynman" +% End: diff --git a/graphics/pgf/contrib/tikz-feynman/tikz-feynman.tex b/graphics/pgf/contrib/tikz-feynman/tikz-feynman.tex new file mode 100644 index 0000000000..c4c96d61aa --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikz-feynman.tex @@ -0,0 +1,1830 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% TikZ-Feynman +% Feynman Diagrams with TikZ +% Copyright (C) 2015 Joshua Ellis +% +% +% This LaTeX file is free: you can redistribute it and/or modify it under the +% terms of the GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) any later +% version. +% +% This is distributed in the hope that it will be useful, but WITHOUT ANY +% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +% A PARTICULAR PURPOSE. See the GNU General Public License for more details. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% HEADER +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\def\pgfautoxrefs{1} +\documentclass[a4paper,final]{ltxdoc} + +\usepackage{etex} + +%% Formatting +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage[vmargin=4cm, hmargin=3cm]{geometry} % Customize text width, page height, margins, etc. +% \usepackage{multicol} % {multicols}{n} environment +% \usepackage{pdflscape} % {landscape} environment + +%\usepackage{setspace} % Line spacing +%\singlespacing % 1-spacing (default) +%\onehalfspacing % 1,5-spacing +%\doublespacing % 2-spacing + +\usepackage{fontspec} % Allows other fonts to be specified +\setmainfont{EB Garamond}[ + Contextuals={Alternate}, + Numbers=OldStyle, +] +\setmonofont{Inconsolata-g}[ + Scale=MatchLowercase, +] +\newfontface\swshape{EB Garamond 12 Italic}[Style=Swash] + +\usepackage{microtype} % Fine small typographical details +\usepackage{titlesec} % Change section heading font +\titleformat*{\section}{\huge\scshape} +\titleformat*{\subsection}{\Large\scshape} +\titleformat*{\subsubsection}{\large\scshape} +\titleformat*{\paragraph}{\scshape} + +\usepackage[perpage]{footmisc} +\usepackage{enumitem} % Easily customize lists +\setlist[description]{font=\normalfont\scshape} + +%% Change the Table of Contents fonts +\usepackage{tocloft} +\renewcommand{\cftsecfont}{\normalfont\scshape} +\setlength\cftbeforesecskip{0pt} +\setcounter{tocdepth}{2} + +%% Language +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage[UKenglish]{babel} % Set up the language +\usepackage{csquotes} +\usepackage{siunitx} % Provides \SI{1}{\metre}, also \ang{90}. +\usepackage{textcomp} + +%% Graphics & Figure +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage{graphicx} % Allow graphics to be included +\usepackage{xcolor} % Define and use colours +% \usepackage{subcaption} % Subfigures inside a figure + +% Keep all pictures in the './img/' sub-directory. +\graphicspath{{./img/}} + +\usepackage{tikz} % Powerful drawing language +\usepackage{tikz-feynman} +\makeatletter +\tikzfeynmanset{compat=\tikzfeynman@version@major.\tikzfeynman@version@minor.\tikzfeynman@version@patch} +\makeatother + +%% TikZ pictures and plots can significantly increase the time it takes to +%% produce the output. The `external` TikZ library library defers the creation +%% of these figures to a sub-process which creates a separate PDF file which is +%% then simply imported into the main document. To call the sub-process, you +%% have to execute the appropriate makefile. If you are using LatexMk, you can +%% use the `.latexmkrc` to automatically do this for you. +%% +%% The following setup works on Linux, and should work on OS X too. +% \usetikzlibrary{external} +% \tikzexternalize[shell escape=-shell-escape, prefix=pgf-img/] +% \immediate\write18{mkdir -p pgf-img} +% \tikzset{ +% external/mode=list and make, +% external/system call={ +% lualatex \tikzexternalcheckshellescape -halt-on-error -interaction=batchmode -jobname="\image" "\texsource" || rm "\image.pdf"}, +% } + +%% Math Packages +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage{amsmath} % The core math package +\usepackage{amssymb} % Defines additional math fonts +\usepackage{mathtools} % Various extra maths functions +% \usepackage{cancel} % Show cancellations with \cancel{} +% \usepackage{autonum} % Only number referenced equations (must be loaded after cleverref) +\usepackage{dsfont} + +\usepackage[cmintegrals,varg]{newtxmath} % Nice math with Garamond + +%% Define \withnumber which forces the line to have number +\newcommand{\withnumber}{\refstepcounter{equation}\tag{\theequation}} + +%% Allows page breaks in math (1 = avoid if possible, 4 = whenever) +%% Page breaks can be avoided at particular places by using \\* +\allowdisplaybreaks[2] + +\DeclarePairedDelimiter{\angles}{\langle}{\rangle} + +%% Tables +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage{array} % New column types, including >{}x<{} +\usepackage{booktabs} % Provides nicer horizontal lines +\usepackage{multirow} % Allows cells to span multiple rows +%\usepackage{longtable} % Allows for tables to span multiple pages + +%% Define the maths version of clr columns. +\newcolumntype{C}{>{\(}c<{\)}} +\newcolumntype{L}{>{\(}l<{\)}} +\newcolumntype{R}{>{\(}r<{\)}} + +%% Other Packages +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\usepackage{listings} % Code listings +\usepackage{minted} % Use Pygments +\usepackage{fp} % Floating point arithmetics +\usepackage{makeidx} % Index creation +\usepackage{xr} % Cross-referencing +\usepackage[orig,UKenglish]{isodate} % Handle dates + +\usepackage{hyperref} % Automatically inserts hyperlinks. +\usepackage{cleveref} % Use `\cref{}` to reference anything + +\usepackage{autonum} + +%% Bibliography +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% hyperref should be loaded first +\usepackage[ + backend=biber, + style=phys, + autocite=inline, + biblabel=brackets, + eprint=true, + doi=true, + isbn=true, +]{biblatex} + +\addbibresource{references.bib} + +%% Other modifications +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% Modify the skip after each paragraph +\setlength{\parskip}{1ex plus 0.5ex minus 0.2ex} +\setlength{\parindent}{0pt} + +\providecommand{\LuaTeX}{Lua\TeX} +\providecommand{\tikzfeynmanname}{\tikzname-Feynman} +\providecommand{\pgfmanual}{\href{http://mirrors.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf}{\tikzname{} manual}} + +\IfFileExists{pgfmanual-en-macros}{ + \let\attribute\relax + \input{pgfmanual-en-macros} +}{ + \PackageError{tikz-feynman-manual}{ +This document requires the file pgfmanual-en-macros.tex (distributed +with pgf) to compile. Please place a copy of that file in the current +directory}{}} + +\makeindex + +\pgfkeys{ + /pdflinks/search key prefixes in={/tikzfeynman/} + /pdflinks/internal link prefix=tikzfeynman, + % + /pdflinks/warnings=false, + % for debugging: + /pdflinks/show labels=false, +} + +\makeatletter +%% Make table of content heading smaller +\renewcommand\tableofcontents{% + \section*{\normalfont\large\scshape\contentsname}% + \vspace{-1.5\baselineskip}% + \@starttoc{toc}% +} +\makeatother + +%% Define some slightly nicer colors +\definecolor{link-color}{RGB}{96 0 0} +\definecolor{cite-color}{RGB}{0 96 0} +\definecolor{file-color}{RGB}{0 0 96} +\definecolor{url-color}{RGB}{0 0 96} +\definecolor{link-border-color}{RGB}{255 159 159} +\definecolor{cite-border-color}{RGB}{159 255 159} +\definecolor{file-border-color}{RGB}{159 159 255} +\definecolor{url-border-color}{RGB}{159 159 255} + +\hypersetup{ + pdfborder=0 0 0, +} + +%% Change the abstract style +\renewenvironment{abstract}{ + \begin{center} + \begin{minipage}{0.9\textwidth} + \begin{center} + \Large + Abstract + \end{center}\vspace*{-1em} + \rule{\textwidth}{1pt} +}{ + \par\noindent + \rule{\textwidth}{1pt} + \end{minipage} + \end{center} +} + +%% Put the abstract only on the arXiv version +\newif\ifarxiv +\arxivfalse + +%% Acknowledgements go in two different places depending on whether it is the +%% arXiv version or not. Have the common code here. +\def\acknowledgements{ + \subsection*{Acknowledgements} + \label{subsec:acknowledgements} + + The original proof-of-concept for using \tikzname{} to draw Feynman diagrams + was done by the user `\href{http://tex.stackexchange.com/users/2552}{Jake}' on + the \TeX{} StackExchange. His original answer can be viewed at: + \url{http://tex.stackexchange.com/a/87395/26980}. + + I must also thank all the people who have used the development versions of + \tikzfeynmanname{} and offered suggestions to improve it and found bugs for me + to fix. +} + +%% Center codeexample +\makeatletter +\let\codeexample@orig=\codeexample +\let\endcodeexample@orig=\endcodeexample +\def\codeexample{ + \begin{center} + \codeexample@orig +} +\def\endcodeexample{ + \endcodeexample@orig + \end{center} +} + +%% Document Information +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\makeatletter +\newcommand{\@keywords}{} +\newcommand{\keywords}[1]{\renewcommand{\@keywords}{#1}} +\newcommand{\@institution}{} +\newcommand{\institution}[1]{\renewcommand{\@institution}{#1}} + +\AtBeginDocument{ + \hypersetup{ + pdftitle={\@title}, + pdfauthor={\@author}, + pdfkeywords={\@keywords}, + } +} +\makeatother + +\title{\tikzfeynmanname} +\author{Joshua \textsc{Ellis}} +\institution{ + ARC Centre of Excellence for Particle Physics at the Terascale \\ + School of Physics, The University of Melbourne \textsc{vic} 3010, Australia +} +\keywords{Feynman diagram, TeX, LaTeX, TikZ, pgf, TikZ-Feynman} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% DOCUMENT +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} +\pagenumbering{roman} + +\begin{titlepage} + \makeatletter + \begin{center} + \vspace*{1em} + \tikz\node[scale=1.5]{% + \color{gray}\Huge\ttfamily \char`\{\textcolor{red!75!black}{\@title}\char`\}}; + + + \vspace{0.5em} + {\huge Feynman diagrams with \tikzname} + + \vspace{0.7em} + {Version \texttt{\tikzfeynman@version} \qquad \origdate\printdateTeX{\tikzfeynman@date}} + + \vspace{1.3em} + {by \@author} \\[1em] + {\@institution} + \end{center} + \makeatother + + \vfill + +\begin{codeexample}[graphic=white] +\feynmandiagram [large, vertical=e to f] { + a -- [fermion] b -- [photon, momentum=\(k\)] c -- [fermion] d, + b -- [fermion, momentum'=\(p_{1}\)] e -- [fermion, momentum'=\(p_{2}\)] c, + e -- [gluon] f, + h -- [fermion] f -- [fermion] i; +}; +\end{codeexample} + + \vfill + + \begin{multicols}{2} + \tableofcontents + \end{multicols} +\end{titlepage} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% CONTENT +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\clearpage +\pagenumbering{arabic} + +\ifarxiv +\begin{abstract} + \tikzfeynmanname{} is a \LaTeX{} package allowing Feynman diagrams to be + easily generated within \LaTeX{} with minimal user instructions and without + the need of external programs. It builds upon the \tikzname{} package and + leverages the graph placement algorithms from \tikzname{} in order to automate + the placement of many vertices. \tikzfeynmanname{} still allows fine-tuned + placement of vertices so that even complex diagrams can be generated with + ease. +\end{abstract} +\fi + +\section{Introduction} +\label{sec:introduction} + +\tikzfeynmanname{} provides a new way to draw Feynman diagrams in \LaTeX{} that +does not rely on external programs and uses a clear extensible syntax. + +\ifarxiv\else +If you use \tikzfeynmanname{} in an academic setting, please cite: +\begin{quote} + \fullcite{tikz-feynman} +\end{quote} +\fi + +Feynman diagrams provide a description of interactions of subatomic particles in +a form that is clearer and more succinct than the corresponding mathematical +description. They were introduced by \citeauthor{PhysRev.76.769} and first +appear in his paper \citetitle{PhysRev.76.769} \cite{PhysRev.76.769}. Since +then, \LaTeX{} has become widely used to type-set scientific papers and +currently, two leading methods of drawing Feynman diagrams in \LaTeX{} are +\href{https://www.ctan.org/pkg/feynmf}{|feynMF|/|feynMP|} \cite{feynmf} and +\href{https://www.ctan.org/pkg/axodraw}{|AxoDraw|} \cite{axodraw}, with the +latter also featuring a \textsc{gui} front-end called +\href{http://jaxodraw.sourceforge.net}{|JaxoDraw|} \cite{jaxodrawV1,jaxodrawV2}. + +Both |feynMF|/|feynMP| and |AxoDraw| have quite complicated syntax. As an +example, the code to generate an \(\ell\ell \to \ell\ell\) scattering Feynman +diagram in each package is: +\begin{center} + \begin{tabular}{p{0.3\linewidth} p{0.27\linewidth} p{0.34\linewidth}} + |AxoDraw| & |feynMF|/|feynMP| & \tikzfeynmanname{} \\[-2em] +\begin{codeexample}[execute code=false] +\begin{picture} +\ArrowLine(190,270)(160,300) +\ArrowLine(160,240)(190,270) +\ArrowLine(270,300)(240,270) +\ArrowLine(240,270)(270,240) +\Photon(190,270)(240,270){4}{4.5} +\Vertex(190,270){1.5} +\Vertex(240,270){1.5} +\end{picture} +\end{codeexample} + & +\begin{codeexample}[execute code=false] +\begin{fmfchar*}(40,30) +\fmfpen{thick} +\fmfleft{i1,i2} +\fmfright{o1,o2} +\fmf{fermion}{i1,v1,o1} +\fmf{fermion}{i2,v2,o2} +\fmf{photon,label=$q$}{v1,v2} +\fmfdot{v1,v2} +\end{fmfchar*} +\end{codeexample} + & +\begin{codeexample}[execute code=false] +\feynmandiagram [horizontal=a to b] { + i1 -- [fermion] a -- [fermion] i2, + a -- [photon] b, + f1 -- [fermion] b -- [fermion] f2, +}; +\end{codeexample} \\[-2em] + \end{tabular} +\end{center} +The learning curves for both |AxoDraw| and |feynMF|/|feynMP| are quite steep, +and although this is partly resolved by using |JaxoDraw|, this requires an +external program. In addition, the creation of Feynman diagrams in +|feynMF|/|feynMP| requires further processing outside of \LaTeX{}. + +\tikzfeynmanname{} on the other hand uses a clear syntax and delegates the +positioning of vertices to algorithms originally developed by +\citeauthor{hu2005} \cite{hu2005}, and \citeauthor{eades1991} \cite{eades1991}, +both of which were implemented into \tikzname{} by \citeauthor{pohlmann2011} +\cite{pohlmann2011}. Since \tikzfeynmanname{} is built on \tikzname{}, users +can harness the power and extensibilty of \tikzname{} \cite{tikz} making it easy +to extend to accommodate individual needs. In order to produce more complicated +diagrams, relative or absolute positioning of vertices can also be used in +\tikzfeynmanname{} so that any diagram can be generated with relative ease. + +\tikzfeynmanname{} is made available through the +\href{https://ctan.org/pkg/tikz-feynman}{Comprehensive \TeX{} Archive Network + (\textsc{ctan})}\footnote{\url{https://ctan.org/pkg/tikz-feynman}} and can +also be downloaded from the +\href{http://www.jpellis.me/projects/tikz-feynman}{project + page}\footnote{\url{http://www.jpellis.me/projects/tikz-feynman}}. The +project is open source and contributions are welcome. The management of bugs +and feature requests is done at +\href{https://github.com/JP-Ellis/tikz-feynman}{Github}\footnote{\url{https://github.com/JP-Ellis/tikz-feynman}}. + +\tikzfeynmanname{}'s versioning will approximately follow +\href{http://semverg.org}{semantic versioning}. This means that changes in the +third number (|1.0.0| to |1.0.1|) will consist of bug fixes and very minor +changes but they should not change the output otherwise\footnote{That is, with + the exception of the bug that they are fixing.}. Changes in the second number +(|1.0.0| to |1.1.0|) will consist of new features but everything should be +backwards compatible. Finally, changes in the first number (|1.0.0| to |2.0.0|) +indicates a major change in the package and code written for |1.0.0| is not +guaranteed to work on |2.0.0|. The intended version of this package to use +should be indicated when the package is loaded with +|\usepackage[compat=x.y.z]{tikz-feynman}| so the user may be informed of any +discrepancyx. If needed, earlier versions may be downloaded from the +\href{http://www.jpellis.me/projects/tikz-feynman}{project + page}\footnote{\url{http://www.jpellis.me/projects/tikz-feynman}}. + +\subsection*{Licence} +\label{subsec:licence} + +This \emph{documentation} may be redistributed and/or modified under the terms +of the \textsc{gnu} General Public License as published by the Free Software +Foundation, either version 3 of the License, or (at your option) any later +version. + +The \emph{code of this package} may be distributed and/or modified under the +conditions of the \LaTeX{} Project Public License, either version 1.3 of this +license or (at your option) any later version. + +This work has the LPPL maintenance status `maintained'. + +The Current Maintainer of this work is Joshua Ellis. + +This package is distributed in the hope that it will be useful, but +\textsc{without any warranty}; without even the implied warranty of +\textsc{merchantability} or \textsc{fitness for a particular purpose}. + +\ifarxiv\else +\acknowledgements +\fi + + +\clearpage +\section{Tutorial} +\label{sec:tutorial} + +\subsection{Loading the Package} +\label{sibsec:loading_the_package} + +After installing the package, the \tikzfeynmanname{} package can be loaded with +|\usepackage{tikz-feynman}| in the preamble. It is recommend that you also +specify the version of \tikzfeynmanname{} to use with the optional package +argument |compat|: |\usepackage[compat=1.1.0]{tikz-feynman}|. This ensures that +any new versions of \tikzfeynmanname{} do not produce any undesirable changes +without warning. + +\subsection{A First Diagram} +\label{subsec:a_first_diagram} + +Feynman diagrams can be declared with the |\feynmandiagram| command. It is +analogous to the |\tikz| command from \tikzname~and requires a final semi-colon +(|;|) to finish the environment. For example, a simple \(s\)-channel diagram +is: + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + i1 -- [fermion] a -- [fermion] i2, + a -- [photon] b, + f1 -- [fermion] b -- [fermion] f2, +}; +\end{codeexample} + +Let's go through this example line by line: +\begin{description} +\item[Line 1] |\feynmandiagram| introduces the Feynman diagram and allows for + optional arguments to be given in the brackets \texttt{[\meta{options}]}. In + this instance, |horizontal=a to b| orients the algorithm outputs such that the + line through vertices |a| and |b| is horizontal. +\item[Line 2] The left fermion line is drawn by declaring three vertices (|i1|, + |a| and |i2|) and connecting them with edges |--|. Just like the + |\feynmandiagram| command above, each edge also take optional arguments + specified in brackets \texttt{[\meta{options}]}. In this instance, we want + these edges to have arrows to indicate that they are fermion lines, so we add + the |fermion| style to them. + + As you will see later on, optional arguments can also be given to the vertices + in exactly the same way. +\item[Line 3] This edge connects vertices |a| and |b| with an edge styled as a + photon. Since there is already a vertex labelled |a|, the algorithm will + connect it to a new vertex labeled |b|. +\item[Line 4] This line is analogous to line 2 and introduces two new vertices, + |f1| and |f2|. It re-uses the previously labelled |b| vertex. +\item[Line 5] Finish the declaration of the Feynman diagram. The final + semi-colon (|;|) is important. +\end{description} + +The name given to each vertex in the graph does not matter. So in this example, +|i1|, |i2| denote the initial particles; |f1|, |f2| denotes the final particles; +and |a|, |b| are the end points of the propagator. The only important aspect is +that what we called |a| in line 2 is also |a| in line 3 so that the underlying +algorithm treats them as the same vertex. + +The order in which vertices are declared does not matter as the default +algorithm re-arranges everything\footnote{It is possible for the algorithm to + get a litte confused in some circumstances, but these cases should be rather + rare. For some algorithms (such as the |layered~layout|), the order in which + vertices are introduces \emph{does} matter. This is documented in + \cref{subsubsec:diagram_keys}.}. For example, one might prefer to draw the +fermion lines all at once, as with the following example (note also that the way +we named vertices is completely different): + +\begin{codeexample}[] +\feynmandiagram [horizontal=f2 to f3] { + f1 -- [fermion] f2 -- [fermion] f3 -- [fermion] f4, + f2 -- [photon] p1, + f3 -- [photon] p2, +}; +\end{codeexample} + +As a final remark, the calculation of where vertices should be placed is usually +done through an algorithm written in Lua. As a result, \LuaTeX{} is required in +order to make use of these algorithms. If \LuaTeX{} is not used, +\tikzfeynmanname{} will default to a more rudimentary algorithm and will warn +the user instead. + +\subsection{Adding Styles} +\label{subsec:adding_styles} + +So far, the examples have only used the |photon| and |fermion| styles. The +\tikzfeynmanname{} package comes with quite a few extra styles for edges and +vertices which are all documented over in \cref{sec:documentation}. As an +example, it is possible to add momentum arrows with |momentum=|\meta{text}, and +in the case of end vertices, the particle can be labelled with +|particle=|\meta{text}. As an example, we take the generic \(s\)-channel +diagram from \cref{subsec:a_first_diagram} and make it a \(e^{+}e^{-} \to +\mu^{+}\mu^{-}\) diagram: +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + i1 [particle=\(e^{-}\)] -- [fermion] a -- [fermion] i2 [particle=\(e^{+}\)], + a -- [photon, edge label=\(\gamma\), momentum'=\(k\)] b, + f1 [particle=\(\mu^{+}\)] -- [fermion] b -- [fermion] f2 [particle=\(\mu^{-}\)], +}; +\end{codeexample} +In addition to the style keys documented below, style keys from \tikzname{} can +be used as well: +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + i1 [particle=\(e^{-}\)] -- [fermion, very thick] a -- [fermion, opacity=0.2] i2 [particle=\(e^{+}\)], + a -- [red, photon, edge label=\(\gamma\), momentum'={[arrow style=red]\(k\)}] b, + f1 [particle=\(\mu^{+}\)] -- [fermion, opacity=0.2] b -- [fermion, very thick] f2 [particle=\(\mu^{-}\)], +}; +\end{codeexample} +For a list of all the various styles that \tikzname{} provides, have a look at +the \pgfmanual; it is extremely thorough and provides many usage examples. + +\tikzfeynmanname{} also supports combining styles together which can be useful +in certain new models such as supersymmetry: +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + i1 [particle=\(\tilde W\)] -- [plain, boson] a -- [anti fermion] i2 [particle=\(q\)], + a -- [charged scalar, edge label=\(\tilde q\)] b, + f1 [particle=\(\tilde g\)] -- [plain, gluon] b -- [fermion] [particle=\(q\)], +}; +\end{codeexample} + +\subsection{When the Algorithm Isn't Enough} +\label{subsec:when_the_algorithm_isnt_enough} + +By default, the |\feynmandiagram| and |\diagram| commands use the +|spring layout| algorithm to place all the edges\footnote{For more details on + this layout and any other graph layouts available, see + \cref{subsubsec:diagram_keys}}. The |spring layout| algorithm attempts to +`spread out' the diagram as much as possible which---for most simpler +diagrams---gives a satisfactory result; however in some cases, this does not +produce the best diagram and this section will look at alternatives. There are +three main alternatives: +\begin{description} +\item[Add invisible edges] While still using the default algorithm, it is + possible to force certain vertices to be closer together by adding extra edges + and making them invisible through |draw=none|. The algorithm will treat these + extra edges in the same way, but they are simply not drawn at the end; + +\item[Use a different algorithm] In some circumstances, other algorithms may be + better suited. Some of the other graph layout algorithms are listed in + \cref{subsubsec:diagram_keys}, and an exhaustive list of all algorithms and + their parameters is given in the \pgfmanual; + +\item[Manual placement] As a last resort, very complicated or unusual diagrams + will require each vertex to be manually placed. +\end{description} + +\subsubsection{Invisible Edges} +\label{subsubsec:invisible_edges} + +The underlying algorithm treats all edges in exactly the same way when +calculating where to place all the vertices, and the actual drawing of the +diagram (after the placements have been calculated) is done separately. +Consequently, it is possible to add edges to the algorithm, but prevent them +from being drawn by adding |draw=none| to the edge style. + +This is particularly useful if you want to ensure that the initial or final +states remain closer together than they would have otherwise as illustrated in +the following example (note that |opacity=0.2| is used instead of |draw=none| to +illustrate where exactly the edge is located). + +\begin{codeexample}[] +% No invisible to keep the two photons together +\feynmandiagram [small, horizontal=a to t1] { + a [particle=\(\pi^{0}\)] -- [scalar] t1 -- t2 -- t3 -- t1, + t2 -- [photon] p1 [particle=\(\gamma\)], + t3 -- [photon] p2 [particle=\(\gamma\)], +}; +\end{codeexample} +\begin{codeexample}[] +% Invisible edge ensures photons are parallel +\feynmandiagram [small, horizontal=a to t1] { + a [particle=\(\pi^{0}\)] -- [scalar] t1 -- t2 -- t3 -- t1, + t2 -- [photon] p1 [particle=\(\gamma\)], + t3 -- [photon] p2 [particle=\(\gamma\)], + p1 -- [opacity=0.2] p2, +}; +\end{codeexample} + +\subsubsection{Alternative Algorithms} +\label{subsubsec:alternative_algorithms} + +The graph drawing library from \tikzname{} has several different algorithms to +position the vertices\footnote{See \cref{subsubsec:diagram_keys} for some + alternative algorithms.} By default, |\diagram| and |\feynmandiagram| use the +|spring layout| algorithm to place the vertices. The |spring layout| attempts +to spread everything out as much as possible which, in most cases, gives a nice +diagram; however, there are certain cases where this does not work. A good +example where the |spring layout| doesn't work are decays where we have the +decaying particle on the left and all the daughter particles on the right. +\begin{codeexample}[] +% Using the default spring layout +\feynmandiagram [horizontal=a to b] { + a [particle=\(\mu^{-}\)] -- [fermion] b -- [fermion] f1 [particle=\(\nu_{\mu}\)], + b -- [boson, edge label=\(W^{-}\)] c, + f2 [particle=\(\overline \nu_{e}\)] -- [fermion] c -- [fermion] f3 [particle=\(e^{-}\)], +}; +\end{codeexample} +\begin{codeexample}[] +% Using the layered layout +\feynmandiagram [layered layout, horizontal=a to b] { + a [particle=\(\mu^{-}\)] -- [fermion] b -- [fermion] f1 [particle=\(\nu_{\mu}\)], + b -- [boson, edge label'=\(W^{-}\)] c, + c -- [anti fermion] f2 [particle=\(\overline \nu_{e}\)], + c -- [fermion] f3 [particle=\(e^{-}\)], +}; +\end{codeexample} +You may notice that in addition to adding the |layered layout| style to +|\feynmandiagram|, we also changed the order in which we specify the vertices. +This is because the |layered layout| algorithm does pay attention to the order +in which vertices are declared (unlike the default |spring layout|); as a +result, |c--f2, c--f3| has a different meaning to |f2--c--f3|. In the former +case, |f2| and |f3| are both on the layer below |c| as desired; whilst the +latter case places |f2| on the layer above |c| (that, the same layer as where +the \(W^{-}\) originates). + +\subsubsection{Manual Placement} +\label{subsubsec:manual_placement} + +In more complicated diagrams, it is quite likely that none of the algorithms +work, no matter how many invisible edges are added. In such cases, the vertices +have to be placed manually. \tikzfeynmanname{} allows for vertices to be +manually placed by using the |\vertex| command. + +The |\vertex| command is available only within the |feynman| environment (which +itself is only available inside a |tikzpicture|). The |feynman| environment +loads all the relevant styles from \tikzfeynmanname{} and declares additional +\tikzfeynmanname-specific commands such as |\vertex| and |\diagram|. This is +inspired from PGFPlots and its use of the |axis| environment. + +The |\vertex| command is very much analogous to the |\node| command from +\tikzname{}, with the notable exception that the vertex contents are optional; +that is, you need not have |{|\meta{text}|}| at the end. In the case where |{}| +is specified, the vertex automatically is given the |particle| style, and +otherwise it is a usual (zero-sized) vertex. + +To specify where the vertices go, it is possible to give explicit coordinates +though it is probably easiest to use the |positioning| library from \tikzname{} +which allows vertices to be placed relative to existing vertices\footnote{The + \pgfmanual{} has some extensive documentation explaining how to use the + |positioning| library.}. By using relative placements, it is possible to +easily tweak one part of the graph and everything will adjust accordingly---the +alternative being to manually adjust the coordinates of every affected vertex. + +Finally, once all the vertices have been specified, the |\diagram*| command is +used to specify all the edges. This works in much the same way as |\diagram| +(and also |\feynmandiagram|), except that it uses an very basic algorithm +to place new nodes and allows existing (named) nodes to be included. In order +to refer to an existing node, the node must be given in parentheses. + +This whole process of specifying the nodes and then drawing the edges between +them is shown below for the muon decay: + +\begin{codeexample}[] +\begin{tikzpicture} + \begin{feynman} + \vertex (a) {\(\mu^{-}\)}; + \vertex [right=of a] (b); + \vertex [above right=of b] (f1) {\(\nu_{\mu}\)}; + \vertex [below right=of b] (c); + \vertex [above right=of c] (f2) {\(\overline \nu_{e}\)}; + \vertex [below right=of c] (f3) {\(e^{-}\)}; + + \diagram* { + (a) -- [fermion] (b) -- [fermion] (f1), + (b) -- [boson, edge label'=\(W^{-}\)] (c), + (c) -- [anti fermion] (f2), + (c) -- [fermion] (f3), + }; + \end{feynman} +\end{tikzpicture} +\end{codeexample} + +\clearpage +\section{Documentation} +\label{sec:documentation} + +\subsection{Commands \emph{\&} Environments} +\label{subsec:commands} + +\begin{command}{\tikzfeynmanset\marg{options}} + This command will process \meta{options} using |\pgfkeys| with the default + path set to |/tikzfeynman|. Typically, \meta{options} will be a + comma-separated list of the form \meta{key}|=|\meta{value}, though the full + power of the mechanism behind |\pgfkeys| can be used (see the \pgfmanual{} for + a complete description). + + Typically, this is used in the preamble of the document to add or change + certain keys for the whole document. +\end{command} + +\begin{command}{\feynmandiagram\opt{\oarg{TikZ options}\oarg{diagram options}}\marg{diagram instructions}} + This commands creates a |{tikzpicture}| and |{feynman}| environment, and + places a |\diagram| inside with the provided \meta{diagram instruction}. + Please refer to the documentation for |\diagram| for the \meta{diagram + instruction} syntax. + + The optional arguments specified in \meta{tikz options} are passed on to the + |{tikzpicture}|, and the \meta{diagram options} are passed on to |\diagram|. + If only one optional argument is given, then the optional arguments are given + to both. A single optional argument will usually suffice as most keys are + recognized by both commands; however, in the event that a key is not + recognized, both options are provided. +\end{command} + +\begin{environment}{{feynman}\opt{\oarg{options}}} + The |{feynman}| environment is where all the drawing of Feynman diagrams takes + place. It makes all the \tikzfeynmanname{} styles available and defines + commands such as |\vertex| and |\diagram| which are otherwise unavailable + outside of this environment. The |{feynman}| environment is only accessible + within the |{tikzpicture}| environment. + + Options which are passed in \meta{options} apply for the whole environment in + the same way that the |{scope}| environment work in \tikzname. + + \begin{command}{\vertex\opt{\oarg{options}} (\meta{name}) \opt{at (\meta{coordinate})} \opt{\marg{contents}};} + Defines a new vertex with the provided \meta{name}. If \meta{contents} is + not provided, the resulting vertex will have zero size. On the other hand, + if \meta{contents} is provided, the |particle=|\meta{contents} style is + applied. Additional styles can be applied to the vertex through + \meta{options}. + + The final semicolon (|;|) is vital for this command since without it, the + \LaTeX{} engine will not know when the |\vertex| command ends. + Additionally, this command \emph{cannot} be chained like one can do with the + inbuilt \tikzname{} commands. + + This command is only available with the |{feynman}| environment. + \end{command} + + \begin{command}{\diagram\opt{\oarg{options}}\marg{diagram instructions}} + Begins a new diagram using the |spring layout|. Keys passed through + \meta{options} can include general \tikzname{} keys, graph-specific keys and + any applicable \tikzfeynmanname{} keys too. Other algorithms (such as |tree + layout|) can be passed through \meta{options} and that will override the + |spring layout|. + + The syntax for the \meta{diagram instructions} is thoroughly described in + the \pgfmanual, but in the context of this package, it will usually suffice + to know the following: + \begin{itemize} + \item Vertices within the graph are specified with no delimiters (i.e.~no + parenthesis, no brackets) and only require spaces around either side. In + order to refer to a vertex defined outside of the |\diagram| command, its + name must be given in parenthesis: |(|\meta{name}|)|. Note that in order + to refer to external vertices, one must use |\diagram*| as most algorithms + (including the default |spring layout|) are incompatible with vertices + defined outside of the algorithm. + + When a vertex name is used multiple times, the underlying algorithm will + consider them to be the same vertex and introduces additional edges. + + Options can be given to the vertex in brackets after the name: \meta{name} + |[|\meta{options}|]|. For vertices defined outside of the |\diagram| + command, these options should be specified when the vertex is first + declared. + + \item The edges between each pair of vertices is specified with |--|, and + these can be chained together: \verb|a -- b -- c|. In order to pass a + style to the edge, it is specified in brackets after the dashed: + |-- | \oarg{options}. For example, to make on edge red, one would use + |-- [red]|. + + \item A comma (|,|)---or equivalently a semicolon (|;|)---specifies the end + of a sequence of edges and vertices and allows for another sequence to be + started. So \verb|a -- b, c -- d| will create two disconnected edges. + + \item Subgroups (aking to scopes in \tikzname) are specified with braces: + |{|\oarg{options}\meta{diagram instructions}|}|. This can be quite + useful when a lot of edges or nodes share a common style. For example, + one could use |{[edges={fermion}]|\verb| a -- b -- c, x -- y -- z}| and + every edge will have the |fermion| style applied automatically. + + Another useful feature of subgroups is that an edge to a group will create + an edge to each vertex in that subgroup as shown below. The example also + shows how they can be nested which in some cases (such as with a + |layered layout|) can be extremely useful. + +\begin{codeexample}[] +\feynmandiagram [nodes=circle, horizontal=a1 to b3] { + a1 -- {b1, b2, b3 -- {c1, c2 -- d1}} +}; +\end{codeexample} + \end{itemize} + \end{command} + + \begin{command}{\diagram*\opt{\oarg{options}}\marg{diagram instructions}} + Same as |\diagram|, but instead of using the |spring layout| algorithm to + place the vertices, this uses the most basic algorithm. This basic + algorithm in most cases will not produce a satisfactory diagram, but is + intended to be used with vertices are declared and positioned outside of the + |\diagram*| command. Essentially, |\diagram*| should be used only to + connect existing vertices. + \end{command} +\end{environment} + + + +\subsection{Keys \emph{\&} Styles} +\label{subsec:Keys} + +The various styles and options that allow the Feynman diagrams to be customized +are defined in what \tikzname{} calls \emph{keys}. The documentation includes +all keys which are defined within \tikzfeynmanname{} which all begin with the +prefix |/tikzfeynman|. In addition, a few of the keys from \tikzname{} itself +which are particularly useful to \tikzfeynmanname{} are documented and these are +prefixed with |/tikz| or |/graph drawing|. Please refer to the \pgfmanual{} for +a more in thorough documentation of the \tikzname{} keys. + + +\tikzfeynmanname{} provides many |every |\meta{key} which allow every instance +of \meta{key} to be modified. For example, to make every diagram red except for +small diagrams which should be blue, then one would add to the preamble: +\begin{codeexample}[execute code=false] +\tikzfeynmanset{ + every diagram={red}, + every small={blue}, +} +\end{codeexample} +If you are completely unhappy with a particular inbuilt style, you can define +your own style with with \meta{key}|/.style={...}| as shown in the +following example: +\begin{codeexample}[execute code=false] +\tikzfeynmanset{ + myblob/.style={ + shape=circle, + draw=blue, + fill=red, + } +} +\end{codeexample} + +All the keys defined here are made available inside the |{feynman}| environment +and inside |\feynmandiagram|; but if you wish to access them outside of this +(say, in a regular |{tikzpicture}| environment), you will need to specify the +full path with the leading |/tikzfeynman|. + +\subsubsection{Feynman Keys} +\label{subsubsec:feynman_keys} + +\begin{keylist}{% + /tikzfeynman/execute at begin feynman=\marg{\TeX{} code}, + /tikzfeynman/execute at end feynman=\marg{\TeX{} code}} + Allows for custom code to be executed at the start or end of each |{feynman}| + environment. +\end{keylist} + +\begin{key}{/tikzfeynman/every feynman=\meta{styles}} + Set of styles which are applied to every |{feynman}| environments (and + consequently, every apply inside all |\feynmandiagram| too). The style also + applies to regular \tikzname{} commands used inside the |{feynman}| + environment. + +\begin{codeexample}[] +\tikzfeynmanset{every feynman={red}} +\begin{tikzpicture} + \node at (0, 0.5) {This is not red}; + \begin{feynman} + \node at (0, -0.5) {This is red}; + \end{feynman} +\end{tikzpicture} +\end{codeexample} +\end{key} + +\begin{stylekey}{/tikzfeynman/inline=\meta{node}} + A style used to display a Feynman diagram inline (typically in an equation), + and aligning such that its vertical placement is at the node specified. The + node specification must enclosed in parentheses. For nodes which contain text + (such as when the |particle| style is applied), it is possible to use the + baseline of the text inside the node to line up with the baseline of the + equation by using |(|\meta{node}|.base)| as demonstrated in the following + example. Note that this key applies additional styles to make the diagram fit + in an equation more nicely; if you do not wish to have these additional + styles, use the |baseline| key. + + \begin{equation} + \feynmandiagram [inline=(d.base), horizontal=d to b] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d [particle=\(\gamma\)], + }; + = i g_{e} \gamma^{\mu} + \end{equation} + +\begin{codeexample}[execute code=false] +\begin{equation} + \feynmandiagram [inline=(d.base), horizontal=d to b] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d [particle=\(\gamma\)], + }; + = i g_{e} \gamma^{\mu} +\end{equation} +\end{codeexample} +\end{stylekey} + +\begin{key}{/tikz/baseline=\meta{node}} + Changes the vertical alignment of the Feynman diagram such that it diagram's + baseline is at the node specified. This works in the same was as + |inline=|\meta{node}, but it does not apply any additional styles (notice how + the following example is larger than the one above). + \begin{equation} + \feynmandiagram [baseline=(d.base), horizontal=d to b] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d [particle=\(\gamma\)], + }; + = i g_{e} \gamma^{\mu} + \end{equation} + +\begin{codeexample}[execute code=false] +\begin{equation} + \feynmandiagram [baseline=(d.base), horizontal=d to b] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d [particle=\(\gamma\)], + }; + = i g_{e} \gamma^{\mu} +\end{equation} +\end{codeexample} +\end{key} + +\begin{keylist}{% + /graph drawing/horizontal=\meta{node} to \meta{node}, + /graph drawing/horizontal'=\meta{node} to \meta{node}, + /graph drawing/vertical=\meta{node} to \meta{node}, + /graph drawing/vertical'=\meta{node} to \meta{node}} + The underlying algorithm will arrange all the nodes relative to each other, + but beyond that it has no idea how the overall graph should be oriented. + By using one of the above keys, the final output of the algorithm is oriented + and/or mirrored such that the two nodes specified are on the same horizontal + (or vertical) line. The two nodes need not actually be connected by an edge + for this to work. + + The two \meta{node} specifications should \emph{not} be enclosed in + parentheses, unlike the |inline| and |baseline| keys. + + The |horizontal'| and |vertical'| keys work in the same was as |horizontal| + and |vertical|, but with a flip. + +\begin{codeexample}[] +\feynmandiagram [inline=(b), horizontal=a to b, red] { + a -- b -- {c [particle=\(c\)], d [particle=\(d\)]} +}; +\feynmandiagram [inline=(b), horizontal'=a to b, blue] { + a -- b -- {c [particle=\(c\)], d [particle=\(d\)]} +}; +\feynmandiagram [inline=(b), vertical=a to b, green!40!black] { + a -- b -- {c [particle=\(c\)], d [particle=\(d\)]} +}; +\feynmandiagram [inline=(b), vertical=b to a, black] { + a -- b -- {c [particle=\(c\)], d [particle=\(d\)]} +}; +\end{codeexample} +\end{keylist} + +\subsubsection{Diagram Keys} +\label{subsubsec:diagram_keys} + +\begin{key}{/tikzfeynman/every diagram=\meta{styles}} + Set of styles which are applied to every diagram; that is, to everything + inside the |\feynmandiagram|, |\diagram| and |\diagram*| commands but not the + general |{feynman}| environment (see \cref{subsubsec:feynman_keys} for that). + +\begin{codeexample}[] +\tikzfeynmanset{every diagram={red}} +\feynmandiagram [small, horizontal=d to b] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d, +}; +\end{codeexample} +\end{key} + +\begin{keylist}{% + /tikzfeynman/small, + /tikzfeynman/medium, + /tikzfeynman/large} + Changes the default separation between the vertices and changes the size of + arrows, blobs, and other shapes to fit different context. The |small| size is + best used with when the diagram is quite simple and doesn't have too many + annotations (such as momentum arrows and particle labels). The |medium| size + is the default and is usually large enough that even diagrams with many labels + and momentum arrows do not become too cluttered. Finally the |large| key is + best for large illustrations as used on the title page of this document. + +\begin{codeexample}[] +\feynmandiagram [baseline=(b), small, horizontal=d to b, red] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d, +}; +\feynmandiagram [baseline=(b), medium, horizontal=d to b, green!40!black] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d, +}; +\feynmandiagram [baseline=(b), large, horizontal=d to b, blue] { + a -- [fermion] b -- [fermion] c, + b -- [boson] d, +}; +\end{codeexample} +\end{keylist} + +There are several algorithms which are available to place the vertices which are +all provided within the |graph drawing| library from \tikzname. Below are +listed a few of these layouts which are more relevant for drawing Feynman +diagrams. For a more complete description of how these algorithm work, please +refer to the \pgfmanual{}. Please note that most graph drawing algorithms are +implemented in Lua and thus require \LuaTeX{} in order to work. If \LuaTeX{} is +not used, \tikzfeynmanname{} will default to a more rudimentary algorithm and +will warn the user instead. + +\begin{key}{/graph drawing/spring layout=\opt{\meta{string}}} + Uses Hu's spring layout \cite{hu2005} as implemented by Pohlmann + \cite{pohlmann2011}. This models each edge as springs and attempts to spread + everything out as much as possible. This is the default layout. + +\begin{codeexample}[] +\feynmandiagram [nodes=circle, small, horizontal=c to d] { + {a, b} -- c -- d -- {e, f}, +}; +\end{codeexample} +\end{key} + +\begin{key}{/graph drawing/spring electrical layout=\opt{\meta{string}}} + Uses Hu's spring electrical layout \cite{hu2005} as implemented by Pohlmann + \cite{pohlmann2011}. This models each edge as springs and gives each vertex a + charge. This algorithm allows for the charge of a particular vertex to be + adjusted using the |electric charge| key (the default is |1|). + +\begin{codeexample}[] +\feynmandiagram [nodes=circle, + small, horizontal=c to d, + spring electrical layout + ] { + {a, b [electric charge=2]} -- c -- d -- {e, f [electric charge=0.1]}, +}; +\end{codeexample} +\end{key} + +\begin{key}{/graph drawing/layered layout=\opt{\meta{string}}} + Uses the Sugiyama layout algorithm \cite{eades1991} as implemented by Pohlmann + \cite{pohlmann2011} in order to place the node. + + When an edge is specified, the first vertex is always located on the layer + above the second vertex. This creates a hierarchy of vertices which is + particularly useful for decays. + + Two vertices can be forced to be on the same layer with the + |/graph drawing/same layer| key. + +\begin{codeexample}[] +\feynmandiagram [nodes=circle, small, horizontal=a to b, layered layout] { + a -- b -- {c, d -- {e, f}}, +}; +\end{codeexample} +\begin{codeexample}[] +\feynmandiagram [nodes=circle, small, horizontal=a to b, layered layout] { + a -- b -- {c -- {c1, c2}, d -- {d1, d2}}, + {[same layer] c1, d}, +}; +\end{codeexample} +\end{key} + +\begin{key}{/graph drawing/tree layout=\opt{\meta{string}}} + Uses the Reingold--Tilform algorithm in order to place the node. This works + in a similar way to the layered layout, but has quite a lot of additional + options to handle missing children in the tree. Please refer to the + \pgfmanual{} for a thorough description of these additional features. + + When an edge is specified, the first vertex is always located on the layer + above the second vertex. This creates a hierarchy of vertices which is + particularly useful for decays. + +\begin{codeexample}[] +\feynmandiagram [nodes=circle, small, horizontal=a to b, tree layout] { + a -- b -- {c, d -- {e, f}}, +}; +\end{codeexample} +\begin{codeexample}[] +\feynmandiagram [nodes=circle, small, horizontal=a to b, tree layout] { + a -- b -- {c -- {c1, c2}, d -- {d1, d2}}, +}; +\end{codeexample} +\end{key} + +\begin{keylist}{% + /tikz/graphs/edges=\meta{options}, + /tikz/graphs/nodes=\meta{options}} + Just like it is possible to change the shape of every vertex or edge in the + whole document, it is also possible to change the shape of every vertex or + edge in a single diagram by modifying these keys and adding the desired + styles. +\end{keylist} + +\subsubsection{Vertex Keys} +\label{subsubsec:vertex_keys} + +\begin{key}{/tikzfeynman/vertex} + The default, base style applied to every vertex initially. Other styles + are subsequently added. This sets the vertex |shape| to be a |coordinate|, + that is, a null shape with no size or width. +\end{key} + +\begin{key}{/tikzfeynman/every \meta{vertex shape}=\meta{styles}} + The style of specific vertices can be modified by changing the appropriate + |every |\meta{vertex shape} key. For example, in order to change the style of + every |dot|-styled vertex, you can modify the |every dot| key, or to modify + every vertex globally, the |every vertex| key can be modified. + +\begin{codeexample}[] +\tikzfeynmanset{ + every vertex={red, dot}, + every particle={blue}, + every blob={draw=green!40!black, pattern color=green!40!black}, +} +\feynmandiagram [horizontal=a to b] { + a [particle={\(\gamma, Z\)}] -- [boson] b [blob], + c -- [fermion] b -- [fermion] d, +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/dot} + Modifies the vertex so that it has a small filled circle. + +\begin{codeexample}[] +\feynmandiagram [small] { + a -- b [dot] -- {c, d} +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/square dot} + Modifies the vertex so that it has a small filled square. + +\begin{codeexample}[] +\feynmandiagram [small] { + a -- b [square dot] -- {c, d} +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/empty dot} + Modifies the vertex so that it has a small empty circle. + +\begin{codeexample}[] +\feynmandiagram [small] { + a -- b [empty dot] -- {c, d} +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/crossed dot} + Modifies the vertex so that it has a small circle with a cross inside. + +\begin{codeexample}[] +\feynmandiagram [small] { + a -- b [crossed dot] -- {c, d} +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/blob} + Modifies the vertex so that it is a large blob, usually used to denote an + effective operator. + +\begin{codeexample}[] +\feynmandiagram [small] { + a -- b [blob] -- {c, d} +}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/particle=\meta{name}} + Modifies the vertex so that it shows \meta{name}. This is intended to label + initial and final particles, but it should not be used on internal vertices as + it will result in the lines at the vertex having a gap. For propagators (the + |edge label| key is much more appropriate). + + Note that if \meta{name} contains characters such as brackets (|[]|) or + commas (|,|), the whole \meta{name} has to be enclosed in braces (|{}|); + otherwise, the parser will interpret the comma as the end of the \meta{name} + and the start of the next key, or the closing bracket as the end of all + optional arguments. + +\begin{codeexample}[] +\feynmandiagram [small, horizontal=a to b] { + a [particle={\(\gamma, Z\)}] -- [boson] b -- {c, d}, +}; +\end{codeexample} +\end{key} + + +\subsubsection{Edge Keys} +\label{subsubsec:edge_keys} + +Just like with the various vertex keys, each edge type has a corresponding +|every |\meta{edge type}; however, due to the existence of very similar keys +such as |scalar|, |charged scalar| and |anti charged scalar|, more specific keys +inherit styles from less specific ones. For example, styles in |every scalar| +will apply to |charged scalar| and |anti charged scalar|. + +The edge styles do not override each other and instead stack. This means that +an edge styled with both |boson| and |fermion| will consist of a straight line +with a wavy line on top and an error. If not styles are provided, then a simple +solid line is drawn. + +\begin{key}{/tikzfeynman/every edge=\meta{styles}} + A style to apply to every edge initially. +\end{key} + +\begin{stylekey}{/tikzfeynman/every \meta{edge style}=\meta{styles}} + The style of specific edges can be modified by changing the appropriate + |every |\meta{edge style} key. For example, in order to make a global change + to every |boson|, you can modify the |every boson| key. + +\begin{codeexample}[] +\tikzfeynmanset{ + every edge={green}, + every boson={red}, + every photon={blue}, +} +\feynmandiagram [small] { + a [particle=\(a\)] -- [boson] o -- [photon] b [particle=\(b\)], + f1 [particle=\(c\)] -- [fermion] o -- [scalar] f2 [particle=\(d\)], +}; +\end{codeexample} +\end{stylekey} + +\begin{key}{/tikzfeynman/plain} + Draws a simple solid line. This style is identical to the default style + applied if no other style is used, but is provided so that it can be combined + with other styles. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [plain] b}; +\feynmandiagram [horizontal=a to b] {a -- [plain, gluon] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/boson} + Draws a sinusoidal line to denote a boson. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [boson] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/charged boson} + Draws a sinusoidal line with an arrow to denote a charged boson. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [charged boson] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/anti charged boson} + Draws a sinusoidal line with an arrow pointing the other way to to denote a + anti charged boson. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [anti charged boson] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/photon} + Draws a sinusoidal line to denote a photon. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [photon] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/scalar} + Draws a dashed line to denote a scalar. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [scalar] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/charged scalar} + Draws a dashed line with an arrow to denote a charged scalar. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [charged scalar] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/anti charged scalar} + Draws a dashed line with an arrow pointing the other way to denote a charged + scalar antiparticle. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [anti charged scalar] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/ghost} + Draws a dotted line to denote a ghost. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [ghost] b}; +\end{codeexample} +\end{key} + + +\begin{key}{/tikzfeynman/fermion} + Draws a solid line with an arrow to denote a fermion. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [fermion] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/anti fermion} + Draws a solid line with an arrow pointing the other way to denote an antifermion. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [anti fermion] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/majorana} + Draws a solid line with two arrows pointing to the center to denote an + Majorana particle. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [majorana] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/anti majorana} + Draws a solid line with two arrows pointing to the ends to denote a Majorana + particle. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [anti majorana] b}; +\end{codeexample} +\end{key} + +\begin{key}{/tikzfeynman/gluon} + Draws a coiled line to denote a gluon. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [gluon] b}; +\end{codeexample} +\end{key} + +\begin{keylist}{% + /tikz/edge label=\meta{text}, + /tikz/edge label'=\meta{text}} + Places a label halfway along the edge with the given text. The primed key + switches which side of the edge the label is placed. +\end{keylist} + +\begin{key}{/tikzfeynman/insertion=\opt{\oarg{options}}\meta{distance}} + Places an insertion (for mass or momentum insertion) along an edge. The + distance specifies how far along the edge the insertion should be placed such + that |0| and |1| respectively correspond to the start and the end of the edge. + + Multiple insertions can be placed along a single edge by repeating the style + key. + + Through the \meta{options} argument, the insertion size and style can be + changed. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [insertion=0.33, insertion=0.67] b}; +\end{codeexample} + + \begin{key}{/tikzfeynman/insertion/size=\meta{distance} (initially 3pt)} + Specifies how big the insertion should be. The length of each edge starting + from the center will be \(\sqrt{2} \times \meta{distance}\). + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [insertion={[size=10pt]0.4}] b}; +\end{codeexample} + \end{key} + + \begin{key}{/tikzfeynman/insertion/style=\meta{distance} (initially \normalfont empty)} + Specifies additional styles to applying to the lines of the insertion. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] {a -- [insertion={[style=red]0.4}] b}; +\end{codeexample} + \end{key} +\end{key} + +\subsubsection{Momentum Keys} +\label{subsubsec:momentum_keys} + +\begin{keylist}{% + /tikzfeynman/momentum=\opt{\oarg{options}}\meta{text}, + /tikzfeynman/momentum'=\opt{\oarg{options}}\meta{text}, + /tikzfeynman/reversed momentum=\opt{\oarg{options}}\meta{text}, + /tikzfeynman/reversed momentum'=\opt{\oarg{options}}\meta{text}, + /tikzfeynman/rmomentum=\opt{\oarg{options}}\meta{text}, + /tikzfeynman/rmomentum'=\opt{\oarg{options}}\meta{text}} + Places a momentum arrow on the specified edge with label given by \meta{text}. + The primed (|'|) version place the momentum arrow on the other side of the + edge; that is, if the momentum arrow was on the right, it will be placed on + the left of the edge. The |reversed momentum| and |reversed momentum'| keys + are analogous to |momentum| and |momentum'| except that the momentum arrow + points in the opposite direction. Finally, the |rmomentum| and |rmomentum'| + are aliases of |reversed momentum| and |reversed momentum'|. + + Note that due to the way the arrow is drawn, it doesn't inherit styles of the + edge. As a result, they have to be re-specified through \meta{options}. + +\begin{codeexample}[] +\feynmandiagram [layered layout, horizontal=a to b] { + a -- [red, fermion, edge label'=\(ab\), momentum={[arrow style=red]\(p_{ab}\)}] b + -- [blue, photon, edge label'=\(bc\)] c + -- [green!40!black, scalar, momentum=\(p_{cd}\)] d, +}; +\end{codeexample} + +\begin{codeexample}[] +\feynmandiagram [layered layout, horizontal=b to c] { + a -- [photon, momentum=\(p\)] b + -- [fermion, half left, looseness=1.5, momentum=\(k\)] c + -- [fermion, half left, looseness=1.5, momentum=\(k-p\)] b, + c -- [photon, momentum=\(p\)] d, +}; +\end{codeexample} + +The \meta{options} allows for the following options to customize the appearance +of the momentum arrows. These can be either set globally with the usual +|\tikzfeynmanset|, or can be set on a individual basis through the +\meta{options} argument of the |momentum| key. In the latter case, only the +\meta{key} in |/tikzfeynman/momentum/|\meta{key} is required. + +\begin{key}{/tikzfeynman/momentum/label distance=\meta{distance} (initially 0pt)} + Set the separation between the text and the arrow. Note that the text is + still surrounded by an |inner sep=0.3333em| by default so the default + distance of |0pt| will not result in the momentum label touching the arrow. +\end{key} + +\begin{key}{/tikzfeynman/momentum/arrow distance=\meta{distance} (initially 3mm)} + Set the separation between the edge and the arrow. +\end{key} + +\begin{key}{/tikzfeynman/momentum/arrow shorten=\meta{distance} (initially 0.15)} + Specify the fraction of the total edge length by which the momentum arrow is + shortened at each end. +\end{key} + +\begin{key}{/tikzfeynman/momentum/label style=\meta{style} (initially \normalfont empty)} + Define styles to apply to the momentum label node. +\end{key} + +\begin{key}{/tikzfeynman/momentum/arrow style=\meta{style} (initially \normalfont empty)} + Define style to apply to the momentum arrow. +\end{key} +\end{keylist} + +\subsubsection{Modifier Keys} +\label{subsubsec:modifier_keys} + +Modifier keys serve only to slightly modify a small feature of the edge. + +\begin{keylist}{% + /tikzfeynman/half left, + /tikzfeynman/half right, + /tikzfeynman/quarter left, + /tikzfeynman/quarter right} + Modifies the edge so that it bends left or right in such a way that it + completes half a circle, or a quarter of a circle. + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + a -- [red, fermion, half left] b -- [blue, fermion, half left] a, +}; +\end{codeexample} + +\begin{codeexample}[] +\feynmandiagram [horizontal=a to c] { + a -- [red!0!blue, fermion, quarter left] b + -- [red!33!blue, fermion, quarter left] c + -- [red!66!blue, fermion, quarter left] d + -- [red!100!blue, fermion, quarter left] a, +}; +\end{codeexample} +\end{keylist} + +\begin{keylist}{% + /tikz/out=\meta{angle}, + /tikz/in=\meta{angle}} + Specifies the angle at which the edge leaves the first vertex in an edge and + the angle at which it enters the second vertex in an edge. +\end{keylist} + +\begin{key}{/tikz/relative=\opt{\meta{true or false}} (default true)} + If |relative| is set to |false|, the angle is relative to the paper whilst when + |relative| is set to |true|, the angle is relative to the straight line + joining the two vertices. +\end{key} + +\begin{key}{/tikz/looseness=\meta{number} (initially 1)} + As the name suggests, this specifies how `loose' or `tight' a curve is + connecting two vertices. +\end{key} + +\clearpage +\section{Examples} +\label{sec:examples} + +Below are a few diagrams which demonstrate how the package can be used in some +more practical examples.. + +\begin{description} +\item[Vertex Rule] \hspace*{0pt} \newline +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + a [particle=\(Z\)] -- [photon, momentum=\(p_{1}\)] b, + f1 [particle=\(\overline f\)] + -- [fermion, rmomentum'=\(p_{3}\)] b + -- [fermion, momentum=\(p_{2}\)] f2 [particle=\(f\)], +}; +\end{codeexample} + +\item[Tree Level Diagrams] \hspace*{0pt} \newline +\begin{codeexample}[] +\feynmandiagram [horizontal=a to b] { + i1 [particle=\(e^{-}\)] -- [fermion] a -- [fermion] i2 [particle=\(e^{+}\)], + a -- [photon, edge label=\(\gamma\)] b, + f1 [particle=\(\mu^{-}\)] -- [fermion] b -- [fermion] f2 [particle=\(\mu^{+}\)], +}; +\end{codeexample} + +\begin{codeexample}[] +\feynmandiagram [vertical'=a to b] { + i1 [particle=\(e^{-}\)] + -- [fermion] a + -- [fermion] f1 [particle=\(e^{-}\)], + a -- [photon, edge label=\(\gamma\)] b, + i2 [particle=\(e^{+}\)] + -- [anti fermion] b + -- [anti fermion] f2 [particle=\(e^{+}\)], +}; +\end{codeexample} + +\begin{codeexample}[] +\begin{tikzpicture} + \begin{feynman} + \diagram [vertical'=a to b] { + i1 [particle=\(e^{-}\)] + -- [fermion] a + -- [draw=none] f1 [particle=\(e^{+}\)], + a -- [photon, edge label'=\(p\)] b, + i2 [particle=\(e^{+}\)] + -- [anti fermion] b + -- [draw=none] f2 [particle=\(e^{-}\)], + }; + \diagram* { + (a) -- [fermion] (f2), + (b) -- [anti fermion] (f1), + }; + \end{feynman} +\end{tikzpicture} +\end{codeexample} + +\item[Loops] \hspace*{0pt} \newline +\begin{codeexample}[] +\feynmandiagram [layered layout, horizontal=b to c] { + a -- [photon, momentum=\(p\)] b + -- [fermion, half left, momentum=\(k\)] c + -- [fermion, half left, momentum=\(k-p\)] b, + c -- [photon, momentum=\(p\)] d, +}; +\end{codeexample} + +\begin{codeexample}[] +\feynmandiagram [layered layout, horizontal=a to b] [edges=gluon] { + {i1, i2} -- a -- [half left] b -- [half left] a, + b -- {f1, f2}, +}; +\end{codeexample} + +\newpage +\item[Box Diagrams] \hspace*{0pt} \newline +\begin{codeexample}[] +\feynmandiagram [layered layout, horizontal=a to b] { + % Draw the top and bottom lines + i1 [particle=\(d\)] + -- [fermion] a + -- [photon, edge label=\(W^{-}\)] b + -- [fermion] f1 [particle=\(\mu^{-}\)], + i2 [particle=\(\overline s\)] + -- [anti fermion] c + -- [photon, edge label'=\(W^{+}\)] d + -- [anti fermion] f2 [particle=\(\mu^{+}\)], + % Draw the two internal fermion lines + { [same layer] a -- [fermion, edge label'=\(q\)] c }, + { [same layer] b -- [anti fermion, edge label=\(\nu_{\mu}\)] d}, +}; +\end{codeexample} + +\newpage +\item[Meson decay and mixing] \hspace*{0pt} \newline +\begin{codeexample}[] +\begin{tikzpicture} + \begin{feynman} + \vertex (a1) {\(\overline b\)}; + \vertex[right=1.5cm of a1] (a2); + \vertex[right=1cm of a2] (a3); + \vertex[right=1.5cm of a3] (a4) {\(\overline u\)}; + + \vertex[below=2em of a1] (b1) {\(d\)}; + \vertex[below=2em of a4] (b2) {\(d\)}; + + %% See section 13.5 of PGF/TikZ manual + \vertex at ($(a2)!0.5!(a3)!0.5cm!90:(a3)$) (d); + %% Equivalent way to obtain (d): + % \vertex at ($(b2)!0.5!(b3) + (0, -0.5cm)$) (d); + \vertex[above=of a4] (c1) {\(u\)}; + \vertex[above=2em of c1] (c3) {\(\overline d\)}; + \vertex at ($(c1)!0.5!(c3) - (1cm, 0)$) (c2); + + \diagram* { + (a4) -- [fermion] (a3) -- [fermion] (a2) -- [fermion] (a1), + (b1) -- [fermion] (b2), + (c3) -- [fermion, out=180, in=45] (c2) -- [fermion, out=-45, in=180] (c1), + (a2) -- [boson, quarter left] (d) -- [boson, quarter left] (a3), + (d) -- [boson, bend left, edge label=\(W^{+}\)] (c2), + }; + + \draw [decoration={brace}, decorate] (b1.south west) -- (a1.north west) + node [pos=0.5, left] {\(B^{0}\)}; + \draw [decoration={brace}, decorate] (c3.north east) -- (c1.south east) + node [pos=0.5, right] {\(\pi^{+}\)}; + \draw [decoration={brace}, decorate] (a4.north east) -- (b2.south east) + node [pos=0.5, right] {\(\pi^{-}\)}; + \end{feynman} +\end{tikzpicture} +\end{codeexample} + +\newpage +\begin{codeexample}[] +\begin{tikzpicture} + \begin{feynman} + \vertex (a1) {\(\overline b\)}; + \vertex[right=1cm of a1] (a2); + \vertex[right=1cm of a2] (a3); + \vertex[right=1cm of a3] (a4) {\(b\)}; + \vertex[right=1cm of a4] (a5); + \vertex[right=2cm of a5] (a6) {\(u\)}; + + \vertex[below=2em of a1] (b1) {\(d\)}; + \vertex[right=1cm of b1] (b2); + \vertex[right=1cm of b2] (b3); + \vertex[right=1cm of b3] (b4) {\(\overline d\)}; + \vertex[below=2em of a6] (b5) {\(\overline d\)}; + + \vertex[above=of a6] (c1) {\(\overline u\)}; + \vertex[above=2em of c1] (c3) {\(d\)}; + \vertex at ($(c1)!0.5!(c3) - (1cm, 0)$) (c2); + + \diagram* { + {[edges=fermion] + (b1) -- (b2) -- (a2) -- (a1), + (b5) -- (b4) -- (b3) -- (a3) -- (a4) -- (a5) -- (a6), + }, + (a2) -- [boson, edge label=\(W\)] (a3), + (b2) -- [boson, edge label'=\(W\)] (b3), + + (c1) -- [fermion, out=180, in=-45] (c2) -- [fermion, out=45, in=180] (c3), + (a5) -- [boson, bend left, edge label=\(W^{-}\)] (c2), + }; + + \draw [decoration={brace}, decorate] (b1.south west) -- (a1.north west) + node [pos=0.5, left] {\(B^{0}\)}; + \draw [decoration={brace}, decorate] (c3.north east) -- (c1.south east) + node [pos=0.5, right] {\(\pi^{-}\)}; + \draw [decoration={brace}, decorate] (a6.north east) -- (b5.south east) + node [pos=0.5, right] {\(\pi^{+}\)}; + \end{feynman} +\end{tikzpicture} +\end{codeexample} + +\newpage +\begin{codeexample}[] +\begin{tikzpicture} + \begin{feynman} + \vertex (a1) {\(\overline b\)}; + \vertex[right=2cm of a1] (a2); + \vertex[right=0.5cm of a2] (a3); + \vertex[right=0.5cm of a3] (a4); + \vertex[right=2cm of a4] (a5) {\(\overline s\)}; + + \vertex[below=2cm of a1] (b1) {\(d\)}; + \vertex[below=2cm of a5] (b2) {\(d\)}; + + \vertex[below=1.5em of a5] (c1) {\(s\)}; + \vertex[above=1.5em of b2] (c3) {\(\overline s\)}; + \vertex at ($(c1)!0.5!(c3) - (1cm, 0)$) (c2); + + \diagram* { + {[edges=fermion] + (a5) -- (a4) -- (a3) -- (a2) -- (a1), + }, + (b1) -- [fermion] (b2), + (c3) -- [fermion, out=180, in=-60] (c2) -- [fermion, out=60, in=180] (c1), + (a3) -- [gluon, bend right] (c2), + (a4) -- [boson, out=90, in=90, looseness=2.0, edge label'=\(W^{+}\)] (a2) + }; + + \draw [decoration={brace}, decorate] (b1.south west) -- (a1.north west) + node [pos=0.5, left] {\(B^{0}\)}; + \draw [decoration={brace}, decorate] (a5.north east) -- (c1.south east) + node [pos=0.5, right] {\(\phi\)}; + \draw [decoration={brace}, decorate] (c3.north east) -- (b2.south east) + node [pos=0.5, right] {\(K^{0}\)}; + \end{feynman} +\end{tikzpicture} +\end{codeexample} + +\end{description} + +%% Index +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\clearpage +\printindex + +%% Bibliography (and acknowledgements) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\clearpage +\pagestyle{plain} + +\ifarxiv +\acknowledgements +\fi + +\printbibliography + +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/graphics/pgf/contrib/tikz-feynman/tikzfeynman.keys.code.tex b/graphics/pgf/contrib/tikz-feynman/tikzfeynman.keys.code.tex new file mode 100644 index 0000000000..14e5f9315e --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikzfeynman.keys.code.tex @@ -0,0 +1,815 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% TikZ-Feynman +% Feynman Diagrams with TikZ +% Copyright (C) 2015 Joshua Ellis +% +% +% This work may be distributed and/or modified under the conditions of the LaTeX +% Project Public License, either version 1.3 of this license or (at your option) +% any later version. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Joshua Ellis. +% +% This program is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +% FOR A PARTICULAR PURPOSE. See the LaTeX Project Public License for more +% details. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Shapes +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Crossed Circle +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\pgfdeclareshape{crossed circle} +{ + \inheritsavedanchors[from=circle] + \inheritanchorborder[from=circle] + \inheritanchor[from=circle]{north} + \inheritanchor[from=circle]{north west} + \inheritanchor[from=circle]{north east} + \inheritanchor[from=circle]{center} + \inheritanchor[from=circle]{west} + \inheritanchor[from=circle]{east} + \inheritanchor[from=circle]{mid} + \inheritanchor[from=circle]{mid west} + \inheritanchor[from=circle]{mid east} + \inheritanchor[from=circle]{base} + \inheritanchor[from=circle]{base west} + \inheritanchor[from=circle]{base east} + \inheritanchor[from=circle]{south} + \inheritanchor[from=circle]{south west} + \inheritanchor[from=circle]{south east} + + \inheritbackgroundpath[from=circle] + + \foregroundpath{ + % Compute south west + \centerpoint + \pgf@xc=\radius + \advance\pgf@x by-0.707107\pgf@xc + \advance\pgf@y by-0.707107\pgf@xc + \pgf@xa=\pgf@x \pgf@ya=\pgf@y % Store coordinates + % Compute north east point + \centerpoint + \pgf@xc=\radius + \advance\pgf@x by0.707107\pgf@xc + \advance\pgf@y by0.707107\pgf@xc + \pgf@xb=\pgf@x \pgf@yb=\pgf@y % Store coordinates + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}} + \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}} + \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}} + \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} + \pgfsetarrowsstart{} + \pgfsetarrowsend{} + } +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Decorations +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Complete Sines +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Complete sines replaces the path with a whole number of sine waves. +%% Thanks to http://tex.stackexchange.com/a/134516/26980 +\pgfdeclaredecoration{complete sines}{initial} +{ + %% Begin by computing the overall path length and find how many sine waves we + %% can fit in. Nothing happens beyond the computation. + \state{initial}[ + width=+0pt, + next state=move, + persistent precomputation={ + \def\tikzfeynman@cs@angle@step{30} + \def\tikzfeynman@cs@current@angle{0} + \pgfmathsetlengthmacro{\tikzfeynman@cs@points@per@step}{ + \pgfdecoratedinputsegmentlength + / int(\pgfdecoratedinputsegmentlength + / \pgfdecorationsegmentlength) + / 360 + * \tikzfeynman@cs@angle@step} + }, + ]{} + %% Move to the origin to the path + \state{move}[ + width=+\tikzfeynman@cs@points@per@step, + next state=draw + ]{ + \pgfpathmoveto{\pgfpointorigin} + } + %% Draw the sine wave itself. This computes the value every 20 degrees and draws straight edges. + \state{draw}[ + width=+\tikzfeynman@cs@points@per@step, + switch if less than=1.25*\tikzfeynman@cs@points@per@step to final, % <- bit of a hack + persistent postcomputation={ + \pgfmathparse{mod(\tikzfeynman@cs@current@angle+\tikzfeynman@cs@angle@step, 360)} + \let\tikzfeynman@cs@current@angle=\pgfmathresult% + }, + ]{ + \pgfmathparse{sin(\tikzfeynman@cs@current@angle) * \pgfmetadecorationsegmentamplitude / 2} + \tikz@decoratepathfalse + \pgfpathlineto{\pgfqpoint{0pt}{\pgfmathresult pt}}% + } + + \state{final}{ + \ifdim\pgfdecoratedremainingdistance>0pt\relax + \pgfpathlineto{\pgfpointdecoratedpathlast} + \fi + } +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Keys +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\tikzfeynmanset{ + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Hooks + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + execute at begin feynman/.code={}, + execute at end feynman/.code={}, + every feynman/.style={/tikzfeynman/every feynman@@/.append style={#1}}, + every feynman@@/.style={ + /tikzfeynman/.cd, + /tikzfeynman/medium, + }, + execute at begin feynman@@/.code={} %% Internal version + execute at end feynman@@/.code={}, %% Internal version + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Diagrams + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + every diagram/.style={/tikzfeynman/every diagram@@/.append style={#1}}, + every diagram@@/.style={ + /tikzfeynman/.cd, + .search also={/tikz/graphs, /tikz}, + nodes={ + /tikzfeynman/.cd, + /tikzfeynman/.search also={/tikz/graphs, /tikz}, + /tikzfeynman/every vertex@@, + /tikzfeynman/every vertex}, + edges={ + /tikzfeynman/.cd, + /tikzfeynman/.search also={/tikz/graphs, /tikz}, + /tikzfeynman/every edge@@, + /tikzfeynman/every edge}, + /tikzfeynman/medium, + }, + every inline/.style={/tikzfeynman/inline@@/.append style={#1}}, + every inline@@/.style={ + /tikzfeynman/small, + }, + inline/.style={ + /tikz/baseline={#1}, + /tikzfeynman/every inline@@, + }, + every small/.style={/tikzfeynman/small@@/.append style={#1}}, + every small@@/.style={ + /tikz/node distance=1cm, + /graph drawing/node distance=1.25cm, + /graph drawing/level distance=1cm, + /graph drawing/sibling distance=1.5cm, + /tikzfeynman/every dot@@/.append style={/tikz/minimum size=1mm}, + /tikzfeynman/every crossed dot@@/.append style={/tikz/minimum size=2mm}, + /tikzfeynman/every blob@@/.append style={/tikz/minimum size=0.5cm}, + /tikzfeynman/arrow size=1.2pt, + /tikzfeynman/insertion/size=2.5pt, + }, + small/.style={/tikzfeynman/every small@@}, + every medium/.style={/tikzfeynman/medium@@/.append style={#1}}, + every medium@@/.style={ + /tikz/node distance=1.5cm, + /graph drawing/node distance=1.9cm, + /graph drawing/level distance=1.5cm, + /graph drawing/sibling distance=2.25cm, + }, + medium/.style={/tikzfeynman/every medium@@}, + every large/.style={/tikzfeynman/large@@/.append style={#1}}, + every large@@/.style={ + /tikz/node distance=2cm, + /graph drawing/node distance=2.5cm, + /graph drawing/level distance=2cm, + /graph drawing/sibling distance=3cm, + /tikz/graphs/edges={thick}, + /tikzfeynman/every dot@@/.append style={/tikz/minimum size=2mm}, + /tikzfeynman/every crossed dot@@/.append style={/tikz/minimum size=4mm}, + /tikzfeynman/every blob@@/.append style={/tikz/minimum size=1cm}, + /tikzfeynman/arrow size=1.6pt, + /tikzfeynman/insertion/size=4pt, + }, + large/.style={/tikzfeynman/every large@@}, + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Vertices + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + every vertex@@/.style={ + /tikz/shape=coordinate, + }, + every vertex/.style={/tikzfeynman/every vertex@@/.append style={#1}}, + vertex/.style={ + /tikzfeynman/every vertex@@, + }, + every dot@@/.style={ + /tikz/shape=circle, + /tikz/graphs/as={}, + /tikz/draw, + /tikz/fill, + /tikz/inner sep=0pt, + /tikz/outer sep=0pt, + /tikz/minimum size=1.5mm, + }, + every dot/.style={/tikzfeynman/every dot@@/.append style={#1}}, + dot/.style={ + /tikzfeynman/every dot@@, + }, + every square dot@@/.style={ + /tikz/shape=rectangle, + }, + every square dot/.style={/tikzfeynman/every square dot@@/.append style={#1}}, + square dot/.style={ + /tikzfeynman/every dot@@, + /tikzfeynman/every square dot@@, + }, + every empty dot@@/.style={ + /tikz/fill=none, + }, + every empty dot/.style={/tikzfeynman/every empty dot@@/.append style={#1}}, + empty dot/.style={ + /tikzfeynman/every dot@@, + /tikzfeynman/every empty dot@@, + }, + every crossed dot@@/.style={ + /tikz/fill=none, + /tikz/shape=crossed circle, + /tikz/minimum size=3mm, + }, + every crossed dot/.style={/tikzfeynman/every crossed dot@@/.append style={#1}}, + crossed dot/.style={ + /tikzfeynman/every dot@@, + /tikzfeynman/every crossed dot@@, + }, + every blob@@/.style={ + /tikz/shape=circle, + /tikz/graphs/as={}, + /tikz/draw, + /tikz/fill=none, + /tikz/outer sep=0.5\pgflinewidth, + /tikz/inner sep=0pt, + /tikz/minimum size=0.75cm, + /tikz/pattern=north west lines, + }, + every blob/.style={/tikzfeynman/every blob@@/.append style={#1}}, + blob/.style={ + /tikzfeynman/every blob@@, + }, + every particle@@/.style={ + /tikz/shape=rectangle, + /tikz/draw=none, + /tikz/fill=none, + /tikz/inner sep=0.3333em, + /tikz/outer sep=0.5\pgflinewidth, + }, + every particle/.style={/tikzfeynman/every particle@@/.append style={#1}}, + particle/.style args={#1}{ + /tikzfeynman/every particle@@, + /tikz/graphs/as={#1}, + }, + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Edge styles + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Arrow Style + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + arrow size/.store in=\tikzfeynman@arrow@size, + arrow size=1.5pt, + with arrow/.style={ + /tikz/decoration={ + markings, + mark=at position #1 with { + \node[ + transform shape, + xshift=-0.5mm, + fill, + inner sep=\tikzfeynman@arrow@size, + draw=none, + isosceles triangle + ] { }; + }, + }, + /tikz/postaction={ + /tikz/decorate=true, + }, + }, + with reversed arrow/.style={ + /tikz/decoration={ + markings, + mark=at position #1 with { + \node[ + transform shape, + xshift=-0.5mm, + rotate=180, + fill, + inner sep=\tikzfeynman@arrow@size, + draw=none, + isosceles triangle + ] { }; + }, + }, + /tikz/postaction={ + /tikz/decorate=true, + }, + }, + %% Base Edge Styles + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + every edge@@/.style={}, + every edge/.style={/tikzfeynman/every edge@@/.append style={#1}}, + %% Specific Styles + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + every plain@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw + }, + }, + every plain/.style={/tikzfeynman/every plain@@/.append style={#1}}, + plain/.style={ + /tikzfeynman/every plain@@, + }, + every boson@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/decoration={ + complete sines, + amplitude=1mm, + segment length=2mm, + }, + /tikz/decorate=true, + }, + }, + every boson/.style={/tikzfeynman/every boson@@/.append style={#1}}, + boson/.style={ + /tikzfeynman/every boson@@, + }, + every charged boson@@/.style={ + /tikzfeynman/with arrow=0.5, + }, + every charged boson/.style={/tikzfeynman/every charged boson@@/.append style={#1}}, + charged boson/.style={ + /tikzfeynman/boson, + /tikzfeynman/every charged boson@@, + }, + every anti charged boson@@/.style={ + /tikzfeynman/with reversed arrow=0.5, + }, + every anti charged boson/.style={/tikzfeynman/every anti charged boson@@/.append style={#1}}, + anti charged boson/.style={ + /tikzfeynman/boson, + /tikzfeynman/every anti charged boson@@, + }, + every photon@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/decoration={ + complete sines, + amplitude=1mm, + segment length=2mm, + }, + /tikz/decorate=true, + }, + }, + every photon/.style={/tikzfeynman/every photon@@/.append style={#1}}, + photon/.style={ + /tikzfeynman/every photon@@, + }, + every scalar@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/dashed, + }, + }, + every scalar/.style={/tikzfeynman/every scalar@@/.append style={#1}}, + scalar/.style={ + /tikzfeynman/every scalar@@, + }, + every charged scalar@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikzfeynman/with arrow=0.5, + }, + }, + every charged scalar/.style={/tikzfeynman/every charged scalar@@/.append style={#1}}, + charged scalar/.style={ + /tikzfeynman/scalar, + /tikzfeynman/every charged scalar@@, + }, + every anti charged scalar@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikzfeynman/with reversed arrow=0.5, + }, + }, + every anti charged scalar/.style={/tikzfeynman/every anti charged scalar@@/.append style={#1}}, + anti charged scalar/.style={ + /tikzfeynman/scalar, + /tikzfeynman/every anti charged scalar@@, + }, + every ghost@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/dotted, + /tikz/thick, + }, + }, + every ghost/.style={/tikzfeynman/every ghost@@/.append style={#1}}, + ghost/.style={ + /tikzfeynman/every ghost@@, + }, + every fermion@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with arrow=0.5, + }, + }, + every fermion/.style={/tikzfeynman/every fermion@@/.append style={#1}}, + fermion/.style={ + /tikzfeynman/every fermion@@, + }, + every anti fermion@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with reversed arrow=0.5, + }, + }, + every anti fermion/.style={/tikzfeynman/every anti fermion@@/.append style={#1}}, + anti fermion/.style={ + /tikzfeynman/every anti fermion@@, + }, + every majorana@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with arrow=0.33, + /tikzfeynman/with reversed arrow=0.73, + }, + }, + every majorana/.style={/tikzfeynman/every majorana@@/.append style={#1}}, + majorana/.style={ + /tikzfeynman/every majorana@@, + }, + every anti majorana@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikzfeynman/with reversed arrow=0.33, + /tikzfeynman/with arrow=0.73, + }, + }, + every anti majorana/.style={/tikzfeynman/every anti majorana@@/.append style={#1}}, + anti majorana/.style={ + /tikzfeynman/every anti majorana@@, + }, + every gluon@@/.style={ + /tikz/draw=none, + /tikz/decoration={name=none}, + /tikz/postaction={ + /tikz/draw, + /tikz/decoration={ + coil, + aspect=0.75, + mirror, + segment length=1.5mm + }, + /tikz/decorate=true, + }, + }, + every gluon/.style={/tikzfeynman/every gluon@@/.append style={#1}}, + gluon/.style={ + /tikzfeynman/every gluon@@, + }, + %% Insertions + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + insertion/.search also={/tikzfeynman,/tikz}, + %% Parameters + insertion/size/.store in=\tikzfeynman@insertion@size, + insertion/size=3pt, + insertion/style/.store in=\tikzfeynman@insertion@style, + insertion/style={}, + %% Styles + insertion@@/.style args={[#1]#2}{ + /tikz/decoration={ + markings, + mark=at position #2 with { + \tikzfeynmanset{insertion/.cd,#1} + \draw [\tikzfeynman@insertion@style] (-\tikzfeynman@insertion@size, -\tikzfeynman@insertion@size) -- (\tikzfeynman@insertion@size, \tikzfeynman@insertion@size); + \draw [\tikzfeynman@insertion@style] (-\tikzfeynman@insertion@size, \tikzfeynman@insertion@size) -- (\tikzfeynman@insertion@size, -\tikzfeynman@insertion@size); + }, + }, + /tikz/postaction={ + /tikz/decorate=true, + }, + }, + insertion@@/.default={[]0.5}, + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Momentum arrows + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + momentum/.search also={/tikzfeynman,/tikz}, + %% Parameters + momentum/label distance/.store in=\tikzfeynman@momentum@label@distance, + momentum/label distance=0pt, + momentum/arrow distance/.store in=\tikzfeynman@momentum@arrow@distance, + momentum/arrow distance=3mm, + momentum/arrow shorten/.store in=\tikzfeynman@momentum@arrow@shorten, + momentum/arrow shorten=0.15, + momentum/label style/.store in=\tikzfeynman@momentum@label@style, + momentum/label style={}, + momentum/arrow style/.store in=\tikzfeynman@momentum@arrow@style, + momentum/arrow style={}, + %% Styles + momentum@@/.style args={[#1]#2}{ + /tikz/preaction={ + /tikz/decoration={ + show path construction, + moveto code={}, + lineto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@1)$) + node [pos=0.5, auto, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + curveto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentfirst) + .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) + .. (\tikzinputsegmentlast) + { \foreach \i in {1, ..., 50} { + coordinate [pos=\tikzfeynman@momentum@arrow@shorten + (1-2 * \tikzfeynman@momentum@arrow@shorten)*\i/50] (tf@m@\i) } }; + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@2)$) + foreach \i [count=\j from 3] in {2, ..., 24} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@\j)$) + } + -- ($(tf@m@25)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@26)$) + node [pos=0.5, auto, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@arrow@style] {#2} + foreach \i [count=\j from 27] in {26, ..., 49} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@\j)$) + } + -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@49)$); + }, + closepath code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@1)$) + node [pos=0.5, auto, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + }, + /tikz/decorate=true, + }, + }, + momentum'@@/.style args={[#1]#2}{ + /tikz/preaction={ + /tikz/decoration={ + show path construction, + moveto code={}, + lineto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@1)$) + node [pos=0.5, auto, swap, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + curveto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentfirst) + .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) + .. (\tikzinputsegmentlast) + { \foreach \i in {1, ..., 50} { + coordinate [pos=\tikzfeynman@momentum@arrow@shorten + (1-2 * \tikzfeynman@momentum@arrow@shorten)*\i/50] (tf@m@\i) } }; + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@2)$) + foreach \i [count=\j from 3] in {2, ..., 24} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@\j)$) + } + -- ($(tf@m@25)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@26)$) + node [pos=0.5, auto, swap, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@arrow@style] {#2} + foreach \i [count=\j from 27] in {26, ..., 49} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@\j)$) + } + -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@49)$); + }, + closepath code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@1)$) + node [pos=0.5, auto, swap, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + }, + /tikz/decorate=true, + }, + }, + reversed momentum@@/.style args={[#1]#2}{ + /tikz/preaction={ + /tikz/decoration={ + show path construction, + moveto code={}, + lineto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@1)$) + node [pos=0.5, auto, swap, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + curveto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentlast) + .. controls (\tikzinputsegmentsupportb) and (\tikzinputsegmentsupporta) + .. (\tikzinputsegmentfirst) + { \foreach \i in {1, ..., 50} { + coordinate [pos=\tikzfeynman@momentum@arrow@shorten + (1-2 * \tikzfeynman@momentum@arrow@shorten)*\i/50] (tf@m@\i) } }; + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@2)$) + foreach \i [count=\j from 3] in {2, ..., 24} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@\j)$) + } + -- ($(tf@m@25)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@26)$) + node [pos=0.5, auto, swap, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@arrow@style] {#2} + foreach \i [count=\j from 27] in {26, ..., 49} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@\j)$) + } + -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@49)$); + }, + closepath code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@1)$) + node [pos=0.5, auto, swap, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + }, + /tikz/decorate=true, + }, + }, + reversed momentum'@@/.style args={[#1]#2}{ + /tikz/preaction={ + /tikz/decoration={ + show path construction, + moveto code={}, + lineto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@1)$) + node [pos=0.5, + auto, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + curveto code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentlast) + .. controls (\tikzinputsegmentsupportb) and (\tikzinputsegmentsupporta) + .. (\tikzinputsegmentfirst) + { \foreach \i in {1, ..., 50} { + coordinate [pos=\tikzfeynman@momentum@arrow@shorten + (1-2 * \tikzfeynman@momentum@arrow@shorten)*\i/50] (tf@m@\i) } }; + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@2)$) + foreach \i [count=\j from 3] in {2, ..., 24} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@\j)$) + } + -- ($(tf@m@25)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@26)$) + node [pos=0.5, + auto, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@arrow@style] {#2} + foreach \i [count=\j from 27] in {26, ..., 49} { + -- ($(tf@m@\i)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@\j)$) + } + -- ($(tf@m@50)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@49)$); + }, + closepath code={ + \tikzfeynmanset{momentum/.cd,#1} + \path (\tikzinputsegmentlast) -- (\tikzinputsegmentfirst) + coordinate [pos=\tikzfeynman@momentum@arrow@shorten] (tf@m@1) + coordinate [pos=1 - \tikzfeynman@momentum@arrow@shorten] (tf@m@2); + \draw [-Stealth, \tikzfeynman@momentum@arrow@style] + ($(tf@m@1)!\tikzfeynman@momentum@arrow@distance!90:(tf@m@2)$) + -- ($(tf@m@2)!\tikzfeynman@momentum@arrow@distance!-90:(tf@m@1)$) + node [pos=0.5, auto, + outer sep=\tikzfeynman@momentum@label@distance, + \tikzfeynman@momentum@label@style] {#2}; + }, + }, + /tikz/decorate=true, + }, + }, + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + %% Modifiers + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + half left/.style={ + /tikz/bend left=90, + /tikz/looseness=1.5, + }, + half right/.style={ + /tikz/bend right=90, + /tikz/looseness=1.5, + }, + quarter left/.style={ + /tikz/bend left=45, + }, + quarter right/.style={ + /tikz/bend right=45, + }, +} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Graceful Failure of LuaTeX keys +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@luatex@required@path{ + \PackageWarning{tikz-feynman}{The key you tried to use '\pgfkeyscurrentpath/\pgfkeyscurrentname' requires LuaTeX. It will be ignored.} +} +\def\tikzfeynman@luatex@required@key{ + \PackageWarning{tikz-feynman}{The key you tried to use '\pgfkeyscurrentpath' requires LuaTeX. It will be ignored.} +} + +\ifluatex\else + \pgfkeys{ + /graph drawing/.unknown/.code=\tikzfeynman@luatex@required@path, + /tikz/graphs/.unknown/.code=\tikzfeynman@luatex@required@path, + /tikz/horizontal/.code=\tikzfeynman@luatex@required@key, + /tikz/horizontal'/.code=\tikzfeynman@luatex@required@key, + /tikz/vertical/.code=\tikzfeynman@luatex@required@key, + /tikz/vertical'/.code=\tikzfeynman@luatex@required@key, + /tikz/tree layout/.code=\tikzfeynman@luatex@required@key, + /tikz/spring layout/.code=\tikzfeynman@luatex@required@key, + /tikz/layered layout/.code=\tikzfeynman@luatex@required@key, + /tikz/spring electrical layout/.code=\tikzfeynman@luatex@required@key, + /tikz/electric charge/.code=\tikzfeynman@luatex@required@key, + } + % \tikzfeynmanset{ + % horizontal/.code={The key 'horizontal' requires LuaTeX. It will be ignored.}, + % } +\fi + +\endinput
\ No newline at end of file diff --git a/graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.0.lua b/graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.0.lua new file mode 100644 index 0000000000..54f0da080e --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.0.lua @@ -0,0 +1,1005 @@ +-- This patched version of the createVertex function simply ensures that the +-- path is never empty. This works fine for TikZ version 3.0.0. +-- +-- Later versions (should) have a more thorough patch by Till which is +-- incompatible with this override unfortunately. +-- +-- ############################################################################# +-- +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua,v 1.12 2013/12/20 14:44:46 tantau Exp $ + + + +--- +-- This class provides the interface between a display +-- layer (like \tikzname\ or a graph editor) and graph drawing +-- system. Another class, |InterfaceToAlgorithms|, binds the algorithm +-- layer (which are written in Lua) to the graph drawing system. +-- +-- The functions declared here are independent of the actual display +-- layer. Rather, the differences between the layers are encapsulated +-- by subclasses of the |Binding| class, see that class for +-- details. Thus, when a new display layer is written, the present +-- class is \emph{used}, but not \emph{modified}. Instead, only a new +-- binding is created and all display layer specific interaction is +-- put there. +-- +-- The job of this class is to provide convenient methods that can be +-- called by the display layer. For instance, it provides methods for +-- starting a graph drawing scope, managing the stack of such scope, +-- adding a node to a graph and so on. + +local InterfaceToDisplay = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local Scope = require "pgf.gd.interface.Scope" + +local Binding = require "pgf.gd.bindings.Binding" + +local Sublayouts = require "pgf.gd.control.Sublayouts" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Edge = require "pgf.gd.model.Edge" +local Collection = require "pgf.gd.model.Collection" + +local Storage = require "pgf.gd.lib.Storage" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Event = require "pgf.gd.lib.Event" + +local lib = require "pgf.gd.lib" + + +-- Forward declarations +local get_current_options_table +local render_collections +local push_on_option_stack +local vertex_created + +-- Local objects + +local phase_unique = {} -- a unique handle +local collections_unique = {} -- a unique handle +local option_cache = nil -- The option cache + + + + +--- +-- Initiliaze the binding. This function is called once by the display +-- layer at the very beginning. For instance, \tikzname\ does the +-- following call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF") +--\end{codeexample} +-- +-- Inside this call, many standard declarations will be executed, that +-- is, the declared binding will be used immediately. +-- +-- Subsequently, the |binding| field of the |InterfaceCore| can be used. +-- +-- @param class A subclass of |Binding|. + +function InterfaceToDisplay.bind(class) + assert (not InterfaceCore.binding, "binding already initialized") + + -- Create a new object + InterfaceCore.binding = setmetatable({}, class) + + -- Load these libraries, which contain many standard declarations: + require "pgf.gd.model.library" + require "pgf.gd.control.library" +end + + + + +--- +-- Start a graph drawing scope. Note that this is not the same as +-- starting a subgraph / sublayout, which are local to a graph drawing +-- scope: When a new graph drawing scope is started, it is pushed on +-- top of a stack of graph drawing scopes and all other ``open'' +-- scopes are no longer directly accessible. All method calls to an +-- |Interface...| object will refer to this newly created scope until +-- either a new scope is opened or until the current scope is closed +-- once more. +-- +-- Each graph drawing scope comes with a syntactic digraph that is +-- build using methods like |addVertex| or |addEdge|. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. + +function InterfaceToDisplay.beginGraphDrawingScope(height) + + -- Create a new scope table + local scope = Scope.new {} + + -- Setup syntactic digraph: + local g = scope.syntactic_digraph + + g.options = get_current_options_table(height) + g.syntactic_digraph = g + g.scope = scope + + -- Push scope: + InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope +end + + + +--- +-- Arranges the current graph using the specified algorithm and options. +-- +-- This function should be called after the graph drawing scope has +-- been opened and the syntactic digraph has been completely +-- specified. It will now start running the algorithm specified +-- through the |algorithm_phase| options. +-- +-- Internally, this function creates a coroutine that will run the current graph +-- drawing algorithm. Coroutines are needed since a graph drawing +-- algorithm may choose to create a new node. In this case, the +-- algorithm needs to be suspended and control must be returned back +-- to the display layer, so that the node can be typeset in order to +-- determine the precise size information. Once this is done, control +-- must be passed back to the exact point inside the algorithm where +-- the node was created. Clearly, all of these actions are exactly +-- what coroutines are for. +-- +-- @return Time it took to run the algorithm + +function InterfaceToDisplay.runGraphDrawingAlgorithm() + + -- Time things + local start = os.clock() + + -- Setup + local scope = InterfaceCore.topScope() + assert(not scope.coroutine, "coroutine already created for current gd scope") + + -- The actual drawing function + local function run () + if #scope.syntactic_digraph.vertices == 0 then + -- Nothing needs to be done + return + end + + LayoutPipeline.run(scope) + end + + scope.coroutine = coroutine.create(run) + + -- Run it: + InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- End timing: + local stop = os.clock() + + return stop - start +end + + +--- +-- Resume the graph drawing coroutine. +-- +-- This function is the work horse of the coroutine management. It +-- gets called whenever control passes back from the display layer to +-- the algorithm level. We resume the graph drawing coroutine so that the +-- algorithm can start/proceed. The tricky part is when the algorithm +-- yields, but is not done. In this case, the code needed for creating +-- a new node is passed back to the display layer through the binding, +-- which must then execute the code and then resuming the coroutine. +-- +function InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Asserts + assert(scope.coroutine, "coroutine not created for current gd scope") + + -- Run + local ok, text = coroutine.resume(scope.coroutine) + assert(ok, text) + if coroutine.status(scope.coroutine) ~= "dead" then + -- Ok, ask binding to continue + binding:resumeGraphDrawingCoroutine(text) + end +end + + + +--- Ends the current graph drawing scope. +-- +function InterfaceToDisplay.endGraphDrawingScope() + assert(#InterfaceCore.scopes > 0, "no gd scope open") + InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop +end + + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- node of the graph. The |name| must be a unique string identifying +-- the node. The newly created vertex will be added to the syntactic +-- digraph. The binding function |everyVertexCreation| will then be +-- called, allowing the binding to store information regarding the newly +-- created vertex. +-- +-- For each vertex an event will be created in the event +-- sequence. This event will have the kind |"node"| and its +-- |parameter| will be the vertex. +-- +-- @param name Name of the vertex. +-- +-- @param shape The shape of the vertex such as |"circle"| or +-- |"rectangle"|. This shape may help a graph drawing algorithm +-- figuring out how the node should be placed. +-- +-- @param path A |Path| object representing the vertex's path. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. +-- +-- @param binding_infos These options are passed to and are specific +-- to the current |Binding|. +-- +-- @param anchors A table of anchors (mapping anchor positions to +-- |Coordinates|). + + +function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors) + + -- The path should never be empty, so we create a trivial path in the provided + -- path is empty. This occurs with the ‘coordinate‘ shape for example. + if #path == 0 then + path:appendMoveto(0, 0) + path:appendClosepath() + end + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local v = scope.node_names[name] + assert (not v or not v.created_on_display_layer, "node already created") + + -- Create vertex + if not v then + v = Vertex.new { + name = name, + shape = shape, + kind = "node", + path = path, + options = get_current_options_table(height), + anchors = anchors, + } + + vertex_created(v,scope) + else + assert(v.kind == "subgraph node", "subgraph node expected") + v.shape = shape + v.path = path + v.anchors = anchors + end + + v.created_on_display_layer = true + + -- Call binding + binding.storage[v] = binding_infos + binding:everyVertexCreation(v) +end + + +-- This is a helper function +function vertex_created(v,scope) + + -- Create Event + local e = InterfaceToDisplay.createEvent ("node", v) + v.event = e + + -- Create name lookup + scope.node_names[v.name] = v + + -- Add vertex to graph + scope.syntactic_digraph:add {v} + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope that is a subgraph vertex. Such a vertex +-- ``surrounds'' the vertices of a subgraph. The special property of a +-- subgraph node opposed to a normal node is that it is created only +-- after the subgraph has been laid out. However, the difference to a +-- collection like |hyper| is that the node is availble immediately as +-- a normal node in the sense that you can connect edges to it. +-- +-- What happens internally is that subgraph nodes get ``registered'' +-- immediately both on the display level and on the algorithm level, +-- but the actual node is only created inside the layout pipeline +-- using a callback of the binding. The present function is used to +-- perform this registering. The node creation happens when the +-- innermost layout in which the subgraph node is declared has +-- finished. For each subgraph node, a collection is created that +-- contains all vertices (and edges) being part of the subgraph. For +-- this reason, this method is a |push...| method, since it pushes +-- something on the options stack. +-- +-- The |init| parameter will be used during the creation of the node, +-- see |Binding:createVertex| for details on the fields. Note that +-- |init.text| is often not displayed for such ``vast'' nodes as those +-- created for whole subgraphs, but a shape may use it nevertheless +-- (for instance, one might display this text at the top of the node +-- or, in case of a \textsc{uml} package, in a special box above the +-- actual node). +-- +-- The |init.generated_options| will be augmented by additional +-- key--value pairs when the vertex is created: +-- +-- \begin{itemize} +-- \item The key |subgraph point cloud| will have as its value a +-- string that is be a list of points (without +-- separating commas) like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in +-- this syntax. The list will contain all points inside the +-- subgraph. In particular, a bounding box around these points will +-- encompass all nodes and bend points of the subgraph. +-- The bounding box of this point cloud is guaranteed to be centered on +-- the origin. +-- \item The key |subgraph bounding box width| will have as its value +-- the width of a bounding box (in \TeX\ points, as a string with the +-- suffix |"pt"|). +-- \item The key |subgraph bounding box height| stores the height of a +-- bounding box. +-- \end{itemize} +-- +-- @param name The name of the node. +-- @param height Height of the options stack. Note that this method +-- pushes something (namely a collection) on the options stack. +-- @param info A table passed to |Binding:createVertex|, see that function. +-- +function InterfaceToDisplay.pushSubgraphVertex(name, height, info) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + -- Create vertex + local v = Vertex.new { + name = name, + kind = "subgraph node", + options = get_current_options_table(height-1) + } + + vertex_created(v,scope) + + -- Store info + info.generated_options = info.generated_options or {} + info.name = name + v.subgraph_info = info + + -- Create collection and link it to v + local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height) + v.subgraph_collection = entry.value + v.subgraph_collection.subgraph_node = v + + -- Find parent collection in options stack: + local collections = v.options.collections + for i=#collections,1,-1 do + if collections[i].kind == InterfaceCore.sublayout_kind then + v.subgraph_collection.parent_layout = collections[i] + break + end + end +end + + + +--- +-- Add options for an already existing vertex. +-- +-- This function allows you to add options to an already existing +-- vertex. The options that will be added are all options on the +-- current options stack; they will overwrite existing options of the +-- same name. For collections, the vertex stays in all collections it +-- used to, it is only added to all collections that are currently on +-- the options stack. +-- +-- @param name Name of the vertex. +-- @param height The option stack height. + +function InterfaceToDisplay.addToVertexOptions(name, height) + + -- Setup + local scope = InterfaceCore.topScope() + + -- Does vertex already exist? + local v = assert (scope.node_names[name], "node is missing, cannot add options") + + v.options = get_current_options_table(height, v.options) + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + + + +--- +-- Creates a new edge in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- edge that is created. Both the |from| vertex and the |to| vertex +-- must exist (have been created through |createVertex|) prior to your +-- being able to call this function. +-- +-- After the edge has been created, the binding layer's function +-- |everyEdgeCreation| will be called, allowing the binding layer to +-- store information about the edge. +-- +-- For each edge an event is created, whose kind is |"edge"| and whose +-- |parameter| is a two-element array whose first entry is the edge's +-- arc in the syntactic digraph and whose second entry is the position +-- of the edge in the arc's array of syntactic edges. +-- +-- @param tail Name of the node the edge begins at. +-- @param head Name of the node the edge ends at. +-- @param direction Direction of the edge (e.g. |--| for an undirected edge +-- or |->| for a directed edge from the first to the second +-- node). +-- @param height The option stack height, see for instance |createVertex|. +-- +-- @param binding_infos These options will be stored in the |storage| +-- of the vertex at the field index by the binding. + +function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local h = scope.node_names[head] + local t = scope.node_names[tail] + assert (h and t, "attempting to create edge between nodes that are not in the graph") + + -- Create Arc object + local arc = scope.syntactic_digraph:connect(t, h) + + -- Create Edge object + local edge = Edge.new { + head = h, + tail = t, + direction = direction, + options = get_current_options_table(height) + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + -- Create Event + local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) + edge.event = e + + -- Make part of collections + for _,c in ipairs(edge.options.collections) do + LookupTable.addOne(c.edges, edge) + end + + -- Call binding + binding.storage[edge] = binding_infos + binding:everyEdgeCreation(edge) + +end + + + + + +--- +-- Push an option to the stack of options. +-- +-- As a graph is parsed, a stack of ``current options'' +-- is created. To add something to this table, the display layers may +-- call the method |pushOption|. To pop something from this stack, +-- just set the |height| value during the next push to the position to +-- which you actually wish to push something; everything above and +-- including this position will be popped from the stack. +-- +-- When an option is pushed, several additional options may also be +-- pushed, namely whenever the option has a |use| field set. These +-- additional options may, in turn, also push new options. Because of +-- this, this function returns a new stack height, representing the +-- resulting stack height. +-- +-- In addition to this stack height, this function returns a Boolean +-- value indicating whether a ``main algorithm phase was set.'' This +-- happens whenever a key is executed (directly or indirectly through +-- the |use| field) that selects an algorithm for the ``main'' +-- algorithm phase. This information may help the caller to setup the +-- graph drawing scopes correctly. +-- +-- @param key A parameter (must be a string). +-- @param value A value (can be anything). If it is a string, it will +-- be converted to whatever the key expects. +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. +-- +-- @return A new stack height +-- @return A Boolean that is |true| iff the main algorithm phase was +-- set by the option or one option |use|d by it. +-- @return The newly created entry on the stack. If more entries are +-- created through the use of the |use| field, the original entry is +-- returned nevertheless. + + +function InterfaceToDisplay.pushOption(key, value, height) + assert(type(key) == "string", "illegal key") + + local key_record = assert(InterfaceCore.keys[key], "unknown key") + local main_phase_set = false + + if value == nil and key_record.default then + value = key_record.default + end + + -- Find out what kind of key we are pushing: + + if key_record.algorithm then + -- Push a phase + if type(InterfaceCore.algorithm_classes[key]) == "function" then + -- Call the constructor function + InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]() + end + + local algorithm = InterfaceCore.algorithm_classes[key] + + assert (algorithm, "algorithm class not found") + + push_on_option_stack(phase_unique, + { phase = key_record.phase, algorithm = algorithm }, + height) + + if key_record.phase == "main" then + main_phase_set = true + end + + elseif key_record.layer then + -- Push a collection + local stack = InterfaceCore.option_stack + local scope = InterfaceCore.topScope() + + -- Get the stack above "height": + local options = get_current_options_table(height-1) + + -- Create the collection event + local event = InterfaceToDisplay.createEvent ("collection", key) + + -- Create collection object: + local collection = Collection.new { kind = key, options = options, event = event } + + -- Store in collections table of current scope: + local collections = scope.collections[key] or {} + collections[#collections + 1] = collection + scope.collections[key] = collections + + -- Build collection tree + collection:registerAsChildOf(options.collections[#options.collections]) + + -- Push on stack + push_on_option_stack(collections_unique, collection, height) + + else + + -- A normal key + push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height) + + end + + local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack] + + -- Now, push use keys: + local use = key_record.use + if key_record.use then + local flag + for _,u in ipairs(InterfaceCore.keys[key].use) do + local use_k = u.key + local use_v = u.value + if type(use_k) == "function" then + use_k = use_k(value) + end + if type(use_v) == "function" then + use_v = use_v(value) + end + height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1) + main_phase_set = main_phase_set or flag + end + end + + return height, main_phase_set, newly_created +end + + +--- +-- Push a layout on the stack of options. As long as this layout is on +-- the stack, all vertices and edges will be part of this layout. For +-- details on layouts, please see |Sublayouts|. +-- +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. + +function InterfaceToDisplay.pushLayout(height) + InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height) +end + + + +--- +-- Creates an event and adds it to the event string of the current scope. +-- +-- @param kind Name/kind of the event. +-- @param parameters Parameters of the event. +-- +-- @return The newly pushed event +-- +function InterfaceToDisplay.createEvent(kind, param) + local scope = InterfaceCore.topScope() + local n = #scope.events + 1 + local e = Event.new { kind = kind, parameters = param, index = n } + scope.events[n] = e + + return e +end + + + +--- +-- This method allows you to query the table of all declared keys. It +-- contains them both as an array and also as a table index by the +-- keys's names. In particular, you can then iterate over it using +-- |ipairs| and you can check whether a key is defined by accessing +-- the table at the key's name. Each entry of the table is the +-- original table passed to |InterfaceToAlgorithms.declare|. +-- +-- @return A lookup table of all declared keys. + +function InterfaceToDisplay.getDeclaredKeys() + return InterfaceCore.keys +end + + + + +--- +-- Renders the graph. +-- +-- This function is called after the graph has been laid out by the +-- graph drawing algorithms. It will trigger a sequence of calls to +-- the binding layer that will, via callbacks, start rendering the +-- whole graph. +-- +-- In detail, this function calls: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderStart() +--render_vertices() +--render_edges() +--render_collections() +--binding:renderStop() +--\end{codeexample} +-- +-- Here, the |render_...| functions are local, internal functions that are, +-- nevertheless, documented here. +-- +-- @param name Returns the algorithm class that has been declared using +-- |declare| under the given name. + +function InterfaceToDisplay.renderGraph() + local scope = InterfaceCore.topScope() + local syntactic_digraph = scope.syntactic_digraph + + local binding = InterfaceCore.binding + + binding:renderStart() + render_vertices(syntactic_digraph.vertices) + render_edges(syntactic_digraph.arcs) + render_collections(scope.collections) + binding:renderStop() +end + + + + + +--- +-- Render the vertices after the graph drawing algorithm has +-- finished. This function is local and internal and included only for +-- documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will start +-- rendering the vertices by calling appropriate callbacks of the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +--\graph [... layout] { +-- a -- b -- c -- d; +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderVerticesStart() +--binding:renderVertex(vertex_a) +--binding:renderVertex(vertex_b) +--binding:renderVertex(vertex_c) +--binding:renderVertex(vertex_d) +--binding:renderVerticesStop() +--\end{codeexample} +-- +-- @param vertices An array of all vertices in the syntactic digraph. + +function render_vertices(vertices) + InterfaceCore.binding:renderVerticesStart() + for _,vertex in ipairs(vertices) do + InterfaceCore.binding:renderVertex(vertex) + end + InterfaceCore.binding:renderVerticesStop() +end + + +--- +-- Render the collections whose layer is not |0|. This local, internal +-- function is called to render the different collection kinds. +-- +-- Collection kinds rendered in the order provided by the |layer| +-- field passed to |declare| during the declaration of the colleciton +-- kind, see also |declare_collection|. If several collection kinds +-- have the same layer, they are rendered in lexicographical ordering +-- (to ensure that they are always rendered in the same order). +-- +-- Consider the following code: +--\begin{codeexample}[code only, tikz syntax=false] +--declare { key = "hyper", layer = 1 } +--\end{codeexample} +-- you can say on the \tikzname\ layer +--\begin{codeexample}[code only] +--\graph { +-- a, b, c, d; +-- { [hyper] a, b, c } +-- { [hyper] b, c, d } +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderCollectionStartKind("hyper", 1) +--binding:renderCollection(collection_containing_abc) +--binding:renderCollection(collection_containing_bcd) +--binding:renderCollectionStopKind("hyper", 1) +--\end{codeexample} +-- +-- @param collections The |collections| table of the current scope. + +function render_collections(collections) + local kinds = InterfaceCore.collection_kinds + local binding = InterfaceCore.binding + + for i=1,#kinds do + local kind = kinds[i].kind + local layer = kinds[i].layer + + if layer ~= 0 then + binding:renderCollectionStartKind(kind, layer) + for _,c in ipairs(collections[kind] or {}) do + binding:renderCollection(c) + end + binding:renderCollectionStopKind(kind, layer) + end + end +end + + +--- +-- Render the syntactic edges of a graph after the graph drawing +-- algorithm has finished. This function is local and internal and included only +-- for documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will first +-- rendering the vertices using |render_vertices|, followed by calling +-- this function, which in turn calls appropriate callbacks to the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +-- \graph [... layout] { +-- a -- b -- c -- d; +-- }; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local binding = InterfaceCore.binding +-- +-- binding:renderEdgesStart() +-- binding:renderEdge(edge_from_a_to_b) +-- binding:renderEdge(edge_from_b_to_c) +-- binding:renderEdge(edge_from_c_to_d) +-- binding:renderEdgesStop() +--\end{codeexample} +-- +-- @param arcs The array of arcs of the syntactic digraph. + +function render_edges(arcs) + InterfaceCore.binding:renderEdgesStart() + for _,a in ipairs(arcs) do + for _,e in ipairs (a.syntactic_edges) do + InterfaceCore.binding:renderEdge(e) + end + end + InterfaceCore.binding:renderEdgesStop() +end + + +local aliases = InterfaceCore.option_aliases +local option_initial = InterfaceCore.option_initial + +local option_metatable = { + __index = + function (t, key) + local k = aliases[key] + if k then + local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil + if v ~= nil then + return v + end + end + return option_initial[key] + end +} + + +--- +-- Get the current options table. +-- +-- An option table can be accessed like a normal table; however, there +-- is a global fallback for this table. If an index is not defined, +-- the value of this index in the global fallback table is used. (This +-- reduces the overall amount of option keys that need to be stored +-- with object.) +-- +-- (This function is local and internal and included only for documentation +-- purposes.) +-- +-- @param height The stack height for which the option table is +-- required. +-- @param table If non |nil|, the options will be added to this +-- table. +-- +-- @return The option table as described above. + +function get_current_options_table (height, table) + local stack = InterfaceCore.option_stack + assert (height >= 0 and height <= #stack, "height value out of bounds") + + if height == InterfaceCore.option_cache_height and not table then + return option_cache + else + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + -- Build options table + local cache + if not table then + cache = setmetatable( + { + algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases), + collections = {} + }, option_metatable) + else + cache = lib.copy(table) + cache.algorithm_phases = lib.copy(cache.algorithm_phases) + cache.collections = lib.copy(cache.collections) + end + + local algorithm_phases = cache.algorithm_phases + local collections = cache.collections + local keys = InterfaceCore.keys + + local function handle (k, v) + if k == phase_unique then + algorithm_phases[v.phase] = v.algorithm + elseif k == collections_unique then + LookupTable.addOne(collections, v) + else + cache[k] = v + end + end + + for _,s in ipairs(stack) do + handle (s.key, s.value) + end + + -- Cache it, if this was not added: + if not table then + InterfaceCore.option_cache_height = height + option_cache = cache + end + + return cache + end +end + + + +-- A helper function + +function push_on_option_stack(key, value, height) + local stack = InterfaceCore.option_stack + + assert (type(height) == "number" and height > 0 and height <= #stack + 1, + "height value out of bounds") + + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + stack[height] = { key = key, value = value } + InterfaceCore.option_cache_height = nil -- invalidate cache +end + + + +-- Done + +return InterfaceToDisplay diff --git a/graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.1.lua b/graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.1.lua new file mode 100644 index 0000000000..acecd80b99 --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikzfeynman.patch.3.0.1.lua @@ -0,0 +1,1037 @@ +-- This patched version of the createVertex function simply ensures that the +-- path is never empty. This works fine for TikZ version 3.0.1 and 3.0.1a. +-- +-- Later versions (should) have a more thorough patch by Till which is +-- incompatible with this override unfortunately. +-- +-- ############################################################################# +-- +-- Copyright 2012 by Till Tantau +-- +-- This file may be distributed an/or modified +-- +-- 1. under the LaTeX Project Public License and/or +-- 2. under the GNU Public License +-- +-- See the file doc/generic/pgf/licenses/LICENSE for more information + +-- @release $Header: /cvsroot/pgf/pgf/generic/pgf/graphdrawing/lua/pgf/gd/interface/InterfaceToDisplay.lua,v 1.14 2014/03/19 09:20:59 tantau Exp $ + +-- Print anything - including nested tables +function table_print (tt, indent, done) + done = done or {} + indent = indent or 0 + if type(tt) == "table" then + for key, value in pairs (tt) do + io.write(string.rep (" ", indent)) -- indent it + if type (value) == "table" and not done [value] then + done [value] = true + io.write(string.format("[%s] => table\n", tostring (key))); + io.write(string.rep (" ", indent+2)) -- indent it + io.write("(\n"); + table_print (value, indent + 4, done) + io.write(string.rep (" ", indent+2)) -- indent it + io.write(")\n"); + else + io.write(string.format("[%s] => %s\n", + tostring (key), tostring(value))) + end + end + else + io.write(tt .. "\n") + end +end + +--- +-- This class provides the interface between a display +-- layer (like \tikzname\ or a graph editor) and graph drawing +-- system. Another class, |InterfaceToAlgorithms|, binds the algorithm +-- layer (which are written in Lua) to the graph drawing system. +-- +-- The functions declared here are independent of the actual display +-- layer. Rather, the differences between the layers are encapsulated +-- by subclasses of the |Binding| class, see that class for +-- details. Thus, when a new display layer is written, the present +-- class is \emph{used}, but not \emph{modified}. Instead, only a new +-- binding is created and all display layer specific interaction is +-- put there. +-- +-- The job of this class is to provide convenient methods that can be +-- called by the display layer. For instance, it provides methods for +-- starting a graph drawing scope, managing the stack of such scope, +-- adding a node to a graph and so on. + +local InterfaceToDisplay = {} + +-- Namespace +require("pgf.gd.interface").InterfaceToDisplay = InterfaceToDisplay + + +-- Imports +local InterfaceCore = require "pgf.gd.interface.InterfaceCore" +local Scope = require "pgf.gd.interface.Scope" + +local Binding = require "pgf.gd.bindings.Binding" + +local Sublayouts = require "pgf.gd.control.Sublayouts" +local LayoutPipeline = require "pgf.gd.control.LayoutPipeline" + +local Digraph = require "pgf.gd.model.Digraph" +local Vertex = require "pgf.gd.model.Vertex" +local Edge = require "pgf.gd.model.Edge" +local Collection = require "pgf.gd.model.Collection" + +local Storage = require "pgf.gd.lib.Storage" +local LookupTable = require "pgf.gd.lib.LookupTable" +local Event = require "pgf.gd.lib.Event" + +local lib = require "pgf.gd.lib" + + +-- Forward declarations +local get_current_options_table +local render_collections +local push_on_option_stack +local vertex_created + +-- Local objects + +local phase_unique = {} -- a unique handle +local collections_unique = {} -- a unique handle +local option_cache = nil -- The option cache + + + + +--- +-- Initiliaze the binding. This function is called once by the display +-- layer at the very beginning. For instance, \tikzname\ does the +-- following call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--InterfaceToDisplay.bind(require "pgf.gd.bindings.BindingToPGF") +--\end{codeexample} +-- +-- Inside this call, many standard declarations will be executed, that +-- is, the declared binding will be used immediately. +-- +-- Subsequently, the |binding| field of the |InterfaceCore| can be used. +-- +-- @param class A subclass of |Binding|. + +function InterfaceToDisplay.bind(class) + assert (not InterfaceCore.binding, "binding already initialized") + + -- Create a new object + InterfaceCore.binding = setmetatable({}, class) + + -- Load these libraries, which contain many standard declarations: + require "pgf.gd.model.library" + require "pgf.gd.control.library" +end + + + + +--- +-- Start a graph drawing scope. Note that this is not the same as +-- starting a subgraph / sublayout, which are local to a graph drawing +-- scope: When a new graph drawing scope is started, it is pushed on +-- top of a stack of graph drawing scopes and all other ``open'' +-- scopes are no longer directly accessible. All method calls to an +-- |Interface...| object will refer to this newly created scope until +-- either a new scope is opened or until the current scope is closed +-- once more. +-- +-- Each graph drawing scope comes with a syntactic digraph that is +-- build using methods like |addVertex| or |addEdge|. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. + +function InterfaceToDisplay.beginGraphDrawingScope(height) + + -- Create a new scope table + local scope = Scope.new {} + + -- Setup syntactic digraph: + local g = scope.syntactic_digraph + + g.options = get_current_options_table(height) + g.syntactic_digraph = g + g.scope = scope + + -- Push scope: + InterfaceCore.scopes[#InterfaceCore.scopes + 1] = scope +end + + + +--- +-- Arranges the current graph using the specified algorithm and options. +-- +-- This function should be called after the graph drawing scope has +-- been opened and the syntactic digraph has been completely +-- specified. It will now start running the algorithm specified +-- through the |algorithm_phase| options. +-- +-- Internally, this function creates a coroutine that will run the current graph +-- drawing algorithm. Coroutines are needed since a graph drawing +-- algorithm may choose to create a new node. In this case, the +-- algorithm needs to be suspended and control must be returned back +-- to the display layer, so that the node can be typeset in order to +-- determine the precise size information. Once this is done, control +-- must be passed back to the exact point inside the algorithm where +-- the node was created. Clearly, all of these actions are exactly +-- what coroutines are for. +-- +-- @return Time it took to run the algorithm + +function InterfaceToDisplay.runGraphDrawingAlgorithm() + + -- Time things + local start = os.clock() + + -- Setup + local scope = InterfaceCore.topScope() + assert(not scope.coroutine, "coroutine already created for current gd scope") + + -- The actual drawing function + local function run () + if #scope.syntactic_digraph.vertices == 0 then + -- Nothing needs to be done + return + end + + LayoutPipeline.run(scope) + end + + scope.coroutine = coroutine.create(run) + + -- Run it: + InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- End timing: + local stop = os.clock() + + return stop - start +end + + +--- +-- Resume the graph drawing coroutine. +-- +-- This function is the work horse of the coroutine management. It +-- gets called whenever control passes back from the display layer to +-- the algorithm level. We resume the graph drawing coroutine so that the +-- algorithm can start/proceed. The tricky part is when the algorithm +-- yields, but is not done. In this case, the code needed for creating +-- a new node is passed back to the display layer through the binding, +-- which must then execute the code and then resuming the coroutine. +-- +function InterfaceToDisplay.resumeGraphDrawingCoroutine() + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Asserts + assert(scope.coroutine, "coroutine not created for current gd scope") + + -- Run + local ok, text = coroutine.resume(scope.coroutine) + assert(ok, text) + if coroutine.status(scope.coroutine) ~= "dead" then + -- Ok, ask binding to continue + binding:resumeGraphDrawingCoroutine(text) + end +end + + + +--- Ends the current graph drawing scope. +-- +function InterfaceToDisplay.endGraphDrawingScope() + assert(#InterfaceCore.scopes > 0, "no gd scope open") + InterfaceCore.scopes[#InterfaceCore.scopes] = nil -- pop +end + + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- node of the graph. The |name| must be a unique string identifying +-- the node. The newly created vertex will be added to the syntactic +-- digraph. The binding function |everyVertexCreation| will then be +-- called, allowing the binding to store information regarding the newly +-- created vertex. +-- +-- For each vertex an event will be created in the event +-- sequence. This event will have the kind |"node"| and its +-- |parameter| will be the vertex. +-- +-- @param name Name of the vertex. +-- +-- @param shape The shape of the vertex such as |"circle"| or +-- |"rectangle"|. This shape may help a graph drawing algorithm +-- figuring out how the node should be placed. +-- +-- @param path A |Path| object representing the vertex's path. +-- +-- @param height The to-be-used height of the options stack. All +-- options above this height will be popped prior to attacking the +-- options to the syntactic digraph. +-- +-- @param binding_infos These options are passed to and are specific +-- to the current |Binding|. +-- +-- @param anchors A table of anchors (mapping anchor positions to +-- |Coordinates|). + + +function InterfaceToDisplay.createVertex(name, shape, path, height, binding_infos, anchors) + + -- The path should never be empty, so we create a trivial path in the provided + -- path is empty. This occurs with the ‘coordinate‘ shape for example. + if #path == 0 then + path:appendMoveto(0, 0) + path:appendClosepath() + end + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local v = scope.node_names[name] + assert (not v or not v.created_on_display_layer, "node already created") + + -- Create vertex + if not v then + v = Vertex.new { + name = name, + shape = shape, + kind = "node", + path = path, + options = get_current_options_table(height), + anchors = anchors, + } + + vertex_created(v,scope) + else + assert(v.kind == "subgraph node", "subgraph node expected") + v.shape = shape + v.path = path + v.anchors = anchors + end + + v.created_on_display_layer = true + + -- Call binding + binding.storage[v] = binding_infos + binding:everyVertexCreation(v) +end + + +-- This is a helper function +function vertex_created(v,scope) + + -- Create Event + local e = InterfaceToDisplay.createEvent ("node", v) + v.event = e + + -- Create name lookup + scope.node_names[v.name] = v + + -- Add vertex to graph + scope.syntactic_digraph:add {v} + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + +--- +-- Creates a new vertex in the syntactic graph of the current graph +-- drawing scope that is a subgraph vertex. Such a vertex +-- ``surrounds'' the vertices of a subgraph. The special property of a +-- subgraph node opposed to a normal node is that it is created only +-- after the subgraph has been laid out. However, the difference to a +-- collection like |hyper| is that the node is availble immediately as +-- a normal node in the sense that you can connect edges to it. +-- +-- What happens internally is that subgraph nodes get ``registered'' +-- immediately both on the display level and on the algorithm level, +-- but the actual node is only created inside the layout pipeline +-- using a callback of the binding. The present function is used to +-- perform this registering. The node creation happens when the +-- innermost layout in which the subgraph node is declared has +-- finished. For each subgraph node, a collection is created that +-- contains all vertices (and edges) being part of the subgraph. For +-- this reason, this method is a |push...| method, since it pushes +-- something on the options stack. +-- +-- The |init| parameter will be used during the creation of the node, +-- see |Binding:createVertex| for details on the fields. Note that +-- |init.text| is often not displayed for such ``vast'' nodes as those +-- created for whole subgraphs, but a shape may use it nevertheless +-- (for instance, one might display this text at the top of the node +-- or, in case of a \textsc{uml} package, in a special box above the +-- actual node). +-- +-- The |init.generated_options| will be augmented by additional +-- key--value pairs when the vertex is created: +-- +-- \begin{itemize} +-- \item The key |subgraph point cloud| will have as its value a +-- string that is be a list of points (without +-- separating commas) like |"(10pt,20pt)(0pt,0pt)(30pt,40pt)"|, always in +-- this syntax. The list will contain all points inside the +-- subgraph. In particular, a bounding box around these points will +-- encompass all nodes and bend points of the subgraph. +-- The bounding box of this point cloud is guaranteed to be centered on +-- the origin. +-- \item The key |subgraph bounding box width| will have as its value +-- the width of a bounding box (in \TeX\ points, as a string with the +-- suffix |"pt"|). +-- \item The key |subgraph bounding box height| stores the height of a +-- bounding box. +-- \end{itemize} +-- +-- @param name The name of the node. +-- @param height Height of the options stack. Note that this method +-- pushes something (namely a collection) on the options stack. +-- @param info A table passed to |Binding:createVertex|, see that function. +-- +function InterfaceToDisplay.pushSubgraphVertex(name, height, info) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + assert (not scope.node_names[name], "node already created") + + -- Create vertex + local v = Vertex.new { + name = name, + kind = "subgraph node", + options = get_current_options_table(height-1) + } + + vertex_created(v,scope) + + -- Store info + info.generated_options = info.generated_options or {} + info.name = name + v.subgraph_info = info + + -- Create collection and link it to v + local _, _, entry = InterfaceToDisplay.pushOption(InterfaceCore.subgraph_node_kind, nil, height) + v.subgraph_collection = entry.value + v.subgraph_collection.subgraph_node = v + + -- Find parent collection in options stack: + local collections = v.options.collections + for i=#collections,1,-1 do + if collections[i].kind == InterfaceCore.sublayout_kind then + v.subgraph_collection.parent_layout = collections[i] + break + end + end +end + + + +--- +-- Add options for an already existing vertex. +-- +-- This function allows you to add options to an already existing +-- vertex. The options that will be added are all options on the +-- current options stack; they will overwrite existing options of the +-- same name. For collections, the vertex stays in all collections it +-- used to, it is only added to all collections that are currently on +-- the options stack. +-- +-- @param name Name of the vertex. +-- @param height The option stack height. + +function InterfaceToDisplay.addToVertexOptions(name, height) + + -- Setup + local scope = InterfaceCore.topScope() + + -- Does vertex already exist? + local v = assert (scope.node_names[name], "node is missing, cannot add options") + + v.options = get_current_options_table(height, v.options) + + -- Add to collections + for _,c in ipairs(v.options.collections) do + LookupTable.addOne(c.vertices, v) + end + +end + + + + + +--- +-- Creates a new edge in the syntactic graph of the current graph +-- drawing scope. The display layer should call this function for each +-- edge that is created. Both the |from| vertex and the |to| vertex +-- must exist (have been created through |createVertex|) prior to your +-- being able to call this function. +-- +-- After the edge has been created, the binding layer's function +-- |everyEdgeCreation| will be called, allowing the binding layer to +-- store information about the edge. +-- +-- For each edge an event is created, whose kind is |"edge"| and whose +-- |parameter| is a two-element array whose first entry is the edge's +-- arc in the syntactic digraph and whose second entry is the position +-- of the edge in the arc's array of syntactic edges. +-- +-- @param tail Name of the node the edge begins at. +-- @param head Name of the node the edge ends at. +-- @param direction Direction of the edge (e.g. |--| for an undirected edge +-- or |->| for a directed edge from the first to the second +-- node). +-- @param height The option stack height, see for instance |createVertex|. +-- +-- @param binding_infos These options will be stored in the |storage| +-- of the vertex at the field index by the binding. + +function InterfaceToDisplay.createEdge(tail, head, direction, height, binding_infos) + + -- Setup + local scope = InterfaceCore.topScope() + local binding = InterfaceCore.binding + + -- Does vertex already exist? + local h = scope.node_names[head] + local t = scope.node_names[tail] + assert (h and t, "attempting to create edge between nodes that are not in the graph") + + -- Create Arc object + local arc = scope.syntactic_digraph:connect(t, h) + + -- Create Edge object + local edge = Edge.new { + head = h, + tail = t, + direction = direction, + options = get_current_options_table(height) + } + + -- Add to arc + arc.syntactic_edges[#arc.syntactic_edges+1] = edge + + -- Create Event + local e = InterfaceToDisplay.createEvent ("edge", { arc, #arc.syntactic_edges }) + edge.event = e + + -- Make part of collections + for _,c in ipairs(edge.options.collections) do + LookupTable.addOne(c.edges, edge) + end + + -- Call binding + binding.storage[edge] = binding_infos + binding:everyEdgeCreation(edge) + +end + + + + + +--- +-- Push an option to the stack of options. +-- +-- As a graph is parsed, a stack of ``current options'' +-- is created. To add something to this table, the display layers may +-- call the method |pushOption|. To pop something from this stack, +-- just set the |height| value during the next push to the position to +-- which you actually wish to push something; everything above and +-- including this position will be popped from the stack. +-- +-- When an option is pushed, several additional options may also be +-- pushed, namely whenever the option has a |use| field set. These +-- additional options may, in turn, also push new options. Because of +-- this, this function returns a new stack height, representing the +-- resulting stack height. +-- +-- In addition to this stack height, this function returns a Boolean +-- value indicating whether a ``main algorithm phase was set.'' This +-- happens whenever a key is executed (directly or indirectly through +-- the |use| field) that selects an algorithm for the ``main'' +-- algorithm phase. This information may help the caller to setup the +-- graph drawing scopes correctly. +-- +-- @param key A parameter (must be a string). +-- @param value A value (can be anything). If it is a string, it will +-- be converted to whatever the key expects. +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. +-- +-- @return A new stack height +-- @return A Boolean that is |true| iff the main algorithm phase was +-- set by the option or one option |use|d by it. +-- @return The newly created entry on the stack. If more entries are +-- created through the use of the |use| field, the original entry is +-- returned nevertheless. + + +function InterfaceToDisplay.pushOption(key, value, height) + assert(type(key) == "string", "illegal key") + + local key_record = assert(InterfaceCore.keys[key], "unknown key") + local main_phase_set = false + + if value == nil and key_record.default then + value = key_record.default + end + + -- Find out what kind of key we are pushing: + + if key_record.algorithm then + -- Push a phase + if type(InterfaceCore.algorithm_classes[key]) == "function" then + -- Call the constructor function + InterfaceCore.algorithm_classes[key] = InterfaceCore.algorithm_classes[key]() + end + + local algorithm = InterfaceCore.algorithm_classes[key] + + assert (algorithm, "algorithm class not found") + + push_on_option_stack(phase_unique, + { phase = value or key_record.phase, algorithm = algorithm }, + height) + + if key_record.phase == "main" then + main_phase_set = true + end + + elseif key_record.layer then + -- Push a collection + local stack = InterfaceCore.option_stack + local scope = InterfaceCore.topScope() + + -- Get the stack above "height": + local options = get_current_options_table(height-1) + + -- Create the collection event + local event = InterfaceToDisplay.createEvent ("collection", key) + + -- Create collection object: + local collection = Collection.new { kind = key, options = options, event = event } + + -- Store in collections table of current scope: + local collections = scope.collections[key] or {} + collections[#collections + 1] = collection + scope.collections[key] = collections + + -- Build collection tree + collection:registerAsChildOf(options.collections[#options.collections]) + + -- Push on stack + push_on_option_stack(collections_unique, collection, height) + + else + + -- A normal key + push_on_option_stack(key, InterfaceCore.convert(value, InterfaceCore.keys[key].type), height) + + end + + local newly_created = InterfaceCore.option_stack[#InterfaceCore.option_stack] + + -- Now, push use keys: + local use = key_record.use + if key_record.use then + local flag + for _,u in ipairs(InterfaceCore.keys[key].use) do + local use_k = u.key + local use_v = u.value + if type(use_k) == "function" then + use_k = use_k(value) + end + if type(use_v) == "function" then + use_v = use_v(value) + end + height, flag = InterfaceToDisplay.pushOption(use_k, use_v, height+1) + main_phase_set = main_phase_set or flag + end + end + + return height, main_phase_set, newly_created +end + + +--- +-- Push a layout on the stack of options. As long as this layout is on +-- the stack, all vertices and edges will be part of this layout. For +-- details on layouts, please see |Sublayouts|. +-- +-- @param height A stack height at which to insert the key. Everything +-- above this height will be removed. + +function InterfaceToDisplay.pushLayout(height) + InterfaceToDisplay.pushOption(InterfaceCore.sublayout_kind, nil, height) +end + + + +--- +-- Creates an event and adds it to the event string of the current scope. +-- +-- @param kind Name/kind of the event. +-- @param parameters Parameters of the event. +-- +-- @return The newly pushed event +-- +function InterfaceToDisplay.createEvent(kind, param) + local scope = InterfaceCore.topScope() + local n = #scope.events + 1 + local e = Event.new { kind = kind, parameters = param, index = n } + scope.events[n] = e + + return e +end + + + +--- +-- This method allows you to query the table of all declared keys. It +-- contains them both as an array and also as a table index by the +-- keys's names. In particular, you can then iterate over it using +-- |ipairs| and you can check whether a key is defined by accessing +-- the table at the key's name. Each entry of the table is the +-- original table passed to |InterfaceToAlgorithms.declare|. +-- +-- @return A lookup table of all declared keys. + +function InterfaceToDisplay.getDeclaredKeys() + return InterfaceCore.keys +end + + + + +--- +-- Renders the graph. +-- +-- This function is called after the graph has been laid out by the +-- graph drawing algorithms. It will trigger a sequence of calls to +-- the binding layer that will, via callbacks, start rendering the +-- whole graph. +-- +-- In detail, this function calls: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderStart() +--render_vertices() +--render_edges() +--render_collections() +--binding:renderStop() +--\end{codeexample} +-- +-- Here, the |render_...| functions are local, internal functions that are, +-- nevertheless, documented here. +-- +-- @param name Returns the algorithm class that has been declared using +-- |declare| under the given name. + +function InterfaceToDisplay.renderGraph() + local scope = InterfaceCore.topScope() + local syntactic_digraph = scope.syntactic_digraph + + local binding = InterfaceCore.binding + + binding:renderStart() + render_vertices(syntactic_digraph.vertices) + render_edges(syntactic_digraph.arcs) + render_collections(scope.collections) + binding:renderStop() +end + + + + + +--- +-- Render the vertices after the graph drawing algorithm has +-- finished. This function is local and internal and included only for +-- documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will start +-- rendering the vertices by calling appropriate callbacks of the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +--\graph [... layout] { +-- a -- b -- c -- d; +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderVerticesStart() +--binding:renderVertex(vertex_a) +--binding:renderVertex(vertex_b) +--binding:renderVertex(vertex_c) +--binding:renderVertex(vertex_d) +--binding:renderVerticesStop() +--\end{codeexample} +-- +-- @param vertices An array of all vertices in the syntactic digraph. + +function render_vertices(vertices) + InterfaceCore.binding:renderVerticesStart() + for _,vertex in ipairs(vertices) do + InterfaceCore.binding:renderVertex(vertex) + end + InterfaceCore.binding:renderVerticesStop() +end + + +--- +-- Render the collections whose layer is not |0|. This local, internal +-- function is called to render the different collection kinds. +-- +-- Collection kinds rendered in the order provided by the |layer| +-- field passed to |declare| during the declaration of the colleciton +-- kind, see also |declare_collection|. If several collection kinds +-- have the same layer, they are rendered in lexicographical ordering +-- (to ensure that they are always rendered in the same order). +-- +-- Consider the following code: +--\begin{codeexample}[code only, tikz syntax=false] +--declare { key = "hyper", layer = 1 } +--\end{codeexample} +-- you can say on the \tikzname\ layer +--\begin{codeexample}[code only] +--\graph { +-- a, b, c, d; +-- { [hyper] a, b, c } +-- { [hyper] b, c, d } +--}; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +--local binding = InterfaceCore.binding +-- +--binding:renderCollectionStartKind("hyper", 1) +--binding:renderCollection(collection_containing_abc) +--binding:renderCollection(collection_containing_bcd) +--binding:renderCollectionStopKind("hyper", 1) +--\end{codeexample} +-- +-- @param collections The |collections| table of the current scope. + +function render_collections(collections) + local kinds = InterfaceCore.collection_kinds + local binding = InterfaceCore.binding + + for i=1,#kinds do + local kind = kinds[i].kind + local layer = kinds[i].layer + + if layer ~= 0 then + binding:renderCollectionStartKind(kind, layer) + for _,c in ipairs(collections[kind] or {}) do + binding:renderCollection(c) + end + binding:renderCollectionStopKind(kind, layer) + end + end +end + + +--- +-- Render the syntactic edges of a graph after the graph drawing +-- algorithm has finished. This function is local and internal and included only +-- for documenting the call graph. +-- +-- When the graph drawing algorithm is done, the interface will first +-- rendering the vertices using |render_vertices|, followed by calling +-- this function, which in turn calls appropriate callbacks to the +-- binding layer. +-- +-- Consider the following code: +--\begin{codeexample}[code only] +-- \graph [... layout] { +-- a -- b -- c -- d; +-- }; +--\end{codeexample} +-- +-- In this case, after the graph drawing algorithm has run, the +-- present function will call: +-- +--\begin{codeexample}[code only, tikz syntax=false] +-- local binding = InterfaceCore.binding +-- +-- binding:renderEdgesStart() +-- binding:renderEdge(edge_from_a_to_b) +-- binding:renderEdge(edge_from_b_to_c) +-- binding:renderEdge(edge_from_c_to_d) +-- binding:renderEdgesStop() +--\end{codeexample} +-- +-- @param arcs The array of arcs of the syntactic digraph. + +function render_edges(arcs) + InterfaceCore.binding:renderEdgesStart() + for _,a in ipairs(arcs) do + for _,e in ipairs (a.syntactic_edges) do + InterfaceCore.binding:renderEdge(e) + end + end + InterfaceCore.binding:renderEdgesStop() +end + + +local aliases = InterfaceCore.option_aliases +local option_initial = InterfaceCore.option_initial + +local option_metatable = { + __index = + function (t, key) + local k = aliases[key] + if k then + local v = (type(k) == "string" and t[k]) or (type(k) == "function" and k(t)) or nil + if v ~= nil then + return v + end + end + return option_initial[key] + end +} + + +--- +-- Get the current options table. +-- +-- An option table can be accessed like a normal table; however, there +-- is a global fallback for this table. If an index is not defined, +-- the value of this index in the global fallback table is used. (This +-- reduces the overall amount of option keys that need to be stored +-- with object.) +-- +-- (This function is local and internal and included only for documentation +-- purposes.) +-- +-- @param height The stack height for which the option table is +-- required. +-- @param table If non |nil|, the options will be added to this +-- table. +-- +-- @return The option table as described above. + +function get_current_options_table (height, table) + local stack = InterfaceCore.option_stack + assert (height >= 0 and height <= #stack, "height value out of bounds") + + if height == InterfaceCore.option_cache_height and not table then + return option_cache + else + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + -- Build options table + local cache + if not table then + cache = setmetatable( + { + algorithm_phases = setmetatable({}, InterfaceCore.option_initial.algorithm_phases), + collections = {} + }, option_metatable) + else + cache = lib.copy(table) + cache.algorithm_phases = lib.copy(cache.algorithm_phases) + cache.collections = lib.copy(cache.collections) + end + + local algorithm_phases = cache.algorithm_phases + local collections = cache.collections + local keys = InterfaceCore.keys + + local function handle (k, v) + if k == phase_unique then + algorithm_phases[v.phase] = v.algorithm + local phase_stack = v.phase .. " stack" + local t = rawget(algorithm_phases, phase_stack) + if not t then + t = algorithm_phases[phase_stack] + assert(type(t) == "table", "unknown phase") + t = lib.copy(t) + algorithm_phases[phase_stack] = t + end + t[#t + 1] = v.algorithm + elseif k == collections_unique then + LookupTable.addOne(collections, v) + else + cache[k] = v + end + end + + for _,s in ipairs(stack) do + handle (s.key, s.value) + end + + -- Cache it, if this was not added: + if not table then + InterfaceCore.option_cache_height = height + option_cache = cache + end + + return cache + end +end + + + +-- A helper function + +function push_on_option_stack(key, value, height) + local stack = InterfaceCore.option_stack + + assert (type(height) == "number" and height > 0 and height <= #stack + 1, + "height value out of bounds") + + -- Clear superfluous part of stack + for i=#stack,height+1,-1 do + stack[i] = nil + end + + stack[height] = { key = key, value = value } + InterfaceCore.option_cache_height = nil -- invalidate cache +end + + + +-- Done + +return InterfaceToDisplay diff --git a/graphics/pgf/contrib/tikz-feynman/tikzlibraryfeynman.code.tex b/graphics/pgf/contrib/tikz-feynman/tikzlibraryfeynman.code.tex new file mode 100644 index 0000000000..76ca76e5ea --- /dev/null +++ b/graphics/pgf/contrib/tikz-feynman/tikzlibraryfeynman.code.tex @@ -0,0 +1,336 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% TikZ-Feynman +% Feynman Diagrams with TikZ +% Copyright (C) 2015 Joshua Ellis +% +% +% This work may be distributed and/or modified under the conditions of the LaTeX +% Project Public License, either version 1.3 of this license or (at your option) +% any later version. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Joshua Ellis. +% +% This program is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +% FOR A PARTICULAR PURPOSE. See the LaTeX Project Public License for more +% details. +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Pre-requisites +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\usetikzlibrary{ + arrows.meta, + calc, + decorations, + decorations.markings, + decorations.pathmorphing, + decorations.pathreplacing, + graphs, + patterns, + positioning, + shapes.geometric, +} +\ifluatex + \usetikzlibrary{ + graphdrawing + } + \usegdlibrary{ + circular, + force, + layered, + trees + } +\fi + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Function definitions +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Miscellaneous functions +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@empty{} + +%% Key Manager +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Setup the tikz-feynman key family +\pgfkeys{ + /tikzfeynman/.is family, + /tikzfeynman/.search also={/tikz}, +} + +%% |\tikzfeynmanset| allows keys that belong with tikz-feynman to be easily set. +\def\tikzfeynmanset{\pgfqkeys{/tikzfeynman}} + +%% Luatex Waring +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Check if we are using luatex +\newif\iftikzfeynman@warn@luatex% +\tikzfeynmanset{ + warn luatex/.is if=tikzfeynman@warn@luatex, + warn luatex=true, +} + +\AtBeginDocument{ + \ifluatex\else + \iftikzfeynman@warn@luatex + \PackageWarning{tikz-feynman}{LuaTeX is required if you wish to have vertices automatically placed. You can disable this warning by setting /tikzfeynman/warn luatex=false} + \fi + \fi +} + +%% Version check +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Check which version is expected and which is installed +\def\tikzfeynman@compat@parse#1.#2.#3\pgfeov{ + \edef\tikzfeynman@compat@major{#1} + \edef\tikzfeynman@compat@minor{#2} + \edef\tikzfeynman@compat@patch{#3} + \edef\tikzfeynman@compat{#1.#2.#3} +} +\let\tikzfeynman@compat=\tikzfeynman@empty +\pgfkeyslet{/tikzfeynman/compat/.@cmd}{\tikzfeynman@compat@parse} +\ProcessPgfPackageOptions{/tikzfeynman} + +\AtBeginDocument{ + \ifx\tikzfeynman@version\tikzfeynman@compat\else + \ifx\tikzfeynman@compat\tikzfeynman@empty + \PackageWarning{tikz-feynman}{Consider loading TikZ-Feynman with \string\usepackage[compat=\tikzfeynman@version]{tikz-feynman} so that you can be warned if TikZ-Feynman changes.} + \else + \ifx\tikzfeynman@compat@major\tikzfeynman@version@major + \ifx\tikzfeynman@compat@minor\tikzfeynman@version@minor + \ifx\tikzfeynman@compat@patch\tikzfeynman@version@patch\else + \PackageInfo{tikz-feynman}{The preamble requested version \tikzfeynman@compat, but the system version is \tikzfeynman@version. This should cause no issue.} + \fi + \else + \PackageWarning{tikz-feynman}{The preamble requested version \tikzfeynman@compat, but the system version is \tikzfeynman@version. This may change some diagrams.} + \fi + \else + \PackageError{tikz-feynman}{The preamble requested version \tikzfeynman@compat, but the system version is \tikzfeynman@version. They are most likely incompatible. Please download the appropriate version from jpellis.me/projects/tikz-feynman.} + \fi + \fi + \fi +} + +%% Override Lua code if necessary +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@apply@patch#1{ + \directlua{require("tikzfeynman.patch.#1.lua")} +} + +%% Version 3.0.0, 3.0.1 and 3.0.1a need to be patched. +\ifluatex + \def\tikzfeynman@temp{3.0.0} + \ifx\pgfversion\tikzfeynman@temp + \tikzfeynman@apply@patch{3.0.0} + \else + \def\tikzfeynman@temp{3.0.1} + \ifx\pgfversion\tikzfeynman@temp + \tikzfeynman@apply@patch{3.0.1} + \else + \def\tikzfeynman@temp{3.0.1a} + \ifx\pgfversion\tikzfeynman@temp + \tikzfeynman@apply@patch{3.0.1} + \fi + \fi + \fi +\fi + +%% Feynman Environment +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%% Provide `\begin{feynman} ... \end{feynman}` within TikZ pictures. +\tikzaddtikzonlycommandshortcutlet\feynman\tikzfeynman@environment@feynman +\tikzaddtikzonlycommandshortcutlet\endfeynman\endtikzfeynman@environment@feynman + +%% \begin{feynman}...\end{feynman} +\def\tikzfeynman@environment@feynman{% + \pgfutil@ifnextchar[{\tikzfeynman@environment@feynman@opt} + {\tikzfeynman@environment@feynman@opt[]}} + +\def\tikzfeynman@environment@feynman@opt[#1]{% + \begingroup + %% Local overrides + \let\tikz@@scan@fig=\tikzfeynman@scan@fig + \let\tikzfeynman@orig@graph=\graph + %% Local commands + \let\vertex=\tikzfeynman@commands@vertex + \let\diagram=\tikzfeynman@commands@diagram + \let\graph=\tikzfeynman@commands@graph + %% Opening hooks + \scope + \tikz@lib@ignore@sizetrue + \tikzfeynman@tikz@search@tikzfeynman + \pgfkeys{/tikzfeynman/every feynman@@,#1} + \pgfkeysvalueof{/tikzfeynman/execute at begin feynman@@}% + \pgfkeysvalueof{/tikzfeynman/execute at begin feynman}% +} + +\def\endtikzfeynman@environment@feynman{% + %% Closing hooks + \pgfkeysvalueof{/tikzfeynman/execute at end feynman}% + \pgfkeysvalueof{/tikzfeynman/execute at end feynman@@}% + \endscope + \endgroup +} + +%% \feynmandiagram +\def\feynmandiagram{% + \pgfutil@ifnextchar[{\feynmandiagram@opt} + {\feynmandiagram@opt[]}} +\def\feynmandiagram@opt[#1]{% + \pgfutil@ifnextchar[{\feynmandiagram@opt@opt[#1]} + {\feynmandiagram@opt@opt[#1][#1]}} +\def\feynmandiagram@opt@opt[#1][#2]{% + \tikz [/tikzfeynman/.cd,#1] + \graph [/tikzfeynman/.cd,/tikzfeynman/every diagram@@,/tikz/graphs/spring layout,#2]} + +%% Allow empty nodes +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\newif\iftikzfeynmanallowemptynode +\newif\iftikzfeynmanvertex +\def\tikzfeynman@scan@fig{% + \pgfutil@ifnextchar a{\tikz@fig@scan@at} + {\pgfutil@ifnextchar({\tikz@fig@scan@name} + {\pgfutil@ifnextchar[{\tikz@fig@scan@options}% + {\pgfutil@ifnextchar\bgroup{\tikz@fig@main}% + {\iftikzfeynmanvertex% + \tikzset{/tikzfeynman/every vertex@@}% + \iftikzfeynmanallowemptynode% + \else% + \tikzset{/tikzfeynman/particle}% + \fi% + \fi% + \tikz@fig@main{}}}}}}%}} + +%% Include /tikzfeynman in the search path +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@tikz@search@tikzfeynman{% + \pgfkeys{/tikz/.unknown/.code=% + \let\tikz@key\pgfkeyscurrentname% + %% Is it a tikzfeynman key? + \pgfkeys{/tikzfeynman/\tikz@key/.try={##1}}% + \ifpgfkeyssuccess% + \else% + %% Is it a pgf key? + \pgfkeys{/pgf/\tikz@key/.try={##1}}% + \ifpgfkeyssuccess% + \else% + \expandafter\pgfutil@in@\expandafter!\expandafter{\tikz@key}% + \ifpgfutil@in@% + %% this is a color! + \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}% + \edef\tikz@textcolor{\tikz@key}% + \else% + \pgfutil@doifcolorelse{\tikz@key} + {% + \expandafter\tikz@addoption\expandafter{\expandafter\tikz@compat@color@set\expandafter{\tikz@key}}% + \edef\tikz@textcolor{\tikz@key}% + }% + {% + %% Ok, second chance: This might be an arrow specification: + \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key}% + \ifpgfutil@in@% + %% Ah, an arrow spec! + \expandafter\tikz@processarrows\expandafter{\tikz@key}% + \else% + %% Ok, third chance: A shape! + \expandafter\ifx\csname pgf@sh@s@\tikz@key\endcsname\relax% + \pgfkeys{/errors/unknown key/.expand + once=\expandafter{\expandafter/\expandafter t\expandafter + i\expandafter k\expandafter z\expandafter/\tikz@key}{##1}}% + \else% + \edef\tikz@shape{\tikz@key}% + \fi% + \fi% + }% + \fi% + \fi% + \fi% + } +} + + +%% Vertex +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Adapted from |\coordinate| code +\def\tikzfeynman@commands@vertex{ + \path \pgfextra{\tikzfeynmanallowemptynodetrue} + \pgfextra{\tikzfeynmanvertextrue} + node} + +%% Diagram +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@commands@diagram{\@ifstar + \tikzfeynman@commands@diagram@star% + \tikzfeynman@commands@diagram@nostar} + +\def\tikzfeynman@commands@diagram@nostar{% + \pgfutil@ifnextchar[{\tikzfeynman@commands@diagram@nostar@opt} + {\tikzfeynman@commands@diagram@nostar@opt[]}} +\def\tikzfeynman@commands@diagram@nostar@opt[#1]{% + \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@,/tikz/graphs/spring layout,#1]} + +\def\tikzfeynman@commands@diagram@star{% + \pgfutil@ifnextchar[{\tikzfeynman@commands@diagram@star@opt} + {\tikzfeynman@commands@diagram@star@opt[]}} +\def\tikzfeynman@commands@diagram@star@opt[#1]{% + \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@,#1]} + +%% Graph +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@commands@graph{% + \pgfutil@ifnextchar[{\tikzfeynman@commands@graph@opt} + {\tikzfeynman@commands@graph@opt[]}} +\def\tikzfeynman@commands@graph@opt[#1]{% + \PackageWarning{tikz-feynman}{It is not recommended to use \string\graph. Use \string\diagram\space or \string\diagram* instead.} + \tikzfeynman@orig@graph [/tikzfeynman/every diagram@@,#1]} + +%% Optional argument in style key +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@key@opt#1[#2]#3\pgfeov{% + \tikzfeynmanset{#1={[#2]#3}}} + +%% Insertion +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@insertion{% + \pgfutil@ifnextchar[{\tikzfeynman@key@opt{insertion@@}} + {\tikzfeynman@key@opt{insertion@@}[]}} +\pgfkeyslet{/tikzfeynman/insertion/.@cmd}{\tikzfeynman@insertion} + +%% Momentum +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\def\tikzfeynman@momentum@std{% + \pgfutil@ifnextchar[{\tikzfeynman@key@opt{momentum@@}} + {\tikzfeynman@key@opt{momentum@@}[]}} +\pgfkeyslet{/tikzfeynman/momentum/.@cmd}{\tikzfeynman@momentum@std} + +\def\tikzfeynman@momentum@stdp{% + \pgfutil@ifnextchar[{\tikzfeynman@key@opt{momentum'@@}} + {\tikzfeynman@key@opt{momentum'@@}[]}} +\pgfkeyslet{/tikzfeynman/momentum'/.@cmd}{\tikzfeynman@momentum@stdp} + +\def\tikzfeynman@momentum@stdr{% + \pgfutil@ifnextchar[{\tikzfeynman@key@opt{reversed momentum@@}} + {\tikzfeynman@key@opt{reversed momentum@@}[]}} +\pgfkeyslet{/tikzfeynman/reversed momentum/.@cmd}{\tikzfeynman@momentum@stdr} +\pgfkeyslet{/tikzfeynman/rmomentum/.@cmd}{\tikzfeynman@momentum@stdr} + +\def\tikzfeynman@momentum@stdrp{% + \pgfutil@ifnextchar[{\tikzfeynman@key@opt{reversed momentum'@@}} + {\tikzfeynman@key@opt{reversed momentum'@@}[]}} +\pgfkeyslet{/tikzfeynman/reversed momentum'/.@cmd}{\tikzfeynman@momentum@stdrp} +\pgfkeyslet{/tikzfeynman/rmomentum'/.@cmd}{\tikzfeynman@momentum@stdrp} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Styles +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\input tikzfeynman.keys.code.tex + +\endinput
\ No newline at end of file |